From fc9cae644214e865187e24c6363d5c3c9558baae Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 16 Jan 2019 01:19:40 -0800 Subject: [PATCH 001/133] add userspace vere app --- app/here.hoon | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++ mar/pill.hoon | 18 +++++++ sur/pill.hoon | 3 ++ sys/arvo.hoon | 5 ++ 4 files changed, 165 insertions(+) create mode 100644 app/here.hoon create mode 100644 mar/pill.hoon create mode 100644 sur/pill.hoon diff --git a/app/here.hoon b/app/here.hoon new file mode 100644 index 000000000..26dec2834 --- /dev/null +++ b/app/here.hoon @@ -0,0 +1,139 @@ +:: usage: +:: /- pill +:: =p .^(pill:pill %cx %/urbit/pill) +:: |start %here +:: :here &pill p +:: :here %init +:: :here [%dojo "+ls %"] +:: :here [%dojo "our"] +:: +/- pill +=, pill +=> $~ |% + ++ move (pair bone card) + ++ card + $% [%turf wire ~] + [%vein wire] + [%look wire src=(each ship purl:eyre)] + [%wind wire p=@ud] + [%snap wire snap=snapshot:jael kick=?] + == + ++ state + $: pil=pill + roc=* + == + -- +=, gall +|_ $: hid/bowl + state + == +++ poke-pill + |= p=pill + ^- (quip move _+>) + =. pil p + ~& lent=(met 3 (jam boot-ova.pil)) + =/ res=toon :: (each * (list tank)) + (mock [boot-ova.pil [2 [0 3] [0 2]]] scry) + ?- -.res + %0 + ~& %suc + =. roc +7.p.res + `+>.$ + ::(u3v-plow userspace-ova.pil) + :: + %1 + ~& [%vere-blocked p.res] + `+>.$ + :: + %2 + ~& %vere-fail + %- (slog p.res) + `+>.$ + == +:: +++ u3v-plow + |= ova=* + ^- (quip move _+>) + =+ ova=((list ,*) ova) + ?~ ova + `+>.$ + =/ res (mox +47.roc) + ?> ?=(%0 -.res) + =+ poke=p.res + =+ res=(slum poke now.hid i.ova) + =+ effects=((list ovum) -.res) + :: ~& effects + =+ %+ turn effects + |= ovo=ovum + ~? =(%blit p.q.ovo) + :+ p.ovo p.q.ovo + =+ bs=((list blit:dill) q.q.ovo) + %+ turn bs + |= b=blit:dill + ?: ?=(%lin -.b) + [%lin (tape p.b)] + b + :: [p.ovo p.q.ovo %hrm ] ::((list blit:dill) q.q.ovo)] + ~? !=(%blit p.q.ovo) + ovo + ~ + =. roc +3.res + $(ova t.ova) +:: +++ poke-noun + |= val=* + ^- (quip move _+>) + ~& r=(met 3 (jam roc)) + ?+ val ~|(%bad-noun-arg !!) + %init + =+ who=~bud + %- u3v-plow + :~ + [/ %wack 0] :: eny + [/ %whom who] :: eny + [//newt/0v1n.2m9vh %barn ~] + [//behn/0v1n.2m9vh %born ~] + [//term/1 %boot %fake who] + -.userspace-ova.pil + [//http/0v1n.2m9vh %live 8.080 `8.445] + [//term/1 %belt %ctl %x] + == + :: + [%dojo p=*] + %- u3v-plow + :~ + [//term/1 %belt %ctl %e] + [//term/1 %belt %ctl %u] + [//term/1 %belt %txt (tape p.val)] + [//term/1 %belt %ret ~] + == + :: + [%peek p=*] + =+ res=(mox +46.roc) + ?> ?=(%0 -.res) + =+ peek=p.res + ~& (slum peek p.val) + `+>.$ + :: + [%wish p=@t] + =+ res=(mox +22.roc) + ?> ?=(%0 -.res) + =+ wish=p.res + ~& (slum wish p.val) + `+>.$ + == +:: +++ mox |=(* (mock [roc +<] scry)) +:: +++ scry |=([* *] ~) +:: +++ prep + |= old/(unit noun) + ^- [(list move) _+>.$] + ?~ old + `+>.$ + =+ new=((soft state) u.old) + ?~ new + `+>.$ + `+>.$(+<+ u.new) +-- diff --git a/mar/pill.hoon b/mar/pill.hoon new file mode 100644 index 000000000..e3eda05fc --- /dev/null +++ b/mar/pill.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/pill/mar + :: +/- pill +=, pill +=, mimes:html +|_ pil=pill +++ grow + |% + ++ mime [/application/octet-stream (as-octs (jam pil))] + -- +++ grab + |% + ++ noun pill + ++ mime |=([p=mite:eyre q=octs:eyre] (pill (cue q.q))) + -- +++ grad %mime +-- diff --git a/sur/pill.hoon b/sur/pill.hoon new file mode 100644 index 000000000..3e271acc9 --- /dev/null +++ b/sur/pill.hoon @@ -0,0 +1,3 @@ +|% ++= pill [boot-ova=* kernel-ova=* userspace-ova=*] +-- diff --git a/sys/arvo.hoon b/sys/arvo.hoon index fc270f5f6..c89685ca7 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -577,7 +577,11 @@ :: ++ poke |= * :: 47 ^- [(list ovum) *] + ~& =+ a=+< + =+ (met 3 (jam a)) + [%larval-poking ?:((gth - 10.000) - `a)] => .(+< ((hard ,[now=@da ovo=ovum]) +<)) + ~& [%larval-harded now p.ovo p.q.ovo] ^- [(list ovum) *] =. +>.$ ?+ -.q.ovo @@ -613,6 +617,7 @@ == :: upgrade once we've accumulated identity, entropy, and %zuse :: + ~& [%upgrading ?=(^ who) ?=(^ eny) ?=(^ bod)] ?. &(?=(^ who) ?=(^ eny) ?=(^ bod)) [~ +>.$] ~> %slog.[0 leaf+"arvo: metamorphosis"] From fe02c7653731f920ff9e062fd3fc9d1a43c3d78d Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 30 Jan 2019 18:48:30 -0800 Subject: [PATCH 002/133] clear clay state and ford cache when hear sunk --- lib/hood/kiln.hoon | 10 ++++++---- sys/vane/clay.hoon | 40 ++++++++++++++++++++++++++++++++++++++-- sys/zuse.hoon | 6 ++++-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/lib/hood/kiln.hoon b/lib/hood/kiln.hoon index 69f0a8ce9..07cd879de 100644 --- a/lib/hood/kiln.hoon +++ b/lib/hood/kiln.hoon @@ -382,10 +382,12 @@ ++ writ |= rot=riot ?~ rot - %^ spam - leaf+"bad %writ response" - (render "on sync" sud her syd) - ~ + =. +>.$ + %^ spam + leaf+"sync cancelled, retrying" + (render "on sync" sud her syd) + ~ + start-sync =. let ?. ?=($w p.p.u.rot) let ud:((hard cass:clay) q.q.r.u.rot) =/ =wire /kiln/sync/[syd]/(scot %p her)/[sud] :: germ: merge mode for sync merges diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index 82fd732e1..d1bdb9d81 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -343,7 +343,9 @@ == == :: $: $f :: $% [%build live=? schematic=schematic:ford] :: - == == + [%keep compiler-cache=@ud build-cache=@ud] :: + [%wipe percent-to-remove=@ud] :: + == == :: $: $b :: $% {$wait p/@da} :: {$rest p/@da} :: @@ -3884,7 +3886,41 @@ abet:(perm:den pax.req rit.req) [mos ..^$] :: - $sunk [~ ..^$] + $sunk + !: + :: if we sunk, don't clear clay + :: + ?: =(our p.req) + [~ ..^$] + :: cancel subscriptions + :: + =/ foreign-desk=(map desk rede) + (fall (~(get by hoy.ruf) p.req) ~) + =/ cancel-ducts=(list duct) + %- zing ^- (list (list duct)) + %+ turn ~(tap by foreign-desk) + |= [=desk =rede] + %+ weld + ^- (list duct) %- zing ^- (list (list duct)) + %+ turn ~(tap by qyx.rede) + |= [=wove ducts=(set duct)] + ~(tap in ducts) + ?~ ref.rede + ~ + (turn ~(tap by fod.u.ref.rede) head) + =/ cancel-moves=(list move) + %+ turn cancel-ducts + |= =duct + [duct %give %writ ~] + =/ clear-ford-cache-moves=(list move) + :~ [hen %pass /clear/keep %f %keep 0 1] + [hen %pass /clear/wipe %f %wipe 100] + [hen %pass /clear/kepe %f %keep 2.048 64] + == + :: delete local state of foreign desk + :: + =. hoy.ruf (~(del by hoy.ruf) p.req) + [(weld cancel-moves clear-ford-cache-moves) ..^$] :: ?($warp $werp) :: capture whether this read is on behalf of another ship diff --git a/sys/zuse.hoon b/sys/zuse.hoon index 722f1efee..4a980c0ff 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -7169,11 +7169,13 @@ :: azimuth: data contract :: :: ++ azimuth 0x308a.b6a6.024c.f198.b57e.008d.0ac9.ad02.1988.6579 :: ropsten - ++ azimuth 0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb :: mainnet + :: ++ azimuth 0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb :: mainnet + ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 :: local bridge :: :: launch: block number of azimuth deploy :: - ++ launch 6.784.800 + :: ++ launch 6.784.800 :: mainnet + ++ launch 0 :: local bridge -- :: :: hashes of ship event signatures From 075700583fe63c3e8378ebaf51f58a37fbd9497b Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 1 Feb 2019 13:46:09 -0800 Subject: [PATCH 003/133] WIP --- app/eth-manage.hoon | 2 +- lib/hood/kiln.hoon | 7 ++ sys/vane/clay.hoon | 187 +++++++++++++++++++++++++++++++++----------- sys/vane/jael.hoon | 47 +++++++---- sys/zuse.hoon | 17 ++-- 5 files changed, 193 insertions(+), 67 deletions(-) diff --git a/app/eth-manage.hoon b/app/eth-manage.hoon index d161f40a5..865e8e567 100644 --- a/app/eth-manage.hoon +++ b/app/eth-manage.hoon @@ -34,7 +34,7 @@ %look :_ ~ =/ pul - (need (de-purl:html 'http://eth-mainnet.urbit.org:8545')) + (need (de-purl:html 'http://localhost:8545')) [ost.hid %look /hi |+pul] == :: diff --git a/lib/hood/kiln.hoon b/lib/hood/kiln.hoon index 07cd879de..4368d2e8a 100644 --- a/lib/hood/kiln.hoon +++ b/lib/hood/kiln.hoon @@ -416,6 +416,13 @@ :: ++ mere |= mes=(each (set path) (pair term tang)) + ?: ?=([%| %ali-sunk *] mes) + =. +>.$ + %^ spam + leaf+"merge cancelled because sunk, restarting" + (render "on sync" sud her syd) + ~ + start-sync:stop =. let +(let) =. +>.$ %- spam diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index d1bdb9d81..c6c7c6354 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -1,5 +1,5 @@ :: clay (4c), revision control -:: +!: :: This is split in three top-level sections: structure definitions, main :: logic, and arvo interface. :: @@ -298,7 +298,10 @@ :: :: Foreign desk data. :: -+= rung rus/(map desk rede) :: neighbor desks +++ rung + $: rit=rift :: lyfe of 1st contact + rus=(map desk rede) :: neighbor desks + == :: :: Hash of a commit, for lookup in the object store (hut.ran) :: @@ -370,6 +373,23 @@ $: @tas :: by any $% {$crud p/@tas q/(list tank)} :: == == == :: +-- +:: +:: Old state types for ++load +:: +=> |% +++ raft-1 + $: rom/room + hoy/(map ship rung-1) + ran/rang :: hashes + mon/(map term beam) + hez/(unit duct) + cez/(map @ta crew) + cue/(qeu [duct task:able]) + tip/@da + == ++= rung-1 rus/(map desk rede) +++ raft-2 raft -- => :: %utilities :: @@ -393,6 +413,7 @@ :: -- local urbit `our` :: -- current time `now` :: -- current duct `hen` +:: -- scry handler `ski` :: -- all vane state `++raft` (rarely used, except for the object store) :: -- target urbit `her` :: -- target desk `syd` @@ -430,11 +451,11 @@ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |% ++ de :: per desk - |= [our=ship now=@da hen=duct raft] + |= [our=ship now=@da ski=sley hen=duct raft] |= [her=ship syd=desk] :: XX ruf=raft crashes in the compiler :: - =* ruf |3.+6.^$ + =* ruf |4.+6.^$ :: =+ ^- [hun=(unit duct) rede] ?. =(our her) @@ -459,9 +480,11 @@ ?. =(our her) :: save foreign +rede :: - =/ rus rus:(fall (~(get by hoy.ruf) her) *rung) - =/ rug (~(put by rus) syd red) - ruf(hoy (~(put by hoy.ruf) her rug)) + =/ run (fall (~(get by hoy.ruf) her) *rung) + =? rit.run =(0 rit.run) + (fall (rift-scry her) *rift) + =/ rug (~(put by rus.run) syd red) + ruf(hoy (~(put by hoy.ruf) her run(rus rug))) :: save domestic +room :: %= ruf @@ -469,6 +492,20 @@ dos.rom (~(put by dos.rom.ruf) syd [qyx dom dok mer per pew]:red) == :: + :: +rift-scry: for a +rift + :: + ++ rift-scry + ~/ %rift-scry + |= who=ship + ^- (unit rift) + =; rit + ?~(rit ~ u.rit) + ;; (unit (unit rift)) + %- (sloy-light ski) + =/ pur=spur + /(scot %p who) + [[151 %noun] %j our %rift da+now pur] + :: :: Handle `%sing` requests :: ++ aver @@ -521,7 +558,8 @@ ~& [%clay-first-failure message.head.row] ~ ?: ?=([%success [%success *] [%error *]] row) - ~& [%clay-second-failure message.tail.row] + ~& %clay-second-failure + %- (slog message.tail.row) ~ ?. ?=([%success [%success *] [%success *]] row) ~ @@ -1759,6 +1797,7 @@ :* hen %pass [%foreign-x (scot %p our) (scot %p her) syd car (scot cas) pax] %f %build live=%.n %pin + :: XX perhaps should be now as in ++validate-plops (case-to-date cas) (vale-page [her syd] peg) == @@ -1870,7 +1909,14 @@ %- emit :* hen %pass [%foreign-plops (scot %p our) (scot %p her) syd lum ~] - %f %build live=%.n %pin (case-to-date cas) + %f %build live=%.n %pin + :: This corresponds to all the changes from [her syd] + :: to [our %home]. This should be (case-to-date cas) + :: in the context of the foreign desk, but since we're + :: getting everything from our own desk now we want to + :: use our most recent commit. + :: + now %list ^- (list schematic:ford) %+ turn ~(tap in pop) @@ -2816,12 +2862,14 @@ ++ me :: merge ali into bob |= {ali/(pair ship desk) alh/(unit dome) new/?} :: from =+ bob=`(pair ship desk)`[our syd] :: to + :: ?: &(?=(~ mer) !new) + :: ~& [%not-actually-merging ali=ali bob=bob hen=hen] + :: ..me =+ ^- dat/(each mery term) ?~ mer - ?: new - =+ *mery - [%& -(sor ali:+, hen hen:+, wat %null)] - [%| %not-actually-merging] + ?> new :: checked in ++take + =+ *mery + [%& -(sor ali:+, hen hen:+, wat %null)] ?. new ?: =(ali sor.u.mer) [%& u.mer] @@ -2940,7 +2988,9 @@ |= rot/riot ^+ +> ?~ rot - (error:he %bad-fetch-ali ~) + ?: (~(has by hoy) her) + (error:he %bad-fetch-ali ~) + (error:he %ali-sunk ~) =+ ^= dum :: construct an empty mime cache :: @@ -3174,7 +3224,7 @@ =+ (cat 3 %diff- nam) [%merge (scot %p p.bob) q.bob (scot %p p.ali) q.ali - ~] %f %build live=%.n %pin - (case-to-date:((de our now hen ruf) p.oth q.oth) r.oth) + (case-to-date:((de our now ski hen ruf) p.oth q.oth) r.oth) %list ^- (list schematic:ford) %+ murn ~(tap by q.bas.dat) @@ -3701,8 +3751,8 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: =| :: instrument state - $: $1 :: vane version - ruf/raft :: revision tree + $: ver=%2 :: vane version + ruf=raft :: revision tree == :: |= [our=ship now=@da eny=@uvJ ski=sley] :: current invocation ^? :: opaque core @@ -3733,7 +3783,7 @@ =/ des ~(tap in ~(key by dos.rom.ruf)) |- ?~ des [[[hen %give %mack ~] mos] ..^^$] - =/ den ((de our now hen ruf) our i.des) + =/ den ((de our now ski hen ruf) our i.des) =^ mor ruf =< abet:wake ?: ?=(^ cew.req) den @@ -3768,7 +3818,7 @@ :: $drop =^ mos ruf - =/ den ((de our now hen ruf) our des.req) + =/ den ((de our now ski hen ruf) our des.req) abet:drop-me:den [mos ..^$] :: @@ -3787,11 +3837,12 @@ ?: =(%$ des.req) [~ ..^$] =^ mos ruf - =/ den ((de our now hen ruf) our des.req) + =/ den ((de our now ski hen ruf) our des.req) abet:(edit:den now dit.req) [mos ..^$] :: $init + ~& [%init hen] [~ ..^$(hun.rom.ruf hen)] :: $into @@ -3827,7 +3878,7 @@ ?: =(%$ des.req) [~ ..^$] =^ mos ruf - =/ den ((de our now hen ruf) our des.req) + =/ den ((de our now ski hen ruf) our des.req) abet:abet:(start:(me:ze:den [her.req dem.req] ~ &) cas.req how.req) [mos ..^$] :: @@ -3844,7 +3895,7 @@ ?~ dos [~ ..^$] =^ mos ruf - =/ den ((de our now hen ruf) p.bem q.bem) + =/ den ((de our now ski hen ruf) p.bem q.bem) abet:(mont:den des.req bem) [mos ..^$] :: @@ -3882,23 +3933,32 @@ :: $perm =^ mos ruf - =/ den ((de our now hen ruf) our des.req) + =/ den ((de our now ski hen ruf) our des.req) abet:(perm:den pax.req rit.req) [mos ..^$] :: $sunk - !: + ~& rift=[p.req q.req] + ~& desks=(turn ~(tap by dos.rom.ruf) head) + ~& hoy=(turn ~(tap by hoy.ruf) head) :: if we sunk, don't clear clay :: ?: =(our p.req) [~ ..^$] :: cancel subscriptions :: - =/ foreign-desk=(map desk rede) - (fall (~(get by hoy.ruf) p.req) ~) + =/ foreign-desk=(unit rung) + (~(get by hoy.ruf) p.req) + ?~ foreign-desk + ~& [%never-heard-of-her p.req q.req] + [~ ..^$] + ~& old-rift=rit.u.foreign-desk + ?: (gte rit.u.foreign-desk q.req) + ~& 'replaying sunk, so not clearing state' + [~ ..^$] =/ cancel-ducts=(list duct) %- zing ^- (list (list duct)) - %+ turn ~(tap by foreign-desk) + %+ turn ~(tap by rus.u.foreign-desk) |= [=desk =rede] %+ weld ^- (list duct) %- zing ^- (list (list duct)) @@ -3915,12 +3975,12 @@ =/ clear-ford-cache-moves=(list move) :~ [hen %pass /clear/keep %f %keep 0 1] [hen %pass /clear/wipe %f %wipe 100] - [hen %pass /clear/kepe %f %keep 2.048 64] + [hen %pass /clear/kep %f %keep 2.048 64] == :: delete local state of foreign desk :: =. hoy.ruf (~(del by hoy.ruf) p.req) - [(weld cancel-moves clear-ford-cache-moves) ..^$] + [(weld clear-ford-cache-moves cancel-moves) ..^$] :: ?($warp $werp) :: capture whether this read is on behalf of another ship @@ -3935,7 +3995,7 @@ ?> ?=($warp -.req) =* rif rif.req =^ mos ruf - =/ den ((de our now hen ruf) wer.req p.rif) + =/ den ((de our now ski hen ruf) wer.req p.rif) =< abet ?~ q.rif cancel-request:den @@ -3957,7 +4017,7 @@ =+ syd=(slav %tas i.t.pax) =+ inx=(slav %ud i.t.t.pax) =^ mos ruf - =/ den ((de our now hen ruf) wer syd) + =/ den ((de our now ski hen ruf) wer syd) abet:(take-foreign-update:den inx ((hard (unit rand)) res.req)) [[[hen %give %mack ~] mos] ..^$] :: @@ -3977,11 +4037,34 @@ :: ++ load => |% - ++ axle $%([%1 ruf=raft]) + ++ axle $% [%1 ruf-1=raft-1] + [%2 ruf-2=raft] + == -- |= old=axle ^+ ..^$ - ..^$(ruf ruf.old) + =? old ?=(%1 -.old) + ~& desks=(turn ~(tap by dos.rom.ruf-1.old) head) + ~& hoy=(turn ~(tap by hoy.ruf-1.old) head) + (load-1-2 old) + ~& hrm=[-.old ver] + ?> ?=(%2 -.old) + ~& desks=(turn ~(tap by dos.rom.ruf-2.old) head) + ~& hoy=(turn ~(tap by hoy.ruf-2.old) head) + %_(..^$ ruf ruf-2.old) +:: +++ load-1-2 + |= [%1 ruf-1=raft-1] + ^- [%2 ruf-2=raft] + :- %2 + %= ruf-1 + hoy + %- ~(rut by hoy.ruf-1) + |= [her=ship run-1=rung-1] + ^- rung + :- (fall (rift-scry her) *rift) + rus.run-1 + == :: ++ scry :: inspect |= {fur/(unit (set monk)) ren/@tas why/shop syd/desk lot/coin tyl/path} @@ -4004,14 +4087,14 @@ ?: ?=(%| -.m) ~ ?: =(p.m his) ~ `p.m - =/ den ((de our now [/scryduct ~] ruf) his syd) + =/ den ((de our now ski [/scryduct ~] ruf) his syd) =+ (aver:den for u.run u.luk tyl) ?~ - - ?~ u.- - ?: ?=(%& -.u.u.-) ``p.u.u.- ~ :: -++ stay [%1 ruf] +++ stay [%2 ruf] ++ take :: accept response |= {tea/wire hen/duct hin/(hypo sign)} ^+ [*(list move) ..^$] @@ -4026,7 +4109,10 @@ %+ bind (~(get by dos.rom.ruf) sud) |=(a=dojo dom.a) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) + ?~ mer.den + ~& [%not-actually-merging ali=[her sud] bob=[our syd] hen=hen] + [~ ruf] abet:abet:(route:(me:ze:den [her sud] kan |) sat dat) [mos ..^$] ?: ?=({$blab care @ @ *} tea) @@ -4056,7 +4142,7 @@ =+ syd=(slav %tas i.t.t.tea) =+ wen=(slav %da i.t.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-inserting:den wen result.q.hin) [mos ..^$] :: @@ -4065,7 +4151,7 @@ =+ syd=(slav %tas i.t.t.tea) =+ wen=(slav %da i.t.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-diffing:den wen result.q.hin) [mos ..^$] :: @@ -4074,7 +4160,7 @@ =+ syd=(slav %tas i.t.t.tea) =+ wen=(slav %da i.t.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-castify:den wen result.q.hin) [mos ..^$] :: @@ -4083,7 +4169,7 @@ =+ syd=(slav %tas i.t.t.tea) =+ wen=(slav %da i.t.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-mutating:den wen result.q.hin) [mos ..^$] :: @@ -4091,7 +4177,7 @@ ?> ?=({@ @ ~} t.tea) =+ syd=(slav %tas i.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-patch:den result.q.hin) [mos ..^$] :: @@ -4099,7 +4185,7 @@ ?> ?=({@ @ ~} t.tea) =+ syd=(slav %tas i.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) our syd) + =/ den ((de our now ski hen ruf) our syd) abet:(take-ergo:den result.q.hin) [mos ..^$] :: @@ -4109,7 +4195,7 @@ =* syd i.t.t.t.tea =+ lem=(slav %da i.t.t.t.t.tea) =^ mos ruf - =/ den ((de our now hen ruf) her syd) + =/ den ((de our now ski hen ruf) her syd) abet:(take-foreign-plops:den ?~(lem ~ `lem) result.q.hin) [mos ..^$] :: @@ -4124,7 +4210,7 @@ ->+ =* pax t.t.t.t.t.t.tea =^ mos ruf - =/ den ((de our now hen ruf) her syd) + =/ den ((de our now ski hen ruf) her syd) abet:(take-foreign-x:den car cas pax result.q.hin) [mos ..^$] == @@ -4221,4 +4307,17 @@ ?~ - `[paf %ins %mime -:!>(*mime) u.mim] `[paf %mut %mime -:!>(*mime) u.mim] +:: +rift-scry: for a +rift +:: +++ rift-scry + ~/ %rift-scry + |= who=ship + ^- (unit rift) + =; lyf + ?~(lyf ~ u.lyf) + ;; (unit (unit rift)) + %- (sloy-light ski) + =/ pur=spur + /(scot %p who) + [[151 %noun] %j our %rift da+now pur] -- diff --git a/sys/vane/jael.hoon b/sys/vane/jael.hoon index d85707fbf..e23685ec5 100644 --- a/sys/vane/jael.hoon +++ b/sys/vane/jael.hoon @@ -1,4 +1,4 @@ -:: :: /van/jael +!: :: /van/jael :: :: %reference/0 !? 150 :: @@ -1409,20 +1409,22 @@ :: :- (file-discontinuity who) %= ..file - :: these must be appended here; +abet flops them - :: - moz =/ lyf=life + moz =/ rit=rift ~| sunk-unknown+who - life:(~(got by kyz.puk)) - %+ weld moz - ^- (list move) - :~ [hen %slip %a %sunk who lyf] - [hen %slip %c %sunk who lyf] - [hen %slip %d %sunk who lyf] - [hen %slip %e %sunk who lyf] - [hen %slip %f %sunk who lyf] - [hen %slip %g %sunk who lyf] - == + =< continuity-number + %+ fall + net:(fall (~(get by pos.eth) who) *point) + *[life pass continuity-number=@ud [? @p] (unit @p)] + %+ weld + ^- (list move) + :~ [hen %slip %a %sunk who rit] + [hen %slip %c %sunk who rit] + [hen %slip %d %sunk who rit] + [hen %slip %e %sunk who rit] + [hen %slip %f %sunk who rit] + [hen %slip %g %sunk who rit] + == + moz == :: pon: updated point :: new: new keypair or "kept continuity?" (yes is no-op) @@ -2289,6 +2291,23 @@ =/ pub (~(get by kyz.puk.sub.lex) u.who) ?~ pub ~ ``[%atom !>(life.u.pub)] + :: + %rift + ?. ?=([@ ~] tyl) [~ ~] + ?. ?& ?=(%& -.why) + (~(has by pry.urb.lex) p.why) + == + [~ ~] + =/ who (slaw %p i.tyl) + ?~ who [~ ~] + :: fake ships always have rift=1 + :: + ?: fak.own.sub.lex + ``[%atom !>(1)] + =/ pos (~(get by pos.eth.sub.lex) u.who) + ?~ pos ~ + ?~ net.u.pos ~ + ``[%atom !>(continuity-number.u.net.u.pos)] :: %deed ?. ?=([@ @ ~] tyl) [~ ~] diff --git a/sys/zuse.hoon b/sys/zuse.hoon index 4a980c0ff..1b7e971fb 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -69,7 +69,8 @@ == :: ++ coop (unit ares) :: possible error -++ life @ud :: ship version +++ life @ud :: ship key revision +++ rift @ud :: ship continuity ++ mime {p/mite q/octs} :: mimetyped data ++ octs {p/@ud q/@t} :: octet-stream ++ sock {p/ship q/ship} :: outgoing [our his] @@ -241,7 +242,7 @@ [%init p=ship] :: report install {$kick p/@da} :: wake up {$nuke p/@p} :: toggle auto-block - {$sunk p=ship q=life} :: report death + {$sunk p=ship q=rift} :: report death {$wake ~} :: timer activate {$wegh ~} :: report memory {$west p/ship q/path r/*} :: network request @@ -474,7 +475,7 @@ {$dirk des/desk} :: mark mount dirty {$ogre pot/$@(desk beam)} :: delete mount point {$perm des/desk pax/path rit/rite} :: change permissions - {$sunk p=ship q=life} :: report death + {$sunk p=ship q=rift} :: report death {$warp wer/ship rif/riff} :: internal file req {$werp who/ship wer/ship rif/riff} :: external file req {$wegh ~} :: report memory @@ -638,7 +639,7 @@ {$harm ~} :: all terms hung up {$init p/ship} :: after gall ready {$noop ~} :: no operation - {$sunk p=ship q=life} :: report death + {$sunk p=ship q=rift} :: report death {$talk p/tank} :: {$text p/tape} :: {$veer p/@ta q/path r/@t} :: install vane @@ -735,7 +736,7 @@ [%live p=@ud q=(unit @ud)] :: http/s ports [%rule p=http-rule] :: update config [%serv p=$@(desk beam)] :: set serving root - [%sunk p=ship q=life] :: report death + [%sunk p=ship q=rift] :: report death [%them p=(unit hiss)] :: outbound request [%they p=@ud q=httr] :: inbound response [%chis p=? q=clip r=httq] :: IPC inbound request @@ -976,7 +977,7 @@ [%kill ~] :: %sunk: receive a report that a foreign ship has lost continuity :: - [%sunk =ship =life] + [%sunk =ship =rift] :: %wegh: produce memory usage information :: [%wegh ~] @@ -1667,7 +1668,7 @@ $% {$conf p/dock q/culm} :: configure app {$init p/ship} :: set owner {$deal p/sock q/cush} :: full transmission - {$sunk p=ship q/life} :: report death + {$sunk p=ship q/rift} :: report death {$west p/ship q/path r/*} :: network request {$wegh ~} :: report memory == :: @@ -1813,7 +1814,7 @@ == == :: $: @tas :: $% [%init p=ship] :: report install - [%sunk p=ship q=life] :: report death + [%sunk p=ship q=rift] :: report death == == == :: ++ public :: public key state $: life=life :: current key number From 88579c518f54965c8094c8dc2c375390c538f684 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 1 Feb 2019 13:49:14 -0800 Subject: [PATCH 004/133] here updates --- app/here.hoon | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++ mar/pill.hoon | 36 ++++++ sur/pill.hoon | 12 ++ 3 files changed, 392 insertions(+) create mode 100644 app/here.hoon create mode 100644 mar/pill.hoon create mode 100644 sur/pill.hoon diff --git a/app/here.hoon b/app/here.hoon new file mode 100644 index 000000000..6a1422467 --- /dev/null +++ b/app/here.hoon @@ -0,0 +1,344 @@ +:: usage: +:: /- pill +:: =p .^(pill:pill %cx %/urbit/pill) +:: |start %here +:: :here &pill p +:: :here %init +:: :here [%dojo "+ls %"] +:: :here [%dojo "our"] +:: +:: TODO: +:: - proper ames routing +:: - save pier point by label +:: - allow cancelling timer +:: - snapshot should keep track of outstanding timers +:: - %init should cancel outstanding timers +:: - allow pausing timer +:: - all commands should allow multiple ships +/- pill +=, pill +=> $~ |% + ++ move (pair bone card) + ++ card + $% [%turf wire ~] + [%vein wire] + [%look wire src=(each ship purl:eyre)] + [%wind wire p=@ud] + [%snap wire snap=snapshot:jael kick=?] + [%wait wire p=@da] + [%rest wire p=@da] + == + ++ unix-effect + %+ pair wire + $% [%blit p=(list blit:dill)] + [%send p=lane:ames q=@] + [%doze p=(unit @da)] + == + ++ state + $: pil=pill + assembled=* + fleet-snaps=(map term (map ship pier)) + piers=(map ship pier) + == + ++ pier + $: snap=* + event-log=(list unix-event) + next-events=(qeu unix-event) + processing-events=? + next-timer=(unit @da) + == + -- +=, gall +|_ $: hid/bowl + state + == +++ pe + |= who=ship + =+ (fall (~(get by piers) who) *pier) + =* pier-data - + =| moves=(list move) + |% + ++ abet + ^- (quip move _this) + =. piers (~(put by piers) who pier-data) + [(flop moves) this] + :: + ++ apex + =. snap assembled + ~& r=(met 3 (jam snap)) + ..abet + :: + ++ push-events + |= ova=(list unix-event) + ^+ ..abet + =. next-events (~(gas to next-events) ova) + ..abet + :: + ++ emit-moves + |= ms=(list move) + =. moves (weld ms moves) + ..abet + :: + ++ plow + |- ^+ ..abet + ?: =(~ next-events) + ..abet + ?. processing-events + ..abet + =^ ovo next-events ~(get to next-events) + =/ res (mox +47.snap) + ?> ?=(%0 -.res) + =+ poke=p.res + =+ res=(slum poke now.hid ovo) + =. event-log [ovo event-log] + =. snap +3.res + =. ..abet (handle-effects ((list ovum) -.res)) + $ + :: + ++ start-processing-events .(processing-events &) + ++ stop-processing-events .(processing-events |) + ++ mox |=(* (mock [snap +<] scry)) + :: + ++ handle-effects + |= effects=(list ovum) + ^+ ..abet + ?~ effects + ..abet + =. ..abet + =/ sof ((soft unix-effect) i.effects) + ?~ sof + ~& [%unknown-effect i.effects] + ..abet + ?- -.q.u.sof + %blit + =/ last-line + %+ roll p.q.u.sof + |= [b=blit:dill line=tape] + ?- -.b + %lin (tape p.b) + %mor ~& line "" + %hop line + %bel line + %clr "" + %sag ~& [%save-jamfile-to p.b] line + %sav ~& [%save-file-to p.b] line + %url ~& [%activate-url p.b] line + == + ~& last-line + ..abet + :: + %send (handle-send u.sof) + %doze (handle-doze u.sof) + == + $(effects t.effects) + :: + ++ handle-send + |= [way=wire %send lan=lane:ames pac=@] + ^+ ..abet + =/ dest-ip + |- ^- (unit @if) + ?- -.lan + %if `r.lan + %is ?~(q.lan ~ $(lan u.q.lan)) + %ix `r.lan + == + ?~ dest-ip + ~& [%sending-no-destination who lan] + ..abet + ?. &(=(0 (rsh u.dest-ip 0 16)) =(1 (rsh u.dest-ip 0 8))) + ~& [%havent-implemented-direct-lanes who lan] + ..abet + =/ her=ship (dis u.dest-ip 0xff) + =/ hear [//newt/0v1n.2m9vh %hear lan pac]~ + ~& [%sending who=who her=her] + =^ ms this + abet:(push-events:(pe her) hear) + (emit-moves ms) + :: + ++ handle-doze + |= [way=wire %doze tim=(unit @da)] + ^+ ..abet + ?~ tim + ?~ next-timer + ..abet + cancel-timer + ?~ next-timer + (set-timer u.tim) + (set-timer:cancel-timer u.tim) + :: + ++ set-timer + |= tim=@da + =. tim +(tim) :: nobody's perfect + =. next-timer `tim + ~& [%sleeping-until who tim] + (emit-moves [ost.hid %wait /(scot %p who) tim]~) + :: + ++ cancel-timer + ~& [%cancelling-timer who] + (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) + -- +++ this . +++ plow-all + |- ^- (quip move _this) + =/ who + =/ pers ~(tap by piers) + |- ^- (unit ship) + ?~ pers + ~ + ?: &(?=(^ next-events.q.i.pers) processing-events.q.i.pers) + ~& [%new-events p.i.pers] + `p.i.pers + ~& [%no-new-events p.i.pers] + $(pers t.pers) + ~& plowing=who + ?~ who + `this + =^ moves this abet:plow:(pe u.who) + =/ nex $ + nex(- (weld -.nex moves)) +:: +++ poke-pill + |= p=pill + ^- (quip move _this) + =. pil p + ~& lent=(met 3 (jam boot-ova.pil)) + =/ res=toon :: (each * (list tank)) + (mock [boot-ova.pil [2 [0 3] [0 2]]] scry) + ?- -.res + %0 + ~& %suc + =. assembled +7.p.res + `this + :: + %1 + ~& [%vere-blocked p.res] + `this + :: + %2 + ~& %vere-fail + %- (slog p.res) + `this + == +:: +++ poke-noun + |= val=* + ^- (quip move _this) + ?+ val ~|(%bad-noun-arg !!) + [%init whos=*] + =/ whos ((list ship) whos.val) + |- ^- (quip move _this) + ?~ whos + `this + ?~ userspace-ova.pil + ~& %no-userspace + `this + =+ who=i.whos + ~& [%initting who] + => .(this ^+(this this)) + =^ moves this + =< abet:plow + %- push-events:apex:(pe who) + ^- (list unix-event) + :~ + `unix-event`[/ %wack 0] :: eny + `unix-event`[/ %whom who] :: eny + `unix-event`[//newt/0v1n.2m9vh %barn ~] + `unix-event`[//behn/0v1n.2m9vh %born ~] + `unix-event`[//term/1 %boot %fake who] + `unix-event`-.userspace-ova.pil + `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] + `unix-event`[//term/1 %belt %ctl `@c`%x] + == + =^ moves-all this plow-all + =/ nex $(whos t.whos) + nex(- (weld -.nex (weld moves moves-all))) + :: + [%dojo who=@p p=*] + =^ moves this + =< abet:plow + %- push-events:(pe who.val) + ^- (list unix-event) + :~ + [//term/1 %belt %ctl `@c`%e] + [//term/1 %belt %ctl `@c`%u] + [//term/1 %belt %txt ((list @c) (tape p.val))] + [//term/1 %belt %ret ~] + == + =^ moves-all this plow-all + [(weld moves moves-all) this] + :: + [%snap-fleet lab=@tas] + =. fleet-snaps (~(put by fleet-snaps) lab.val piers) + `this + :: + [%restore-fleet lab=@tas] + =. piers (~(got by fleet-snaps) lab.val) + `this + :: + [%peek who=@p p=*] + :: =+ res=(mox +46.snap) + :: ?> ?=(%0 -.res) + :: =+ peek=p.res + :: ~& (slum peek p.val) + `this + :: + [%wish who=@p p=@t] + :: =+ res=(mox +22.snap) + :: ?> ?=(%0 -.res) + :: =+ wish=p.res + :: ~& (slum wish p.val) + `this + :: + %clear-next + :: =. next-events ~ + `this + :: + [%unpause-events hers=*] + %+ execute-turn ((list ship) hers.val) + |= who=ship + start-processing-events:(pe who) + :: + [%pause-events hers=*] + %+ execute-turn ((list ship) hers.val) + |= who=ship + stop-processing-events:(pe who) + == +:: +++ execute-turn + |= [hers=(list ship) fun=$-([ship] _(pe))] + |- ^- (quip move _this) + ?~ hers + =^ moves this plow-all + [moves this] + =^ moves this + abet:plow:(fun i.hers) + =/ nex $(hers t.hers) + nex(- (weld moves -.nex)) +:: +++ wake + |= [way=wire ~] + ^- (quip move _this) + ?> ?=([@ ~] way) + =/ who (,@p (slav %p i.way)) + ~& [%waking who] + =^ moves this + =< abet:plow + %- push-events:(pe who) + ^- (list unix-event) + :~ [//behn/0v1n.2m9vh %wake ~] + == + =^ moves-all this plow-all + [(weld moves moves-all) this] +:: +++ scry |=([* *] ~) +:: +++ prep + |= old/(unit noun) + ^- [(list move) _+>.$] + ?~ old + `+>.$ + =+ new=((soft state) u.old) + ?~ new + `+>.$ + `+>.$(+<+ u.new) +-- diff --git a/mar/pill.hoon b/mar/pill.hoon new file mode 100644 index 000000000..1f0c6447e --- /dev/null +++ b/mar/pill.hoon @@ -0,0 +1,36 @@ +:: +:::: /hoon/pill/mar + :: +/- pill +=, pill +=, mimes:html +|_ pil=pill +++ grow + |% + ++ mime [/application/octet-stream (as-octs (jam pil))] + -- +++ grab + |% + ++ noun pill + ++ mime + |= [p=mite:eyre q=octs:eyre] + =+ o=(pair ,* ,*) :: ,*) + =+ (,[boot-ova=* kernel-ova=(list o) userspace-ova=(list o)] (cue q.q)) + =/ convert + |= ova=(list o) + ^- (list unix-event) + %+ turn ova + |= ovo=o + =/ sof ((soft unix-event) ovo) + ?~ sof + ~& [%unknown-event p.ovo] + !! + ~& [%known-event (wire p.ovo) (@tas -.q.ovo)] + u.sof + :: =/ boot-ova (convert boot-ova) + =/ kernel-ova (convert kernel-ova) + =/ userspace-ova (convert userspace-ova) + [boot-ova kernel-ova userspace-ova] + -- +++ grad %mime +-- diff --git a/sur/pill.hoon b/sur/pill.hoon new file mode 100644 index 000000000..33d06604b --- /dev/null +++ b/sur/pill.hoon @@ -0,0 +1,12 @@ +|% +++ unix-event + %+ pair wire + $% [%wack p=@] + [%whom p=ship] + [%live p=@ud q=(unit @ud)] + [%barn ~] + [%boot %fake p=ship] + unix-task + == ++= pill [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] +-- From 6138daf40c1d0182ae37c9a583a7c80978997ab5 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 1 Feb 2019 17:00:15 -0800 Subject: [PATCH 005/133] aquarium boots a fleet --- app/{here.hoon => aqua.hoon} | 256 +++++++++++++++++++++++------------ sys/vane/gall.hoon | 63 ++++----- 2 files changed, 198 insertions(+), 121 deletions(-) rename app/{here.hoon => aqua.hoon} (50%) diff --git a/app/here.hoon b/app/aqua.hoon similarity index 50% rename from app/here.hoon rename to app/aqua.hoon index 6a1422467..34b24bc87 100644 --- a/app/here.hoon +++ b/app/aqua.hoon @@ -1,11 +1,11 @@ :: usage: :: /- pill :: =p .^(pill:pill %cx %/urbit/pill) -:: |start %here -:: :here &pill p -:: :here %init -:: :here [%dojo "+ls %"] -:: :here [%dojo "our"] +:: |start %aqua +:: :aqua &pill p +:: :aqua %init +:: :aqua [%dojo "+ls %"] +:: :aqua [%dojo "our"] :: :: TODO: :: - proper ames routing @@ -15,17 +15,16 @@ :: - %init should cancel outstanding timers :: - allow pausing timer :: - all commands should allow multiple ships +:: - shared command line across ships would be cool +:: +:: We get ++unix-event and ++pill from /-pill +:: /- pill =, pill => $~ |% ++ move (pair bone card) ++ card - $% [%turf wire ~] - [%vein wire] - [%look wire src=(each ship purl:eyre)] - [%wind wire p=@ud] - [%snap wire snap=snapshot:jael kick=?] - [%wait wire p=@da] + $% [%wait wire p=@da] [%rest wire p=@da] == ++ unix-effect @@ -35,7 +34,8 @@ [%doze p=(unit @da)] == ++ state - $: pil=pill + $: %0 + pil=pill assembled=* fleet-snaps=(map term (map ship pier)) piers=(map ship pier) @@ -52,6 +52,9 @@ |_ $: hid/bowl state == +:: +:: Represents a single ship's state. +:: ++ pe |= who=ship =+ (fall (~(get by piers) who) *pier) @@ -64,6 +67,7 @@ [(flop moves) this] :: ++ apex + =. pier-data *pier =. snap assembled ~& r=(met 3 (jam snap)) ..abet @@ -79,6 +83,8 @@ =. moves (weld ms moves) ..abet :: + :: Process the events in our queue. + :: ++ plow |- ^+ ..abet ?: =(~ next-events) @@ -95,9 +101,15 @@ =. ..abet (handle-effects ((list ovum) -.res)) $ :: + ++ mox |=(* (mock [snap +<] scry)) + :: + :: Start/stop processing events. When stopped, events are added to + :: our queue but not processed. + :: ++ start-processing-events .(processing-events &) ++ stop-processing-events .(processing-events |) - ++ mox |=(* (mock [snap +<] scry)) + :: + :: Handle all the effects produced by a single event. :: ++ handle-effects |= effects=(list ovum) @@ -110,28 +122,47 @@ ~& [%unknown-effect i.effects] ..abet ?- -.q.u.sof - %blit - =/ last-line - %+ roll p.q.u.sof - |= [b=blit:dill line=tape] - ?- -.b - %lin (tape p.b) - %mor ~& line "" - %hop line - %bel line - %clr "" - %sag ~& [%save-jamfile-to p.b] line - %sav ~& [%save-file-to p.b] line - %url ~& [%activate-url p.b] line - == - ~& last-line - ..abet - :: + %blit (handle-blit u.sof) %send (handle-send u.sof) %doze (handle-doze u.sof) == $(effects t.effects) :: + :: Would love to see a proper stateful terminal handler. Ideally, + :: you'd be able to ^X into the virtual ship, like the old ^W. + :: + :: However, that's porbably not the primary way of interacting with + :: it. In practice, most of the time you'll be running from a file + :: (eg for automated testing) or fanning the same command to multiple + :: ships or otherwise making use of the fact that we can + :: programmatically send events. + :: + ++ handle-blit + |= [way=wire %blit blits=(list blit:dill)] + ^+ ..abet + =/ last-line + %+ roll blits + |= [b=blit:dill line=tape] + ?- -.b + %lin (tape p.b) + %mor ~& "{}: {line}" "" + %hop line + %bel line + %clr "" + %sag ~& [%save-jamfile-to p.b] line + %sav ~& [%save-file-to p.b] line + %url ~& [%activate-url p.b] line + == + ~& last-line + ..abet + :: + :: This needs a better SDN solution. Every ship should have an IP + :: address, and we should eventually test changing those IP + :: addresses. + :: + :: For now, we broadcast every packet to every ship and rely on them + :: to drop them. + :: ++ handle-send |= [way=wire %send lan=lane:ames pac=@] ^+ ..abet @@ -145,15 +176,23 @@ ?~ dest-ip ~& [%sending-no-destination who lan] ..abet - ?. &(=(0 (rsh u.dest-ip 0 16)) =(1 (rsh u.dest-ip 0 8))) + ?. &(=(0 (rsh 0 16 u.dest-ip)) =(1 (rsh 0 8 u.dest-ip))) ~& [%havent-implemented-direct-lanes who lan] ..abet - =/ her=ship (dis u.dest-ip 0xff) - =/ hear [//newt/0v1n.2m9vh %hear lan pac]~ - ~& [%sending who=who her=her] - =^ ms this - abet:(push-events:(pe her) hear) - (emit-moves ms) + ~& [%blast-sending who=who] + =/ hear [//newt/0v1n.2m9vh %hear lan pac] + =. this (blast-event hear) + :: =/ her ?:(=(~dev who) ~bud ~dev) ::ship (dis u.dest-ip 0xff) + :: ?. (~(has by piers) her) + :: ~& [%dropping who=who her=her] + :: ..abet + :: ~& [%sending who=who her=her ip=`@ux`u.dest-ip] + :: =^ ms this + :: abet:(push-events:(pe her) ~[hear]) + ..abet + :: + :: Would love to be able to control time more precisely, jumping + :: forward and whatnot. :: ++ handle-doze |= [way=wire %doze tim=(unit @da)] @@ -177,7 +216,11 @@ ~& [%cancelling-timer who] (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) -- +:: ++ this . +:: +:: Run all events on all ships until all queues are empty +:: ++ plow-all |- ^- (quip move _this) =/ who @@ -188,7 +231,6 @@ ?: &(?=(^ next-events.q.i.pers) processing-events.q.i.pers) ~& [%new-events p.i.pers] `p.i.pers - ~& [%no-new-events p.i.pers] $(pers t.pers) ~& plowing=who ?~ who @@ -197,6 +239,9 @@ =/ nex $ nex(- (weld -.nex moves)) :: +:: Load a pill and assemble arvo. Doesn't send any of the initial +:: events. +:: ++ poke-pill |= p=pill ^- (quip move _this) @@ -220,52 +265,46 @@ `this == :: +:: Handle commands +:: +:: Should put some thought into arg structure, maybe make a mark. +:: ++ poke-noun |= val=* ^- (quip move _this) + :: Could potentially factor out the three lines of turn-ships + :: boilerplate + :: ?+ val ~|(%bad-noun-arg !!) [%init whos=*] - =/ whos ((list ship) whos.val) - |- ^- (quip move _this) - ?~ whos - `this - ?~ userspace-ova.pil - ~& %no-userspace - `this - =+ who=i.whos + %+ turn-ships ((list ship) whos.val) + |= [who=ship thus=_this] + =. this thus ~& [%initting who] - => .(this ^+(this this)) - =^ moves this - =< abet:plow - %- push-events:apex:(pe who) - ^- (list unix-event) - :~ - `unix-event`[/ %wack 0] :: eny - `unix-event`[/ %whom who] :: eny - `unix-event`[//newt/0v1n.2m9vh %barn ~] - `unix-event`[//behn/0v1n.2m9vh %born ~] - `unix-event`[//term/1 %boot %fake who] - `unix-event`-.userspace-ova.pil - `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] - `unix-event`[//term/1 %belt %ctl `@c`%x] - == - =^ moves-all this plow-all - =/ nex $(whos t.whos) - nex(- (weld -.nex (weld moves moves-all))) + %- push-events:apex:(pe who) + ^- (list unix-event) + :~ `unix-event`[/ %wack 0] :: eny + `unix-event`[/ %whom who] :: eny + `unix-event`[//newt/0v1n.2m9vh %barn ~] + `unix-event`[//behn/0v1n.2m9vh %born ~] + `unix-event`[//term/1 %boot %fake who] + `unix-event`-.userspace-ova.pil + `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] + `unix-event`[//term/1 %belt %ctl `@c`%x] + == :: - [%dojo who=@p p=*] - =^ moves this - =< abet:plow - %- push-events:(pe who.val) - ^- (list unix-event) - :~ - [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] - [//term/1 %belt %txt ((list @c) (tape p.val))] - [//term/1 %belt %ret ~] - == - =^ moves-all this plow-all - [(weld moves moves-all) this] + [%dojo whos=* command=*] + %+ turn-ships ((list ship) whos.val) + |= [who=ship thus=_this] + =. this thus + %- push-events:(pe who) + ^- (list unix-event) + :~ + [//term/1 %belt %ctl `@c`%e] + [//term/1 %belt %ctl `@c`%u] + [//term/1 %belt %txt ((list @c) (tape command.val))] + [//term/1 %belt %ret ~] + == :: [%snap-fleet lab=@tas] =. fleet-snaps (~(put by fleet-snaps) lab.val piers) @@ -276,6 +315,7 @@ `this :: [%peek who=@p p=*] + :: should resurrect :: =+ res=(mox +46.snap) :: ?> ?=(%0 -.res) :: =+ peek=p.res @@ -283,37 +323,69 @@ `this :: [%wish who=@p p=@t] + :: should resurrect :: =+ res=(mox +22.snap) :: ?> ?=(%0 -.res) :: =+ wish=p.res :: ~& (slum wish p.val) `this - :: - %clear-next - :: =. next-events ~ - `this :: [%unpause-events hers=*] - %+ execute-turn ((list ship) hers.val) - |= who=ship + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus start-processing-events:(pe who) :: [%pause-events hers=*] - %+ execute-turn ((list ship) hers.val) - |= who=ship + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus stop-processing-events:(pe who) == :: -++ execute-turn - |= [hers=(list ship) fun=$-([ship] _(pe))] +:: Run a callback function against a list of ships, aggregating state +:: and plowing all ships at the end. +:: +:: I think we should use patterns like this more often. Because we +:: don't, here's some points to be aware. +:: +:: `fun` must take `this` as a parameter, since it needs to be +:: downstream of previous state changes. You could use `state` as +:: the state variable, but it muddles the code and it's not clear +:: whether it's better. You could use the `_(pe)` core if you're +:: sure you'll never need to refer to anything outside of your pier, +:: but I don't think we can guarantee that. +:: +:: The callback function must start with `=. this thus`, or else +:: you don't get the new state. Would be great if you could hot-swap +:: that context in here, but we don't know where to put it unless we +:: restrict the callbacks to always have `this` at a particular axis, +:: and that doesn't feel right +:: +++ turn-ships + |= [hers=(list ship) fun=$-([ship _this] _(pe))] |- ^- (quip move _this) ?~ hers =^ moves this plow-all [moves this] =^ moves this - abet:plow:(fun i.hers) - =/ nex $(hers t.hers) - nex(- (weld moves -.nex)) + abet:plow:(fun i.hers this) + =^ nex-moves this $(hers t.hers, this this) + [(weld moves nex-moves) this] +:: +:: Send the same event to all ships +:: +++ blast-event + |= ovo=unix-event + =/ pers ~(tap by piers) + |- ^+ this + ?~ pers + this + =^ moves-dropped this + abet:(push-events:(pe p.i.pers) ~[ovo]) + $(pers t.pers) +:: +:: Received timer wake :: ++ wake |= [way=wire ~] @@ -330,8 +402,12 @@ =^ moves-all this plow-all [(weld moves moves-all) this] :: +:: Trivial scry for mock +:: ++ scry |=([* *] ~) :: +:: Throw away old state if it doesn't soft to new state. +:: ++ prep |= old/(unit noun) ^- [(list move) _+>.$] diff --git a/sys/vane/gall.hoon b/sys/vane/gall.hoon index 5eff555a6..e0a96ca3a 100644 --- a/sys/vane/gall.hoon +++ b/sys/vane/gall.hoon @@ -1258,37 +1258,38 @@ ^- (unit @tas) ?+ sep ~& [%ap-vain sep] ~ - $build `%f - $cash `%a - $conf `%g - $cred `%c - $crew `%c - $crow `%c - $deal `%g - $dirk `%c - $drop `%c - $flog `%d - $info `%c - $keep `%f - $kill `%f - $look `%j - $merg `%c - $mint `%j - $mont `%c - $nuke `%a - $ogre `%c - $perm `%c - $rule `%e - $serv `%e - $snap `%j - $them `%e - $wait `%b - $want `%a - $warp `%c - $well `%e - $well `%e - $wind `%j - $wipe `%f + %build `%f + %cash `%a + %conf `%g + %cred `%c + %crew `%c + %crow `%c + %deal `%g + %dirk `%c + %drop `%c + %flog `%d + %info `%c + %keep `%f + %kill `%f + %look `%j + %merg `%c + %mint `%j + %mont `%c + %nuke `%a + %ogre `%c + %perm `%c + %rest `%b + %rule `%e + %serv `%e + %snap `%j + %them `%e + %wait `%b + %want `%a + %warp `%c + %well `%e + %well `%e + %wind `%j + %wipe `%f == -- -- From 54a618723c97f9aea1737e724646bd79de85726e Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 1 Feb 2019 17:14:11 -0800 Subject: [PATCH 006/133] comments --- app/aqua.hoon | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 34b24bc87..b9ff29ce7 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -1,21 +1,16 @@ :: usage: -:: /- pill -:: =p .^(pill:pill %cx %/urbit/pill) :: |start %aqua -:: :aqua &pill p -:: :aqua %init -:: :aqua [%dojo "+ls %"] -:: :aqua [%dojo "our"] +:: /- pill +:: :aqua &pill .^(pill:pill %cx %/urbit/pill) +:: :aqua [%init ~[~bud ~dev]] +:: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] +:: :aqua [%dojo ~[~bud] "|hi ~dev"] +:: :aqua [%pause-events ~[~bud ~dev]] :: :: TODO: -:: - proper ames routing -:: - save pier point by label -:: - allow cancelling timer :: - snapshot should keep track of outstanding timers :: - %init should cancel outstanding timers -:: - allow pausing timer -:: - all commands should allow multiple ships -:: - shared command line across ships would be cool +:: :: :: We get ++unix-event and ++pill from /-pill :: From ea2746588110625883b40e97395cb341e15d7ed6 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 4 Feb 2019 14:13:20 -0800 Subject: [PATCH 007/133] add outgoing http support and proper restoring --- app/aqua.hoon | 172 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 153 insertions(+), 19 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index b9ff29ce7..8ba3bd995 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -7,10 +7,6 @@ :: :aqua [%dojo ~[~bud] "|hi ~dev"] :: :aqua [%pause-events ~[~bud ~dev]] :: -:: TODO: -:: - snapshot should keep track of outstanding timers -:: - %init should cancel outstanding timers -:: :: :: We get ++unix-event and ++pill from /-pill :: @@ -21,12 +17,14 @@ ++ card $% [%wait wire p=@da] [%rest wire p=@da] + [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] == ++ unix-effect %+ pair wire $% [%blit p=(list blit:dill)] [%send p=lane:ames q=@] [%doze p=(unit @da)] + [%thus p=@ud q=(unit hiss:eyre)] == ++ state $: %0 @@ -41,6 +39,7 @@ next-events=(qeu unix-event) processing-events=? next-timer=(unit @da) + http-requests=(set @ud) == -- =, gall @@ -96,6 +95,39 @@ =. ..abet (handle-effects ((list ovum) -.res)) $ :: + :: Restart outstanding requests + :: + ++ restore + ^+ ..abet + :: Restore behn + :: + =. ..abet + ?~ next-timer + ..abet + (set-timer u.next-timer) + :: Restore eyre + :: + =. http-requests ~ + =. ..abet (push-events [//http/0v1n.2m9vh %born ~]~) + ..abet + :: + :: Cancel outstanding requests + :: + ++ sleep + ^+ ..abet + :: Sleep behn + :: + =. ..abet + ?~ next-timer + ..abet + cancel-timer + :: Sleep eyre + :: + :: Eyre doesn't support cancelling HTTP requests from userspace. + :: + =. http-requests ~ + ..abet + :: ++ mox |=(* (mock [snap +<] scry)) :: :: Start/stop processing events. When stopped, events are added to @@ -114,12 +146,13 @@ =. ..abet =/ sof ((soft unix-effect) i.effects) ?~ sof - ~& [%unknown-effect i.effects] + ~& [who=who %unknown-effect i.effects] ..abet ?- -.q.u.sof %blit (handle-blit u.sof) %send (handle-send u.sof) %doze (handle-doze u.sof) + %thus (handle-thus u.sof) == $(effects t.effects) :: @@ -210,6 +243,64 @@ ++ cancel-timer ~& [%cancelling-timer who] (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) + :: + ++ take-wake + |= [way=wire ~] + =. next-timer ~ + %- push-events:(pe who) + [//behn/0v1n.2m9vh %wake ~]~ + :: + :: Handle outgoing HTTP request + :: + ++ handle-thus + |= [way=wire %thus num=@ud req=(unit hiss:eyre)] + ^+ ..abet + ?~ req + ?. (~(has in http-requests) num) + ..abet + :: Eyre doesn't support cancelling HTTP requests from userspace, + :: so we remove it from our state so we won't pass along the + :: response. + :: + ~& [%cant-cancel-thus who=who num=num] + =. http-requests (~(del in http-requests) num) + ..abet + =. http-requests (~(put in http-requests) num) + %- emit-moves :_ ~ + :* ost.hid + %hiss + /(scot %p who)/(scot %ud num) + ~ + %httr + [%hiss u.req] + == + :: + :: Pass HTTP response back to virtual ship + :: + ++ take-sigh-httr + |= [way=wire res=httr:eyre] + ^+ ..abet + ?> ?=([@ ~] way) + =/ num (slav %ud i.way) + ?. (~(has in http-requests) num) + ~& [%ignoring-httr who=who num=num] + ..abet + =. http-requests (~(del in http-requests) num) + (push-events [//http/0v1n.2m9vh %they num res]~) + :: + :: Got error in HTTP response + :: + ++ take-sigh-tang + |= [way=wire tan=tang] + ^+ ..abet + ?> ?=([@ ~] way) + =/ num (slav %ud i.way) + ?. (~(has in http-requests) num) + ~& [%ignoring-httr who=who num=num] + ..abet + =. http-requests (~(del in http-requests) num) + %- (slog tan) + ..abet -- :: ++ this . @@ -271,8 +362,8 @@ :: boilerplate :: ?+ val ~|(%bad-noun-arg !!) - [%init whos=*] - %+ turn-ships ((list ship) whos.val) + [%init hers=*] + %+ turn-ships ((list ship) hers.val) |= [who=ship thus=_this] =. this thus ~& [%initting who] @@ -284,12 +375,13 @@ `unix-event`[//behn/0v1n.2m9vh %born ~] `unix-event`[//term/1 %boot %fake who] `unix-event`-.userspace-ova.pil + `unix-event`[//http/0v1n.2m9vh %born ~] `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] `unix-event`[//term/1 %belt %ctl `@c`%x] == :: - [%dojo whos=* command=*] - %+ turn-ships ((list ship) whos.val) + [%dojo hers=* command=*] + %+ turn-ships ((list ship) hers.val) |= [who=ship thus=_this] =. this thus %- push-events:(pe who) @@ -300,14 +392,34 @@ [//term/1 %belt %txt ((list @c) (tape command.val))] [//term/1 %belt %ret ~] == + :: + [%raw-event hers=* ovo=*] + =/ ovo ((soft unix-event) ovo.val) + ?~ ovo + ~& %ovo-not-an-event + `this + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + (push-events:(pe who) ~[u.ovo]) :: [%snap-fleet lab=@tas] =. fleet-snaps (~(put by fleet-snaps) lab.val piers) `this :: [%restore-fleet lab=@tas] + =^ moves-1 this + %+ turn-ships (turn ~(tap by piers) head) + |= [who=ship thus=_this] + =. this thus + sleep:(pe who) =. piers (~(got by fleet-snaps) lab.val) - `this + =^ moves-2 this + %+ turn-ships (turn ~(tap by piers) head) + |= [who=ship thus=_this] + =. this thus + restore:(pe who) + [(weld moves-1 moves-2) this] :: [%peek who=@p p=*] :: should resurrect @@ -385,17 +497,39 @@ ++ wake |= [way=wire ~] ^- (quip move _this) - ?> ?=([@ ~] way) + ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%waking who] - =^ moves this - =< abet:plow - %- push-events:(pe who) - ^- (list unix-event) - :~ [//behn/0v1n.2m9vh %wake ~] - == - =^ moves-all this plow-all - [(weld moves moves-all) this] + %+ turn-ships ~[who] + |= [who=ship thus=_this] + =. this thus + (take-wake:(pe who) t.way ~) +:: +:: Received inbound HTTP response +:: +++ sigh-httr + |= [way=wire res=httr:eyre] + ^- (quip move _this) + ?> ?=([@ *] way) + =/ who (,@p (slav %p i.way)) + ~& [%received-httr who] + %+ turn-ships ~[who] + |= [who=ship thus=_this] + =. this thus + (take-sigh-httr:(pe who) t.way res) +:: +:: Received inbound HTTP response error +:: +++ sigh-tang + |= [way=wire tan=tang] + ^- (quip move _this) + ?> ?=([@ *] way) + =/ who (,@p (slav %p i.way)) + ~& [%received-httr who] + %+ turn-ships ~[who] + |= [who=ship thus=_this] + =. this thus + (take-sigh-tang:(pe who) t.way tan) :: :: Trivial scry for mock :: From fd5df264d9b7c067f3b284ef764779f7c2fb2271 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 4 Feb 2019 14:31:55 -0800 Subject: [PATCH 008/133] resurrect peek and wish --- app/aqua.hoon | 78 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 8ba3bd995..818dc34f5 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -6,6 +6,8 @@ :: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] :: :aqua [%dojo ~[~bud] "|hi ~dev"] :: :aqua [%pause-events ~[~bud ~dev]] +:: :aqua [%wish ~[~bud ~dev] '(add 2 3)'] +:: :aqua [%peek ~[~bud] /cx/~bud/home/(scot %da now)/app/curl/hoon] :: :: :: We get ++unix-event and ++pill from /-pill @@ -88,13 +90,33 @@ =^ ovo next-events ~(get to next-events) =/ res (mox +47.snap) ?> ?=(%0 -.res) - =+ poke=p.res - =+ res=(slum poke now.hid ovo) + =/ poke p.res + =/ res (slum poke now.hid ovo) =. event-log [ovo event-log] =. snap +3.res =. ..abet (handle-effects ((list ovum) -.res)) $ :: + :: Peek + :: + ++ peek + |= p=* + =/ res (mox +46.snap) + ?> ?=(%0 -.res) + =/ peek p.res + ~& [who=who %peeked (slum peek [now.hid p])] + ..abet + :: + :: Wish + :: + ++ wish + |= txt=@t + =/ res (mox +22.snap) + ?> ?=(%0 -.res) + =/ wish p.res + ~& [who=who %wished (slum wish txt)] + ..abet + :: :: Restart outstanding requests :: ++ restore @@ -402,6 +424,30 @@ |= [who=ship thus=_this] =. this thus (push-events:(pe who) ~[u.ovo]) + :: + [%peek hers=* p=*] + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + (peek:(pe who) p.val) + :: + [%wish hers=* p=@t] + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + (wish:(pe who) p.val) + :: + [%unpause-events hers=*] + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + start-processing-events:(pe who) + :: + [%pause-events hers=*] + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + stop-processing-events:(pe who) :: [%snap-fleet lab=@tas] =. fleet-snaps (~(put by fleet-snaps) lab.val piers) @@ -420,34 +466,6 @@ =. this thus restore:(pe who) [(weld moves-1 moves-2) this] - :: - [%peek who=@p p=*] - :: should resurrect - :: =+ res=(mox +46.snap) - :: ?> ?=(%0 -.res) - :: =+ peek=p.res - :: ~& (slum peek p.val) - `this - :: - [%wish who=@p p=@t] - :: should resurrect - :: =+ res=(mox +22.snap) - :: ?> ?=(%0 -.res) - :: =+ wish=p.res - :: ~& (slum wish p.val) - `this - :: - [%unpause-events hers=*] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - start-processing-events:(pe who) - :: - [%pause-events hers=*] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - stop-processing-events:(pe who) == :: :: Run a callback function against a list of ships, aggregating state From 81e8c5928004c13229c4bb3b7214c788fbbc071f Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 4 Feb 2019 16:05:34 -0800 Subject: [PATCH 009/133] implement barebones clay file injection --- app/aqua.hoon | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 818dc34f5..7392a0d76 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -5,9 +5,11 @@ :: :aqua [%init ~[~bud ~dev]] :: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] :: :aqua [%dojo ~[~bud] "|hi ~dev"] -:: :aqua [%pause-events ~[~bud ~dev]] :: :aqua [%wish ~[~bud ~dev] '(add 2 3)'] :: :aqua [%peek ~[~bud] /cx/~bud/home/(scot %da now)/app/curl/hoon] +:: :aqua [%dojo ~[~bud ~dev] '|mount %'] +:: :aqua [%file ~[~bud ~dev] %/sys/vane] +:: :aqua [%pause-events ~[~bud ~dev]] :: :: :: We get ++unix-event and ++pill from /-pill @@ -27,6 +29,7 @@ [%send p=lane:ames q=@] [%doze p=(unit @da)] [%thus p=@ud q=(unit hiss:eyre)] + [%ergo p=@tas q=mode:clay] == ++ state $: %0 @@ -175,6 +178,7 @@ %send (handle-send u.sof) %doze (handle-doze u.sof) %thus (handle-thus u.sof) + %ergo (handle-ergo u.sof) == $(effects t.effects) :: @@ -229,7 +233,7 @@ ?. &(=(0 (rsh 0 16 u.dest-ip)) =(1 (rsh 0 8 u.dest-ip))) ~& [%havent-implemented-direct-lanes who lan] ..abet - ~& [%blast-sending who=who] + ~& [who=who %blast-sending] =/ hear [//newt/0v1n.2m9vh %hear lan pac] =. this (blast-event hear) :: =/ her ?:(=(~dev who) ~bud ~dev) ::ship (dis u.dest-ip 0xff) @@ -259,11 +263,9 @@ |= tim=@da =. tim +(tim) :: nobody's perfect =. next-timer `tim - ~& [%sleeping-until who tim] (emit-moves [ost.hid %wait /(scot %p who) tim]~) :: ++ cancel-timer - ~& [%cancelling-timer who] (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) :: ++ take-wake @@ -284,7 +286,7 @@ :: so we remove it from our state so we won't pass along the :: response. :: - ~& [%cant-cancel-thus who=who num=num] + ~& [who=who %cant-cancel-thus num=num] =. http-requests (~(del in http-requests) num) ..abet =. http-requests (~(put in http-requests) num) @@ -305,7 +307,7 @@ ?> ?=([@ ~] way) =/ num (slav %ud i.way) ?. (~(has in http-requests) num) - ~& [%ignoring-httr who=who num=num] + ~& [who=who %ignoring-httr num=num] ..abet =. http-requests (~(del in http-requests) num) (push-events [//http/0v1n.2m9vh %they num res]~) @@ -318,11 +320,22 @@ ?> ?=([@ ~] way) =/ num (slav %ud i.way) ?. (~(has in http-requests) num) - ~& [%ignoring-httr who=who num=num] + ~& [who=who %ignoring-httr num=num] ..abet =. http-requests (~(del in http-requests) num) %- (slog tan) ..abet + :: + :: We should mirror a mount point of child to a clay desk of host. + :: For now, we just allow injecting a change to the child, so we + :: throw away ergos. + :: + ++ handle-ergo + |= [way=wire %ergo mount-point=@tas mod=mode:clay] + ^+ ..abet + ~& [who=who %file-changes (turn mod head)] + ..abet + :: -- :: ++ this . @@ -424,6 +437,16 @@ |= [who=ship thus=_this] =. this thus (push-events:(pe who) ~[u.ovo]) + :: + [%file hers=* pax=*] + =/ pax (path pax.val) + ?> ?=([@ @ @ *] pax) + =/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] + %+ turn-ships ((list ship) hers.val) + |= [who=ship thus=_this] + =. this thus + %- push-events:(pe who) + [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~]~ :: [%peek hers=* p=*] %+ turn-ships ((list ship) hers.val) From da5515b6a8c7f10e07f2a636d78a8ef1bddc9cd9 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Tue, 5 Feb 2019 18:21:41 -0800 Subject: [PATCH 010/133] first integration test --- app/aqua.hoon | 94 ++++++++++++++++++++++------- app/ph.hoon | 149 ++++++++++++++++++++++++++++++++++++++++++++++ lib/ph.hoon | 72 ++++++++++++++++++++++ mar/pill.hoon | 4 +- sur/aquarium.hoon | 29 +++++++++ sur/pill.hoon | 12 ---- 6 files changed, 326 insertions(+), 34 deletions(-) create mode 100644 app/ph.hoon create mode 100644 lib/ph.hoon create mode 100644 sur/aquarium.hoon delete mode 100644 sur/pill.hoon diff --git a/app/aqua.hoon b/app/aqua.hoon index 7392a0d76..3ac9763ec 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -1,7 +1,9 @@ +:: An aquarium of virtual ships. Put in some fish and watch them! +:: :: usage: :: |start %aqua -:: /- pill -:: :aqua &pill .^(pill:pill %cx %/urbit/pill) +:: /- aquarium +:: :aqua &pill .^(pill:aquarium %cx %/urbit/pill) :: :aqua [%init ~[~bud ~dev]] :: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] :: :aqua [%dojo ~[~bud] "|hi ~dev"] @@ -12,24 +14,17 @@ :: :aqua [%pause-events ~[~bud ~dev]] :: :: -:: We get ++unix-event and ++pill from /-pill +:: We get ++unix-event and ++pill from /-aquarium :: -/- pill -=, pill +/- aquarium +=, aquarium => $~ |% ++ move (pair bone card) ++ card $% [%wait wire p=@da] [%rest wire p=@da] [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] - == - ++ unix-effect - %+ pair wire - $% [%blit p=(list blit:dill)] - [%send p=lane:ames q=@] - [%doze p=(unit @da)] - [%thus p=@ud q=(unit hiss:eyre)] - [%ergo p=@tas q=mode:clay] + [%diff %aqua-effect aqua-effect] == ++ state $: %0 @@ -48,7 +43,7 @@ == -- =, gall -|_ $: hid/bowl +|_ $: hid=bowl state == :: @@ -173,13 +168,15 @@ ?~ sof ~& [who=who %unknown-effect i.effects] ..abet - ?- -.q.u.sof + =. ..abet + ?- -.q.u.sof %blit (handle-blit u.sof) %send (handle-send u.sof) %doze (handle-doze u.sof) %thus (handle-thus u.sof) %ergo (handle-ergo u.sof) - == + == + (publish-effect u.sof) $(effects t.effects) :: :: Would love to see a proper stateful terminal handler. Ideally, @@ -336,6 +333,18 @@ ~& [who=who %file-changes (turn mod head)] ..abet :: + :: Give effect to our subscribers + :: + ++ publish-effect + |= ovo=unix-effect + ^+ ..abet + %- emit-moves + %+ murn ~(tap by sup.hid) + |= [b=bone her=ship pax=path] + ^- (unit move) + ?. =(/effects/(scot %p who) pax) + ~ + `[b %diff %aqua-effect who ovo] -- :: ++ this . @@ -360,6 +369,19 @@ =/ nex $ nex(- (weld -.nex moves)) :: +:: Subscribe to effects from a ship +:: +++ peer-effects + |= pax=path + ^- (quip move _this) + ?. ?=([@ ~] pax) + ~& [%aqua-bad-peer-effects pax] + `this + ?~ (slaw %p i.pax) + ~& [%aqua-bad-peer-effects-ship pax] + `this + `this +:: :: Load a pill and assemble arvo. Doesn't send any of the initial :: events. :: @@ -386,10 +408,12 @@ `this == :: -:: Handle commands +:: Handle commands from CLI :: :: Should put some thought into arg structure, maybe make a mark. :: +:: Should convert some of these to just rewrite into ++poke-events. +:: ++ poke-noun |= val=* ^- (quip move _this) @@ -491,6 +515,33 @@ [(weld moves-1 moves-2) this] == :: +:: +:: +++ poke-aqua-events + |= events=(list aqua-event) + ^- (quip move _this) + %+ turn-events events + |= [ovo=aqua-event thus=_this] + =. this thus + ?- -.ovo + %init-ship + %- push-events:apex:(pe who.ovo) + ^- (list unix-event) + :~ [/ %wack 0] :: eny + [/ %whom who.ovo] :: eny + [//newt/0v1n.2m9vh %barn ~] + [//behn/0v1n.2m9vh %born ~] + [//term/1 %boot %fake who.ovo] + -.userspace-ova.pil + [//http/0v1n.2m9vh %born ~] + [//http/0v1n.2m9vh %live 8.080 `8.445] + [//term/1 %belt %ctl `@c`%x] + == + :: + %event + (push-events:(pe who.ovo) [ovo.ovo]~) + == +:: :: Run a callback function against a list of ships, aggregating state :: and plowing all ships at the end. :: @@ -510,8 +561,9 @@ :: restrict the callbacks to always have `this` at a particular axis, :: and that doesn't feel right :: -++ turn-ships - |= [hers=(list ship) fun=$-([ship _this] _(pe))] +++ turn-plow + |* arg=mold + |= [hers=(list arg) fun=$-([arg _this] _(pe))] |- ^- (quip move _this) ?~ hers =^ moves this plow-all @@ -521,6 +573,9 @@ =^ nex-moves this $(hers t.hers, this this) [(weld moves nex-moves) this] :: +++ turn-ships (turn-plow ship) +++ turn-events (turn-plow aqua-event) +:: :: Send the same event to all ships :: ++ blast-event @@ -540,7 +595,6 @@ ^- (quip move _this) ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) - ~& [%waking who] %+ turn-ships ~[who] |= [who=ship thus=_this] =. this thus diff --git a/app/ph.hoon b/app/ph.hoon new file mode 100644 index 000000000..5d8fd6a76 --- /dev/null +++ b/app/ph.hoon @@ -0,0 +1,149 @@ +:: Test the pH of your aquarium. See if it's safe to put real fish in. +:: +:: usage: +:: :aqua [%run-test %test-add] +:: +:: TODO: +:: - Restore a fleet +:: - Compose tests +:: +/- aquarium +/+ ph +=, aquarium +=, ph +=> $~ |% + ++ move (pair bone card) + ++ card + $% [%peer wire dock path] + [%poke wire dock %aqua-events (list aqua-event)] + == + :: + ++ test-map (map term test-core) + :: + ++ state + $: %0 + test-cores=test-map + other-state + == + ++ other-state + $~ + -- +=, gall +|_ $: hid=bowl + state + == +++ this . +++ install-tests + ^+ this + =. test-cores + %- malt + ^- (list (pair term test-core)) + :~ + :- %test-add + |% + ++ start + ^- (pair (list ship) (list ph-event)) + :- ~[~bud] + %- zing + :~ (init ~bud) + (dojo ~bud "[%test-result (add 2 3)]") + == + :: + ++ route + |= ovo=aqua-effect + ^- (list ph-event) + (expect-dojo-output ~bud ovo "[%test-result 5]") + :: XX if it's been five minutes, we failed + -- + :: + :- %test-hi + |% + ++ start + ^- (pair (list ship) (list ph-event)) + :- ~[~bud ~dev] + %- zing + :~ (init ~bud) + (init ~dev) + (dojo ~bud "|hi ~dev") + == + :: + ++ route + |= ovo=aqua-effect + ^- (list ph-event) + :: + :: doesn't work because for some reason we lose the + :: subscription immediately after opening it. maybe + :: because we receive so many events without immediate + :: reap it triggers the backpressure mechanism in gall? + :: + (expect-dojo-output ~bud ovo "hi ~dev successful") + -- + == + this +:: +++ prep + |= old=(unit [@ tests=* rest=*]) + ^- [(list move) _this] + =. this install-tests + ?~ old + `this + =/ new ((soft other-state) rest.u.old) + ?~ new + `this + `this(+<+>+ u.new) +:: +++ run-events + |= what=(list ph-event) + ^- [(list move) _this] + ?: =(~ what) + `this + =/ res + |- ^- (each (list aqua-event) $~) + ?~ what + [%& ~] + ?: ?=(%test-done -.i.what) + ~& ?~(p.i.what "test successful" "test failed") + [%| ~] + =/ nex $(what t.what) + ?: ?=(%| -.nex) + nex + [%& `aqua-event`i.what p.nex] + ?: ?=(%| -.res) + `this + [[ost.hid %poke /running [our.hid %aqua] %aqua-events p.res]~ this] +:: +:: Should check whether we're already subscribed +:: +++ subscribe-to-effects + |= [lab=@tas hers=(list ship)] + :_ this + %+ turn hers + |= her=ship + ^- move + :* ost.hid + %peer + /[lab]/(scot %p her) + [our.hid %aqua] + /effects/(scot %p her) + == +:: +++ poke-noun + |= arg=* + ^- (quip move _this) + ?+ arg ~|(%bad-noun-arg !!) + [%run-test lab=@tas] + =/ res=[hers=(list ship) events=(list ph-event)] + start:(~(got by test-cores) lab.arg) + =^ moves-1 this (subscribe-to-effects lab.arg hers.res) + =^ moves-2 this (run-events events.res) + [(weld moves-1 moves-2) this] + == +:: +++ diff-aqua-effect + |= [way=wire ovo=aqua-effect] + ^- (quip move _this) + :: ~& [%diff-aqua-effect way -.q.ovo.ovo] + ?> ?=([@ @ ~] way) + =/ lab i.way + (run-events (route:(~(got by test-cores) lab) ovo)) +-- diff --git a/lib/ph.hoon b/lib/ph.hoon new file mode 100644 index 000000000..81ea46ea4 --- /dev/null +++ b/lib/ph.hoon @@ -0,0 +1,72 @@ +:: +:::: /hoon/ph/lib + :: +/- aquarium +=, aquarium +|% +:: Defines a complete integration test. +:: +:: Perhaps route should take a unix-effect rather than a sign. +:: Similarly, perhaps ++abet should produce a list of +:: unix-events. Also, perhaps we should support state. +:: +:: Perhaps closer to this: +:: ++ test-core +:: $_ ^? +:: |% +:: ++ start ^?(..abet) +:: ++ route |~([wire unix-effect] ^?(..abet)) +:: ++ abet *(list unix-event) +:: -- +:: +++ test-core + $_ ^? + |% + ++ start *(pair (list ship) (list ph-event)) + ++ route |~(aqua-effect *(list ph-event)) + -- +:: +++ ph-event + $% [%test-done p=?] + aqua-event + == +:: +++ send-events-to + |= [who=ship what=(list unix-event)] + ^- (list ph-event) + %+ turn what + |= ovo=unix-event + [%event who ovo] +:: +++ init + |= who=ship + ^- (list ph-event) + [%init-ship who]~ +:: +:: factor out send-events-to +:: +++ dojo + |= [who=ship what=tape] + ^- (list ph-event) + %+ send-events-to who + ^- (list unix-event) + :~ + [//term/1 %belt %ctl `@c`%e] + [//term/1 %belt %ctl `@c`%u] + [//term/1 %belt %txt ((list @c) what)] + [//term/1 %belt %ret ~] + == +:: +++ expect-dojo-output + |= [who=ship ovo=aqua-effect what=tape] + ^- (list ph-event) + ?. ?=(%blit -.q.ovo.ovo) + ~ + ?. %+ lien p.q.ovo.ovo + |= =blit:dill + ?. ?=(%lin -.blit) + | + !=(~ (find what p.blit)) + ~ + [%test-done &]~ +-- diff --git a/mar/pill.hoon b/mar/pill.hoon index 1f0c6447e..15c0cdf6d 100644 --- a/mar/pill.hoon +++ b/mar/pill.hoon @@ -1,8 +1,8 @@ :: :::: /hoon/pill/mar :: -/- pill -=, pill +/- aquarium +=, aquarium =, mimes:html |_ pil=pill ++ grow diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon new file mode 100644 index 000000000..d6bf34356 --- /dev/null +++ b/sur/aquarium.hoon @@ -0,0 +1,29 @@ +|% +++ aqua-event + $% [%init-ship who=ship] + [%event who=ship ovo=unix-event] + == +:: +++ aqua-effect + ,[who=ship ovo=unix-effect] +:: +++ unix-event + %+ pair wire + $% [%wack p=@] + [%whom p=ship] + [%live p=@ud q=(unit @ud)] + [%barn ~] + [%boot %fake p=ship] + unix-task + == +:: +++ unix-effect + %+ pair wire + $% [%blit p=(list blit:dill)] + [%send p=lane:ames q=@] + [%doze p=(unit @da)] + [%thus p=@ud q=(unit hiss:eyre)] + [%ergo p=@tas q=mode:clay] + == ++= pill [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] +-- diff --git a/sur/pill.hoon b/sur/pill.hoon deleted file mode 100644 index 33d06604b..000000000 --- a/sur/pill.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|% -++ unix-event - %+ pair wire - $% [%wack p=@] - [%whom p=ship] - [%live p=@ud q=(unit @ud)] - [%barn ~] - [%boot %fake p=ship] - unix-task - == -+= pill [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] --- From 1cfea70e8b300f41134b6f095f134d5abe31d7a9 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 7 Feb 2019 17:12:57 -0800 Subject: [PATCH 011/133] hoist moves into variable --- app/aqua.hoon | 152 ++++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 3ac9763ec..26227bf86 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -43,6 +43,10 @@ == -- =, gall +:: +:: Hoist moves into state for cleaner state management +:: +=| moves=(list move) |_ $: hid=bowl state == @@ -53,38 +57,37 @@ |= who=ship =+ (fall (~(get by piers) who) *pier) =* pier-data - - =| moves=(list move) |% - ++ abet - ^- (quip move _this) + ++ abet-pe + ^+ this =. piers (~(put by piers) who pier-data) - [(flop moves) this] + this :: ++ apex =. pier-data *pier =. snap assembled ~& r=(met 3 (jam snap)) - ..abet + ..abet-pe :: ++ push-events |= ova=(list unix-event) - ^+ ..abet + ^+ ..abet-pe =. next-events (~(gas to next-events) ova) - ..abet + ..abet-pe :: ++ emit-moves |= ms=(list move) =. moves (weld ms moves) - ..abet + ..abet-pe :: :: Process the events in our queue. :: ++ plow - |- ^+ ..abet + |- ^+ ..abet-pe ?: =(~ next-events) - ..abet + ..abet-pe ?. processing-events - ..abet + ..abet-pe =^ ovo next-events ~(get to next-events) =/ res (mox +47.snap) ?> ?=(%0 -.res) @@ -92,7 +95,7 @@ =/ res (slum poke now.hid ovo) =. event-log [ovo event-log] =. snap +3.res - =. ..abet (handle-effects ((list ovum) -.res)) + =. ..abet-pe (handle-effects ((list ovum) -.res)) $ :: :: Peek @@ -103,7 +106,7 @@ ?> ?=(%0 -.res) =/ peek p.res ~& [who=who %peeked (slum peek [now.hid p])] - ..abet + ..abet-pe :: :: Wish :: @@ -113,40 +116,40 @@ ?> ?=(%0 -.res) =/ wish p.res ~& [who=who %wished (slum wish txt)] - ..abet + ..abet-pe :: :: Restart outstanding requests :: ++ restore - ^+ ..abet + ^+ ..abet-pe :: Restore behn :: - =. ..abet + =. ..abet-pe ?~ next-timer - ..abet + ..abet-pe (set-timer u.next-timer) :: Restore eyre :: =. http-requests ~ - =. ..abet (push-events [//http/0v1n.2m9vh %born ~]~) - ..abet + =. ..abet-pe (push-events [//http/0v1n.2m9vh %born ~]~) + ..abet-pe :: :: Cancel outstanding requests :: ++ sleep - ^+ ..abet + ^+ ..abet-pe :: Sleep behn :: - =. ..abet + =. ..abet-pe ?~ next-timer - ..abet + ..abet-pe cancel-timer :: Sleep eyre :: :: Eyre doesn't support cancelling HTTP requests from userspace. :: =. http-requests ~ - ..abet + ..abet-pe :: ++ mox |=(* (mock [snap +<] scry)) :: @@ -160,15 +163,15 @@ :: ++ handle-effects |= effects=(list ovum) - ^+ ..abet + ^+ ..abet-pe ?~ effects - ..abet - =. ..abet + ..abet-pe + =. ..abet-pe =/ sof ((soft unix-effect) i.effects) ?~ sof ~& [who=who %unknown-effect i.effects] - ..abet - =. ..abet + ..abet-pe + =. ..abet-pe ?- -.q.u.sof %blit (handle-blit u.sof) %send (handle-send u.sof) @@ -190,7 +193,7 @@ :: ++ handle-blit |= [way=wire %blit blits=(list blit:dill)] - ^+ ..abet + ^+ ..abet-pe =/ last-line %+ roll blits |= [b=blit:dill line=tape] @@ -205,7 +208,7 @@ %url ~& [%activate-url p.b] line == ~& last-line - ..abet + ..abet-pe :: :: This needs a better SDN solution. Every ship should have an IP :: address, and we should eventually test changing those IP @@ -216,7 +219,7 @@ :: ++ handle-send |= [way=wire %send lan=lane:ames pac=@] - ^+ ..abet + ^+ ..abet-pe =/ dest-ip |- ^- (unit @if) ?- -.lan @@ -226,31 +229,31 @@ == ?~ dest-ip ~& [%sending-no-destination who lan] - ..abet + ..abet-pe ?. &(=(0 (rsh 0 16 u.dest-ip)) =(1 (rsh 0 8 u.dest-ip))) ~& [%havent-implemented-direct-lanes who lan] - ..abet + ..abet-pe ~& [who=who %blast-sending] =/ hear [//newt/0v1n.2m9vh %hear lan pac] =. this (blast-event hear) :: =/ her ?:(=(~dev who) ~bud ~dev) ::ship (dis u.dest-ip 0xff) :: ?. (~(has by piers) her) :: ~& [%dropping who=who her=her] - :: ..abet + :: ..abet-pe :: ~& [%sending who=who her=her ip=`@ux`u.dest-ip] :: =^ ms this - :: abet:(push-events:(pe her) ~[hear]) - ..abet + :: abet-pe:(push-events:(pe her) ~[hear]) + ..abet-pe :: :: Would love to be able to control time more precisely, jumping :: forward and whatnot. :: ++ handle-doze |= [way=wire %doze tim=(unit @da)] - ^+ ..abet + ^+ ..abet-pe ?~ tim ?~ next-timer - ..abet + ..abet-pe cancel-timer ?~ next-timer (set-timer u.tim) @@ -275,17 +278,17 @@ :: ++ handle-thus |= [way=wire %thus num=@ud req=(unit hiss:eyre)] - ^+ ..abet + ^+ ..abet-pe ?~ req ?. (~(has in http-requests) num) - ..abet + ..abet-pe :: Eyre doesn't support cancelling HTTP requests from userspace, :: so we remove it from our state so we won't pass along the :: response. :: ~& [who=who %cant-cancel-thus num=num] =. http-requests (~(del in http-requests) num) - ..abet + ..abet-pe =. http-requests (~(put in http-requests) num) %- emit-moves :_ ~ :* ost.hid @@ -300,12 +303,12 @@ :: ++ take-sigh-httr |= [way=wire res=httr:eyre] - ^+ ..abet + ^+ ..abet-pe ?> ?=([@ ~] way) =/ num (slav %ud i.way) ?. (~(has in http-requests) num) ~& [who=who %ignoring-httr num=num] - ..abet + ..abet-pe =. http-requests (~(del in http-requests) num) (push-events [//http/0v1n.2m9vh %they num res]~) :: @@ -313,15 +316,15 @@ :: ++ take-sigh-tang |= [way=wire tan=tang] - ^+ ..abet + ^+ ..abet-pe ?> ?=([@ ~] way) =/ num (slav %ud i.way) ?. (~(has in http-requests) num) ~& [who=who %ignoring-httr num=num] - ..abet + ..abet-pe =. http-requests (~(del in http-requests) num) %- (slog tan) - ..abet + ..abet-pe :: :: We should mirror a mount point of child to a clay desk of host. :: For now, we just allow injecting a change to the child, so we @@ -329,15 +332,15 @@ :: ++ handle-ergo |= [way=wire %ergo mount-point=@tas mod=mode:clay] - ^+ ..abet + ^+ ..abet-pe ~& [who=who %file-changes (turn mod head)] - ..abet + ..abet-pe :: :: Give effect to our subscribers :: ++ publish-effect |= ovo=unix-effect - ^+ ..abet + ^+ ..abet-pe %- emit-moves %+ murn ~(tap by sup.hid) |= [b=bone her=ship pax=path] @@ -348,11 +351,12 @@ -- :: ++ this . +++ abet-aqua [(flop moves) this] :: :: Run all events on all ships until all queues are empty :: ++ plow-all - |- ^- (quip move _this) + |- ^+ this =/ who =/ pers ~(tap by piers) |- ^- (unit ship) @@ -364,10 +368,9 @@ $(pers t.pers) ~& plowing=who ?~ who - `this - =^ moves this abet:plow:(pe u.who) - =/ nex $ - nex(- (weld -.nex moves)) + this + =. this abet-pe:plow:(pe u.who) + $ :: :: Subscribe to effects from a ship :: @@ -388,6 +391,7 @@ ++ poke-pill |= p=pill ^- (quip move _this) + =< abet-aqua =. pil p ~& lent=(met 3 (jam boot-ova.pil)) =/ res=toon :: (each * (list tank)) @@ -396,16 +400,16 @@ %0 ~& %suc =. assembled +7.p.res - `this + this :: %1 ~& [%vere-blocked p.res] - `this + this :: %2 ~& %vere-fail %- (slog p.res) - `this + this == :: :: Handle commands from CLI @@ -417,6 +421,8 @@ ++ poke-noun |= val=* ^- (quip move _this) + =< abet-aqua + ^+ this :: Could potentially factor out the three lines of turn-ships :: boilerplate :: @@ -456,7 +462,7 @@ =/ ovo ((soft unix-event) ovo.val) ?~ ovo ~& %ovo-not-an-event - `this + this %+ turn-ships ((list ship) hers.val) |= [who=ship thus=_this] =. this thus @@ -498,28 +504,29 @@ :: [%snap-fleet lab=@tas] =. fleet-snaps (~(put by fleet-snaps) lab.val piers) - `this + this :: [%restore-fleet lab=@tas] - =^ moves-1 this + =. this %+ turn-ships (turn ~(tap by piers) head) |= [who=ship thus=_this] =. this thus sleep:(pe who) =. piers (~(got by fleet-snaps) lab.val) - =^ moves-2 this + =. this %+ turn-ships (turn ~(tap by piers) head) |= [who=ship thus=_this] =. this thus restore:(pe who) - [(weld moves-1 moves-2) this] + this == :: -:: +:: Apply a list of events tagged by ship :: ++ poke-aqua-events |= events=(list aqua-event) ^- (quip move _this) + =< abet-aqua %+ turn-events events |= [ovo=aqua-event thus=_this] =. this thus @@ -564,14 +571,12 @@ ++ turn-plow |* arg=mold |= [hers=(list arg) fun=$-([arg _this] _(pe))] - |- ^- (quip move _this) + |- ^+ this ?~ hers - =^ moves this plow-all - [moves this] - =^ moves this - abet:plow:(fun i.hers this) - =^ nex-moves this $(hers t.hers, this this) - [(weld moves nex-moves) this] + plow-all + =. this + abet-pe:plow:(fun i.hers this) + $(hers t.hers, this this) :: ++ turn-ships (turn-plow ship) ++ turn-events (turn-plow aqua-event) @@ -584,8 +589,8 @@ |- ^+ this ?~ pers this - =^ moves-dropped this - abet:(push-events:(pe p.i.pers) ~[ovo]) + =. this + abet-pe:(push-events:(pe p.i.pers) ~[ovo]) $(pers t.pers) :: :: Received timer wake @@ -593,6 +598,7 @@ ++ wake |= [way=wire ~] ^- (quip move _this) + =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) %+ turn-ships ~[who] @@ -605,6 +611,7 @@ ++ sigh-httr |= [way=wire res=httr:eyre] ^- (quip move _this) + =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] @@ -618,6 +625,7 @@ ++ sigh-tang |= [way=wire tan=tang] ^- (quip move _this) + =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] From 39ce13817b049154be94cafe50122c677f49e173 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 7 Feb 2019 18:03:46 -0800 Subject: [PATCH 012/133] test-hi works --- app/aqua.hoon | 58 +++++++++++++++++++++++++++++++++++------------ app/ph.hoon | 24 +++++++++++++------- lib/ph.hoon | 10 ++++---- sur/aquarium.hoon | 4 ++-- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 26227bf86..ab1abc9e6 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -24,7 +24,7 @@ $% [%wait wire p=@da] [%rest wire p=@da] [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] - [%diff %aqua-effect aqua-effect] + [%diff %aqua-effects aqua-effects] == ++ state $: %0 @@ -44,8 +44,11 @@ -- =, gall :: -:: Hoist moves into state for cleaner state management +:: aqua-effect-list: collect list of aqua effects to broadcast at once +:: to avoid gall backpressure +:: moves: Hoist moves into state for cleaner state management :: +=| unix-effects=(jar ship unix-effect) =| moves=(list move) |_ $: hid=bowl state @@ -77,7 +80,7 @@ :: ++ emit-moves |= ms=(list move) - =. moves (weld ms moves) + =. this (^emit-moves ms) ..abet-pe :: :: Process the events in our queue. @@ -341,17 +344,42 @@ ++ publish-effect |= ovo=unix-effect ^+ ..abet-pe + =. unix-effects (~(add ja unix-effects) who ovo) + ..abet-pe + -- +:: +++ this . +:: +:: ++apex-aqua and ++abet-aqua must bookend calls from gall +:: +++ apex-aqua + ^+ this + =: moves ~ + unix-effects ~ + == + this +:: +++ abet-aqua + ^- (quip move _this) + =. this %- emit-moves %+ murn ~(tap by sup.hid) |= [b=bone her=ship pax=path] ^- (unit move) - ?. =(/effects/(scot %p who) pax) + ?. ?=([%effects @ ~] pax) ~ - `[b %diff %aqua-effect who ovo] - -- + =/ who (slav %p i.t.pax) + =/ fx (~(get ja unix-effects) who) + ?~ fx + ~ + `[b %diff %aqua-effects who fx] + [(flop moves) this] +:: +++ emit-moves + |= ms=(list move) + =. moves (weld ms moves) + this :: -++ this . -++ abet-aqua [(flop moves) this] :: :: Run all events on all ships until all queues are empty :: @@ -382,7 +410,7 @@ `this ?~ (slaw %p i.pax) ~& [%aqua-bad-peer-effects-ship pax] - `this + !! `this :: :: Load a pill and assemble arvo. Doesn't send any of the initial @@ -391,7 +419,7 @@ ++ poke-pill |= p=pill ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua =. pil p ~& lent=(met 3 (jam boot-ova.pil)) =/ res=toon :: (each * (list tank)) @@ -421,7 +449,7 @@ ++ poke-noun |= val=* ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua ^+ this :: Could potentially factor out the three lines of turn-ships :: boilerplate @@ -526,7 +554,7 @@ ++ poke-aqua-events |= events=(list aqua-event) ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua %+ turn-events events |= [ovo=aqua-event thus=_this] =. this thus @@ -598,7 +626,7 @@ ++ wake |= [way=wire ~] ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) %+ turn-ships ~[who] @@ -611,7 +639,7 @@ ++ sigh-httr |= [way=wire res=httr:eyre] ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] @@ -625,7 +653,7 @@ ++ sigh-tang |= [way=wire tan=tang] ^- (quip move _this) - =< abet-aqua + =. this apex-aqua =< abet-aqua ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] diff --git a/app/ph.hoon b/app/ph.hoon index 5d8fd6a76..c9515eb2c 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -50,9 +50,9 @@ == :: ++ route - |= ovo=aqua-effect + |= [who=ship ovo=unix-effect] ^- (list ph-event) - (expect-dojo-output ~bud ovo "[%test-result 5]") + (expect-dojo-output ~bud who ovo "[%test-result 5]") :: XX if it's been five minutes, we failed -- :: @@ -68,7 +68,7 @@ == :: ++ route - |= ovo=aqua-effect + |= [who=ship ovo=unix-effect] ^- (list ph-event) :: :: doesn't work because for some reason we lose the @@ -76,7 +76,7 @@ :: because we receive so many events without immediate :: reap it triggers the backpressure mechanism in gall? :: - (expect-dojo-output ~bud ovo "hi ~dev successful") + (expect-dojo-output ~bud who ovo "hi ~dev successful") -- == this @@ -129,6 +129,7 @@ :: ++ poke-noun |= arg=* + ~& %herm ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) [%run-test lab=@tas] @@ -139,11 +140,18 @@ [(weld moves-1 moves-2) this] == :: -++ diff-aqua-effect - |= [way=wire ovo=aqua-effect] +++ diff-aqua-effects + |= [way=wire ova=aqua-effects] ^- (quip move _this) - :: ~& [%diff-aqua-effect way -.q.ovo.ovo] + :: ~& [%diff-aqua-effect way who.ova] ?> ?=([@ @ ~] way) =/ lab i.way - (run-events (route:(~(got by test-cores) lab) ovo)) + %- run-events + |- ^- (list ph-event) + ?~ ovo.ova + ~ + ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] + %+ weld + (route:(~(got by test-cores) lab) who.ova i.ovo.ova) + $(ovo.ova t.ovo.ova) -- diff --git a/lib/ph.hoon b/lib/ph.hoon index 81ea46ea4..5978fff34 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -23,7 +23,7 @@ $_ ^? |% ++ start *(pair (list ship) (list ph-event)) - ++ route |~(aqua-effect *(list ph-event)) + ++ route |~([ship unix-effect] *(list ph-event)) -- :: ++ ph-event @@ -58,11 +58,13 @@ == :: ++ expect-dojo-output - |= [who=ship ovo=aqua-effect what=tape] + |= [who=ship her=ship ovo=unix-effect what=tape] ^- (list ph-event) - ?. ?=(%blit -.q.ovo.ovo) + ?. =(who her) ~ - ?. %+ lien p.q.ovo.ovo + ?. ?=(%blit -.q.ovo) + ~ + ?. %+ lien p.q.ovo |= =blit:dill ?. ?=(%lin -.blit) | diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index d6bf34356..c265485fa 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -4,8 +4,8 @@ [%event who=ship ovo=unix-event] == :: -++ aqua-effect - ,[who=ship ovo=unix-effect] +++ aqua-effects + ,[who=ship ovo=(list unix-effect)] :: ++ unix-event %+ pair wire From 705a5315583340ec84579df60e1f60f5f30ff93b Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Feb 2019 11:52:36 -0800 Subject: [PATCH 013/133] add init cache to aqua for faster boot times --- app/aqua.hoon | 58 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index ab1abc9e6..a4ee3f3a3 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -30,6 +30,7 @@ $: %0 pil=pill assembled=* + init-cache=(map ship pier) fleet-snaps=(map term (map ship pier)) piers=(map ship pier) == @@ -560,18 +561,30 @@ =. this thus ?- -.ovo %init-ship - %- push-events:apex:(pe who.ovo) - ^- (list unix-event) - :~ [/ %wack 0] :: eny - [/ %whom who.ovo] :: eny - [//newt/0v1n.2m9vh %barn ~] - [//behn/0v1n.2m9vh %born ~] - [//term/1 %boot %fake who.ovo] - -.userspace-ova.pil - [//http/0v1n.2m9vh %born ~] - [//http/0v1n.2m9vh %live 8.080 `8.445] - [//term/1 %belt %ctl `@c`%x] - == + =/ prev (~(get by init-cache) who.ovo) + ?^ prev + ~& [%loading-cached-ship who.ovo] + =. this (restore-ships ~[who.ovo] init-cache) + (pe who.ovo) + =/ initted + =< plow + %- push-events:apex:(pe who.ovo) + ^- (list unix-event) + :~ [/ %wack 0] :: eny + [/ %whom who.ovo] :: eny + [//newt/0v1n.2m9vh %barn ~] + [//behn/0v1n.2m9vh %born ~] + [//term/1 %boot %fake who.ovo] + -.userspace-ova.pil + [//http/0v1n.2m9vh %born ~] + [//http/0v1n.2m9vh %live 8.080 `8.445] + [//term/1 %belt %ctl `@c`%x] + == + =. this abet-pe:initted + =. init-cache + %+ ~(put by init-cache) who.ovo + (~(got by piers) who.ovo) + (pe who.ovo) :: %event (push-events:(pe who.ovo) [ovo.ovo]~) @@ -621,6 +634,27 @@ abet-pe:(push-events:(pe p.i.pers) ~[ovo]) $(pers t.pers) :: +:: Restore ships +:: +++ restore-ships + |= [hers=(list ship) from=(map ship pier)] + =. this + %+ turn-ships hers + |= [who=ship thus=_this] + =. this thus + sleep:(pe who) + =. piers + %- ~(gas by piers) + %+ turn hers + |= her=ship + [her (~(got by from) her)] + =. this + %+ turn-ships hers + |= [who=ship thus=_this] + =. this thus + restore:(pe who) + this +:: :: Received timer wake :: ++ wake From 1a87a5c9fad7c96a45ee051eed4f962aa895d4af Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Feb 2019 13:34:24 -0800 Subject: [PATCH 014/133] add a little state to tests --- app/aqua.hoon | 3 ++ app/ph.hoon | 115 +++++++++++++++++++++++++++++++--------------- lib/ph.hoon | 2 +- sur/aquarium.hoon | 1 + 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index a4ee3f3a3..99bd626f6 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -585,6 +585,9 @@ %+ ~(put by init-cache) who.ovo (~(got by piers) who.ovo) (pe who.ovo) + :: + %pause-events + stop-processing-events:(pe who.ovo) :: %event (push-events:(pe who.ovo) [ovo.ovo]~) diff --git a/app/ph.hoon b/app/ph.hoon index c9515eb2c..1a7ef671a 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -14,15 +14,15 @@ => $~ |% ++ move (pair bone card) ++ card - $% [%peer wire dock path] - [%poke wire dock %aqua-events (list aqua-event)] + $% [%poke wire dock %aqua-events (list aqua-event)] + [%peer wire dock path] + [%pull wire dock ~] == :: - ++ test-map (map term test-core) - :: ++ state $: %0 - test-cores=test-map + raw-test-cores=(map term test-core) + test-cores=(map term [hers=(list ship) cor=test-core]) other-state == ++ other-state @@ -35,66 +35,80 @@ ++ this . ++ install-tests ^+ this - =. test-cores + =. raw-test-cores %- malt ^- (list (pair term test-core)) :~ - :- %test-add + :- %add + =+ num=5 |% ++ start - ^- (pair (list ship) (list ph-event)) - :- ~[~bud] - %- zing - :~ (init ~bud) - (dojo ~bud "[%test-result (add 2 3)]") - == + ^- (trel (list ship) (list ph-event) _..start) + =. num +(num) + :+ ~[~bud] + %- zing + :~ (init ~bud) + (dojo ~bud "[%test-result (add 2 3)]") + == + ..start :: ++ route |= [who=ship ovo=unix-effect] ^- (list ph-event) + ~& [%num num] (expect-dojo-output ~bud who ovo "[%test-result 5]") :: XX if it's been five minutes, we failed -- :: - :- %test-hi + :- %hi |% ++ start - ^- (pair (list ship) (list ph-event)) - :- ~[~bud ~dev] - %- zing - :~ (init ~bud) - (init ~dev) - (dojo ~bud "|hi ~dev") - == + ^- (trel (list ship) (list ph-event) _..start) + :+ ~[~bud ~dev] + %- zing + :~ (init ~bud) + (init ~dev) + (dojo ~bud "|hi ~dev") + == + ..start :: ++ route |= [who=ship ovo=unix-effect] ^- (list ph-event) - :: - :: doesn't work because for some reason we lose the - :: subscription immediately after opening it. maybe - :: because we receive so many events without immediate - :: reap it triggers the backpressure mechanism in gall? - :: (expect-dojo-output ~bud who ovo "hi ~dev successful") -- + :: + :- %individual-breach + *test-core + :: + :: (init ~zod) + :: (init ~marzod) + :: wait for sync to finish + :: cycle ~zod keys + :: verify it sunk + :: kill ~zod + :: (init ~zod) w/new keys + :: change file on ~zod + :: wait for sync to finish + :: verify file has changed + :: == this :: ++ prep |= old=(unit [@ tests=* rest=*]) - ^- [(list move) _this] + ^- (quip move _this) =. this install-tests ?~ old `this =/ new ((soft other-state) rest.u.old) ?~ new `this - `this(+<+>+ u.new) + `this(+<+>+> u.new) :: ++ run-events - |= what=(list ph-event) - ^- [(list move) _this] + |= [lab=term what=(list ph-event)] + ^- (quip move _this) ?: =(~ what) `this =/ res @@ -109,9 +123,33 @@ nex [%& `aqua-event`i.what p.nex] ?: ?=(%| -.res) - `this + (cancel-test lab) [[ost.hid %poke /running [our.hid %aqua] %aqua-events p.res]~ this] :: +:: Cancel subscriptions to ships +:: +++ cancel-test + |= lab=term + ^- (quip move _this) + =/ test (~(get by test-cores) lab) + ?~ test + `this + =. test-cores (~(del by test-cores) lab) + :_ this + %- zing + %+ turn hers.u.test + |= her=ship + ^- (list move) + :~ [ost.hid %pull /[lab]/(scot %p her) [our.hid %aqua] ~] + :* ost.hid + %poke + /cancelling + [our.hid %aqua] + %aqua-events + [%pause-events her]~ + == + == +:: :: Should check whether we're already subscribed :: ++ subscribe-to-effects @@ -133,10 +171,11 @@ ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) [%run-test lab=@tas] - =/ res=[hers=(list ship) events=(list ph-event)] - start:(~(got by test-cores) lab.arg) + =/ res=[hers=(list ship) events=(list ph-event) new-state=test-core] + start:(~(got by raw-test-cores) lab.arg) + =. test-cores (~(put by test-cores) lab.arg hers.res new-state.res) =^ moves-1 this (subscribe-to-effects lab.arg hers.res) - =^ moves-2 this (run-events events.res) + =^ moves-2 this (run-events lab.arg events.res) [(weld moves-1 moves-2) this] == :: @@ -144,14 +183,14 @@ |= [way=wire ova=aqua-effects] ^- (quip move _this) :: ~& [%diff-aqua-effect way who.ova] - ?> ?=([@ @ ~] way) + ?> ?=([@tas @ ~] way) =/ lab i.way - %- run-events + %+ run-events lab |- ^- (list ph-event) ?~ ovo.ova ~ ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] %+ weld - (route:(~(got by test-cores) lab) who.ova i.ovo.ova) + (route:cor:(~(got by test-cores) lab) who.ova i.ovo.ova) $(ovo.ova t.ovo.ova) -- diff --git a/lib/ph.hoon b/lib/ph.hoon index 5978fff34..e3d2fcc15 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -22,7 +22,7 @@ ++ test-core $_ ^? |% - ++ start *(pair (list ship) (list ph-event)) + ++ start *(trel (list ship) (list ph-event) _^?(..start)) ++ route |~([ship unix-effect] *(list ph-event)) -- :: diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index c265485fa..24a9a3fe5 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -1,6 +1,7 @@ |% ++ aqua-event $% [%init-ship who=ship] + [%pause-events who=ship] [%event who=ship ovo=unix-event] == :: From 64b11765b50a9e91ff8d5f0fb242aaa638c53380 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Feb 2019 15:21:40 -0800 Subject: [PATCH 015/133] WIP merge --- app/aqua.hoon | 17 ++++++++++------- app/ph.hoon | 31 +++++++++++++++++++++++++++++-- lib/ph.hoon | 10 ++++++++++ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 99bd626f6..8b35a6c02 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -35,8 +35,9 @@ piers=(map ship pier) == ++ pier - $: snap=* - event-log=(list unix-event) + $: tym=@da + snap=* + event-log=(list [@da unix-event]) next-events=(qeu unix-event) processing-events=? next-timer=(unit @da) @@ -96,8 +97,9 @@ =/ res (mox +47.snap) ?> ?=(%0 -.res) =/ poke p.res - =/ res (slum poke now.hid ovo) - =. event-log [ovo event-log] + =. tym (max +(tym) now.hid) + =/ res (slum poke tym ovo) + =. event-log [[tym ovo] event-log] =. snap +3.res =. ..abet-pe (handle-effects ((list ovum) -.res)) $ @@ -237,7 +239,7 @@ ?. &(=(0 (rsh 0 16 u.dest-ip)) =(1 (rsh 0 8 u.dest-ip))) ~& [%havent-implemented-direct-lanes who lan] ..abet-pe - ~& [who=who %blast-sending] + :: ~& [who=who %blast-sending] =/ hear [//newt/0v1n.2m9vh %hear lan pac] =. this (blast-event hear) :: =/ her ?:(=(~dev who) ~bud ~dev) ::ship (dis u.dest-ip 0xff) @@ -337,7 +339,7 @@ ++ handle-ergo |= [way=wire %ergo mount-point=@tas mod=mode:clay] ^+ ..abet-pe - ~& [who=who %file-changes (turn mod head)] + ~& [who=who %file-changes (lent mod)] :: (turn mod head)] ..abet-pe :: :: Give effect to our subscribers @@ -562,7 +564,7 @@ ?- -.ovo %init-ship =/ prev (~(get by init-cache) who.ovo) - ?^ prev + ?: &(?=(^ prev) !=(who.ovo ~marbud)) ~& [%loading-cached-ship who.ovo] =. this (restore-ships ~[who.ovo] init-cache) (pe who.ovo) @@ -590,6 +592,7 @@ stop-processing-events:(pe who.ovo) :: %event + ~& ev=-.q.ovo.ovo (push-events:(pe who.ovo) [ovo.ovo]~) == :: diff --git a/app/ph.hoon b/app/ph.hoon index 1a7ef671a..54e7a3043 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -77,6 +77,33 @@ ^- (list ph-event) (expect-dojo-output ~bud who ovo "hi ~dev successful") -- + :: + :- %child-sync + |% + ++ start + ^- (trel (list ship) (list ph-event) _..start) + :+ ~[~bud ~marbud] + %- zing + :~ (init ~bud) + :: (dojo ~bud "|mount %") + :: %+ insert-file ~bud + :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon + (init ~marbud) + :: (dojo ~marbud "|mount %") + :: %+ insert-file ~marbud + :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon + == + ..start + ++ route + |= [who=ship ovo=unix-effect] + ^- (list ph-event) + (expect-dojo-output ~marbud who ovo "hrm") + -- + :: (init ~zod) + :: (init ~marzod) + :: wait for initial sync + :: change file on zod + :: check on ~marzod :: :- %individual-breach *test-core @@ -90,7 +117,7 @@ :: (init ~zod) w/new keys :: change file on ~zod :: wait for sync to finish - :: verify file has changed + :: verify file has changed on ~marzod :: == this @@ -189,7 +216,7 @@ |- ^- (list ph-event) ?~ ovo.ova ~ - ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] + :: ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] %+ weld (route:cor:(~(got by test-cores) lab) who.ova i.ovo.ova) $(ovo.ova t.ovo.ova) diff --git a/lib/ph.hoon b/lib/ph.hoon index e3d2fcc15..6065eafa2 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -57,6 +57,16 @@ [//term/1 %belt %ret ~] == :: +++ insert-file + |= [who=ship pax=path] + ^- (list ph-event) + ?> ?=([@ @ @ *] pax) + =/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] + %+ send-events-to who + :~ + [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~] + == +:: ++ expect-dojo-output |= [who=ship her=ship ovo=unix-effect what=tape] ^- (list ph-event) From 0fc7ab112ebcbdc2d19cbe86a335ccf1554dc555 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Feb 2019 19:17:46 -0800 Subject: [PATCH 016/133] modify behn to not fire in the middle of another event and take one timer at a time --- sys/vane/behn.hoon | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sys/vane/behn.hoon b/sys/vane/behn.hoon index 30aa9cf35..2415a54bb 100644 --- a/sys/vane/behn.hoon +++ b/sys/vane/behn.hoon @@ -59,9 +59,6 @@ ++ wait |= date=@da ^+ [moves state] - :: process elapsed timers first to maintain sort order - :: - =. event-core notify-clients =. timers.state (set-timer [date duct]) set-wake :: +wake: unix says we should wake up; notify clients and set :next-wake @@ -92,7 +89,7 @@ :: ++ notify-clients =* timers timers.state - |- ^+ event-core + ^+ event-core :: ?~ timers =. moves (flop moves) @@ -102,10 +99,10 @@ =. moves (flop moves) event-core :: - %_ $ - timers t.timers - moves [[duct.i.timers %give %wake ~] moves] - == + =. moves [[duct.i.timers %give %wake ~] moves] + => .(timers t.timers) + =. moves (flop moves) + event-core :: +set-wake: set or unset a unix timer to wake us when next timer expires :: :: We prepend the unix %doze event so that it is handled first. Arvo must From da12f0467a32a59db27533395a3dfac785e4a486 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Feb 2019 19:18:38 -0800 Subject: [PATCH 017/133] WIP --- app/aqua.hoon | 45 +++++++++++++++++++++++++++------------------ app/ph.hoon | 15 +++++++++++++-- lib/hood/helm.hoon | 3 ++- lib/ph.hoon | 13 +++++++++++-- sys/vane/clay.hoon | 8 ++++++-- sys/vane/gall.hoon | 1 - 6 files changed, 59 insertions(+), 26 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 8b35a6c02..68f04463e 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -30,13 +30,13 @@ $: %0 pil=pill assembled=* + tym=@da init-cache=(map ship pier) fleet-snaps=(map term (map ship pier)) piers=(map ship pier) == ++ pier - $: tym=@da - snap=* + $: snap=* event-log=(list [@da unix-event]) next-events=(qeu unix-event) processing-events=? @@ -268,14 +268,17 @@ ++ set-timer |= tim=@da =. tim +(tim) :: nobody's perfect + ~& [who=who %setting-timer tim] =. next-timer `tim (emit-moves [ost.hid %wait /(scot %p who) tim]~) :: ++ cancel-timer + ~& [who=who %cancell-timer (need next-timer)] (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) :: ++ take-wake |= [way=wire ~] + ~& [who=who %wakey now.hid] =. next-timer ~ %- push-events:(pe who) [//behn/0v1n.2m9vh %wake ~]~ @@ -459,22 +462,27 @@ :: ?+ val ~|(%bad-noun-arg !!) [%init hers=*] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - ~& [%initting who] - %- push-events:apex:(pe who) - ^- (list unix-event) - :~ `unix-event`[/ %wack 0] :: eny - `unix-event`[/ %whom who] :: eny - `unix-event`[//newt/0v1n.2m9vh %barn ~] - `unix-event`[//behn/0v1n.2m9vh %born ~] - `unix-event`[//term/1 %boot %fake who] - `unix-event`-.userspace-ova.pil - `unix-event`[//http/0v1n.2m9vh %born ~] - `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] - `unix-event`[//term/1 %belt %ctl `@c`%x] - == + =/ hers ((list ship) hers.val) + ?~ hers + this + =^ ms this (poke-aqua-events [%init-ship i.hers]~) + (emit-moves ms) + :: %+ turn-ships ((list ship) hers.val) + :: |= [who=ship thus=_this] + :: =. this thus + :: ~& [%initting who] + :: %- push-events:apex:(pe who) + :: ^- (list unix-event) + :: :~ `unix-event`[/ %wack 0] :: eny + :: `unix-event`[/ %whom who] :: eny + :: `unix-event`[//newt/0v1n.2m9vh %barn ~] + :: `unix-event`[//behn/0v1n.2m9vh %born ~] + :: `unix-event`[//term/1 %boot %fake who] + :: `unix-event`-.userspace-ova.pil + :: `unix-event`[//http/0v1n.2m9vh %born ~] + :: `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] + :: `unix-event`[//term/1 %belt %ctl `@c`%x] + :: == :: [%dojo hers=* command=*] %+ turn-ships ((list ship) hers.val) @@ -568,6 +576,7 @@ ~& [%loading-cached-ship who.ovo] =. this (restore-ships ~[who.ovo] init-cache) (pe who.ovo) + =. this abet-pe:sleep:(pe who.ovo) =/ initted =< plow %- push-events:apex:(pe who.ovo) diff --git a/app/ph.hoon b/app/ph.hoon index 54e7a3043..16265b189 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -85,10 +85,11 @@ :+ ~[~bud ~marbud] %- zing :~ (init ~bud) + :: (dojo ~bud "\"magic-go\":[.^(") :: (dojo ~bud "|mount %") :: %+ insert-file ~bud :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon - (init ~marbud) + :: (init ~marbud) :: (dojo ~marbud "|mount %") :: %+ insert-file ~marbud :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon @@ -97,7 +98,17 @@ ++ route |= [who=ship ovo=unix-effect] ^- (list ph-event) - (expect-dojo-output ~marbud who ovo "hrm") + :: + :: This is actually super fragile. If we start ~marbud any + :: earlier in the process, we get a crash. The crash may be + :: harmless, not sure. + :: + %- on-dojo-output + :^ ~bud who ovo + :- "~zod not responding still trying" + ^- $-($~ (list ph-event)) + |= ~ + (init ~marbud) -- :: (init ~zod) :: (init ~marzod) diff --git a/lib/hood/helm.hoon b/lib/hood/helm.hoon index 462361511..f5b566fda 100644 --- a/lib/hood/helm.hoon +++ b/lib/hood/helm.hoon @@ -189,7 +189,8 @@ =/ top=path /(scot %p our)/home/(scot %da now)/sys =/ hun .^(@ %cx (welp top /hoon/hoon)) =/ arv .^(@ %cx (welp top /arvo/hoon)) - :- [%flog /reset [%lyra `@t`hun `@t`arv]] + :- `card`[%flog /reset [%lyra `@t`hun `@t`arv]] + ^- (list card) %+ turn (module-ova:pill top) |=(a=[wire flog:dill] [%flog a]) diff --git a/lib/ph.hoon b/lib/ph.hoon index 6065eafa2..0adc5855f 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -67,8 +67,8 @@ [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~] == :: -++ expect-dojo-output - |= [who=ship her=ship ovo=unix-effect what=tape] +++ on-dojo-output + |= [who=ship her=ship ovo=unix-effect what=tape fun=$-($~ (list ph-event))] ^- (list ph-event) ?. =(who her) ~ @@ -80,5 +80,14 @@ | !=(~ (find what p.blit)) ~ + (fun) +:: +++ expect-dojo-output + |= [who=ship her=ship ovo=unix-effect what=tape] + ^- (list ph-event) + %- on-dojo-output + :^ who her ovo + :- what + |= ~ [%test-done &]~ -- diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index 1297256b0..c6c2113ed 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -2397,8 +2397,8 @@ ^+ bar ?- -.mys $ins :: insert if not exist - ?: (~(has by bar) pax) !! :: - ?: (~(has by hat) pax) !! :: + ?: (~(has by bar) pax) ~|([%ins-bar pax] !!) :: + ?: (~(has by hat) pax) ~|([%ins-hat pax] !!) :: %+ ~(put by bar) pax %- make-direct-blob ?: &(?=($mime -.p.mys) =([%hoon ~] (slag (dec (lent pax)) pax))) @@ -4231,6 +4231,10 @@ :: $note [[hen %give +.q.hin]~ ..^$] $wake + :: dear reader, if it crashes here, check the wire. If it came + :: from ++bait, then I don't think we have any handling for that + :: sort of thing. + :: =^ queued cue.ruf ~(get to cue.ruf) :: =/ queued-duct=duct -.queued diff --git a/sys/vane/gall.hoon b/sys/vane/gall.hoon index 07e534bf3..5ec68757f 100644 --- a/sys/vane/gall.hoon +++ b/sys/vane/gall.hoon @@ -1258,7 +1258,6 @@ ^- (unit @tas) ?+ sep ~& [%ap-vain sep] ~ -<<<<<<< HEAD %build `%f %cash `%a %conf `%g From 17cea6a1c7d833568ec759980586f4283322f07e Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 11 Feb 2019 13:42:54 -0800 Subject: [PATCH 018/133] better child-sync test --- app/aqua.hoon | 2 +- app/ph.hoon | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 68f04463e..dc0b58cf9 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -572,7 +572,7 @@ ?- -.ovo %init-ship =/ prev (~(get by init-cache) who.ovo) - ?: &(?=(^ prev) !=(who.ovo ~marbud)) + ?: &(?=(^ prev) (lth who.ovo ~marzod)) ~& [%loading-cached-ship who.ovo] =. this (restore-ships ~[who.ovo] init-cache) (pe who.ovo) diff --git a/app/ph.hoon b/app/ph.hoon index 16265b189..4fcc9c1b3 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -82,7 +82,7 @@ |% ++ start ^- (trel (list ship) (list ph-event) _..start) - :+ ~[~bud ~marbud] + :+ ~[~bud ~marbud ~linnup-torsyx] %- zing :~ (init ~bud) :: (dojo ~bud "\"magic-go\":[.^(") @@ -98,17 +98,37 @@ ++ route |= [who=ship ovo=unix-effect] ^- (list ph-event) + %- zing + :~ + %- on-dojo-output + :^ ~bud who ovo + :- "+ /~bud/base/2/web/testing/udon" + ^- $-($~ (list ph-event)) + |= ~ + (init ~marbud) :: - :: This is actually super fragile. If we start ~marbud any - :: earlier in the process, we get a crash. The crash may be - :: harmless, not sure. + %- on-dojo-output + :^ ~marbud who ovo + :- "; ~bud is your neighbor" + ^- $-($~ (list ph-event)) + |= ~ + (init ~linnup-torsyx) :: - %- on-dojo-output - :^ ~bud who ovo - :- "~zod not responding still trying" - ^- $-($~ (list ph-event)) - |= ~ - (init ~marbud) + %- on-dojo-output + :^ ~linnup-torsyx who ovo + :- "; ~bud is your neighbor" + ^- $-($~ (list ph-event)) + |= ~ + (dojo ~linnup-torsyx "|hi ~bud") + :: + %- on-dojo-output + :^ ~linnup-torsyx who ovo + :- "hi ~bud successful" + :: :- "; ~bud is your neighbor" + ^- $-($~ (list ph-event)) + |= ~ + [%test-done &]~ + == -- :: (init ~zod) :: (init ~marzod) @@ -223,12 +243,16 @@ :: ~& [%diff-aqua-effect way who.ova] ?> ?=([@tas @ ~] way) =/ lab i.way + =/ test-cor (~(get by test-cores) lab) + ?~ test-cor + ~& [%ph-dropping lab] + `this %+ run-events lab |- ^- (list ph-event) ?~ ovo.ova ~ :: ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] %+ weld - (route:cor:(~(got by test-cores) lab) who.ova i.ovo.ova) + (route:cor.u.test-cor who.ova i.ovo.ova) $(ovo.ova t.ovo.ova) -- From 600dc02a2f045dfe34f5f880b3b7df9637e8b4a9 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 11 Feb 2019 15:25:25 -0800 Subject: [PATCH 019/133] basic ph test composition --- app/ph.hoon | 158 ++++++++++++++++++++++++++++++++-------------------- lib/ph.hoon | 83 ++++++++++++++++++++++++++- 2 files changed, 178 insertions(+), 63 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index 4fcc9c1b3..043a15538 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -1,4 +1,4 @@ -:: Test the pH of your aquarium. See if it's safe to put real fish in. +:: Test the pH of your aquarium. See if it's safe to put in real fish. :: :: usage: :: :aqua [%run-test %test-add] @@ -42,82 +42,64 @@ :- %add =+ num=5 |% + ++ ships ~[~bud] ++ start - ^- (trel (list ship) (list ph-event) _..start) + ^- (pair (list ph-event) _..start) =. num +(num) - :+ ~[~bud] - %- zing - :~ (init ~bud) - (dojo ~bud "[%test-result (add 2 3)]") - == - ..start + :_ ..start + %- zing + :~ (init ~bud) + (dojo ~bud "[%test-result (add 2 3)]") + == :: ++ route |= [who=ship ovo=unix-effect] - ^- (list ph-event) + ^- (quip ph-event _..start) ~& [%num num] + :_ ..start (expect-dojo-output ~bud who ovo "[%test-result 5]") :: XX if it's been five minutes, we failed -- :: :- %hi |% + ++ ships ~[~bud ~marbud] ++ start - ^- (trel (list ship) (list ph-event) _..start) - :+ ~[~bud ~dev] - %- zing - :~ (init ~bud) - (init ~dev) - (dojo ~bud "|hi ~dev") - == - ..start + ^- (pair (list ph-event) _..start) + :_ ..start + %- zing + :~ (init ~bud) + (init ~dev) + (dojo ~bud "|hi ~dev") + == :: ++ route |= [who=ship ovo=unix-effect] - ^- (list ph-event) + ^- (quip ph-event _..start) + :_ ..start (expect-dojo-output ~bud who ovo "hi ~dev successful") -- :: - :- %child-sync + [%headstart-marbud marbud:head-starts] + :: + :- %composed-child-sync + %+ compose-tests marbud:head-starts + ^- test-core |% + ++ ships ~[~bud ~marbud ~linnup-torsyx] ++ start - ^- (trel (list ship) (list ph-event) _..start) - :+ ~[~bud ~marbud ~linnup-torsyx] - %- zing - :~ (init ~bud) - :: (dojo ~bud "\"magic-go\":[.^(") - :: (dojo ~bud "|mount %") - :: %+ insert-file ~bud - :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon - :: (init ~marbud) - :: (dojo ~marbud "|mount %") - :: %+ insert-file ~marbud - :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon - == - ..start + :_ ..start + (init ~linnup-torsyx) + :: ++ route |= [who=ship ovo=unix-effect] - ^- (list ph-event) + ^- (quip ph-event _..start) + :_ ..start %- zing :~ - %- on-dojo-output - :^ ~bud who ovo - :- "+ /~bud/base/2/web/testing/udon" - ^- $-($~ (list ph-event)) - |= ~ - (init ~marbud) - :: - %- on-dojo-output - :^ ~marbud who ovo - :- "; ~bud is your neighbor" - ^- $-($~ (list ph-event)) - |= ~ - (init ~linnup-torsyx) - :: %- on-dojo-output :^ ~linnup-torsyx who ovo :- "; ~bud is your neighbor" - ^- $-($~ (list ph-event)) |= ~ (dojo ~linnup-torsyx "|hi ~bud") :: @@ -125,11 +107,62 @@ :^ ~linnup-torsyx who ovo :- "hi ~bud successful" :: :- "; ~bud is your neighbor" - ^- $-($~ (list ph-event)) |= ~ [%test-done &]~ == -- + :: + :- %child-sync + |% + ++ ships ~[~bud ~marbud ~linnup-torsyx] + ++ start + ^- (pair (list ph-event) _..start) + :_ ..start + %- zing + :~ (init ~bud) + == + :: + ++ route + |= [who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + :_ ..start + %- zing + :~ + %- on-dojo-output + :^ ~bud who ovo + :- "+ /~bud/base/2/web/testing/udon" + |= ~ + (init ~marbud) + :: + %- on-dojo-output + :^ ~marbud who ovo + :- "; ~bud is your neighbor" + |= ~ + (init ~linnup-torsyx) + :: + %- on-dojo-output + :^ ~linnup-torsyx who ovo + :- "; ~bud is your neighbor" + |= ~ + (dojo ~linnup-torsyx "|hi ~bud") + :: + %- on-dojo-output + :^ ~linnup-torsyx who ovo + :- "hi ~bud successful" + :: :- "; ~bud is your neighbor" + |= ~ + [%test-done &]~ + == + -- + :: (dojo ~bud "\"magic-go\":[.^(") + :: (dojo ~bud "|mount %") + :: %+ insert-file ~bud + :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon + :: (init ~marbud) + :: (dojo ~marbud "|mount %") + :: %+ insert-file ~marbud + :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon + :: :: (init ~zod) :: (init ~marzod) :: wait for initial sync @@ -229,10 +262,10 @@ ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) [%run-test lab=@tas] - =/ res=[hers=(list ship) events=(list ph-event) new-state=test-core] + =/ res=[events=(list ph-event) new-state=test-core] start:(~(got by raw-test-cores) lab.arg) - =. test-cores (~(put by test-cores) lab.arg hers.res new-state.res) - =^ moves-1 this (subscribe-to-effects lab.arg hers.res) + =. test-cores (~(put by test-cores) lab.arg [ships .]:new-state.res) + =^ moves-1 this (subscribe-to-effects lab.arg ships.new-state.res) =^ moves-2 this (run-events lab.arg events.res) [(weld moves-1 moves-2) this] == @@ -247,12 +280,15 @@ ?~ test-cor ~& [%ph-dropping lab] `this - %+ run-events lab - |- ^- (list ph-event) - ?~ ovo.ova - ~ - :: ~& [%diff-aqua-effect-i way -.q.i.ovo.ova] - %+ weld - (route:cor.u.test-cor who.ova i.ovo.ova) - $(ovo.ova t.ovo.ova) + =^ events u.test-cor + |- ^- (quip ph-event _u.test-cor) + ?~ ovo.ova + [~ u.test-cor] + =^ events-1 cor.u.test-cor + (route:cor.u.test-cor who.ova i.ovo.ova) + =^ events-2 u.test-cor + $(ovo.ova t.ovo.ova) + [(weld events-1 events-2) u.test-cor] + =. test-cores (~(put by test-cores) lab u.test-cor) + (run-events lab events) -- diff --git a/lib/ph.hoon b/lib/ph.hoon index 0adc5855f..725166d22 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -22,8 +22,9 @@ ++ test-core $_ ^? |% - ++ start *(trel (list ship) (list ph-event) _^?(..start)) - ++ route |~([ship unix-effect] *(list ph-event)) + ++ ships *(list ship) + ++ start *(quip ph-event _^?(..start)) + ++ route |~([ship unix-effect] *(quip ph-event _^?(..start))) -- :: ++ ph-event @@ -90,4 +91,82 @@ :- what |= ~ [%test-done &]~ +:: +++ compose-tests + |= [a=test-core b=test-core] + ^- test-core + =/ done-with-a | + |% + :: Union of ships in a and b + :: + ++ ships ~(tap in (~(uni in (silt ships.a)) (silt ships.b))) + :: + :: Start with start of a + :: + ++ start + ^- (quip ph-event _..start) + =^ events a start:a + [events ..start] + :: + :: Keep going on a until it's done. If success, go to b. + :: + :: In theory, we should be able to just swap out the whole core + :: for b, but in practice the types are hard, and we generally + :: try to avoid changing the structure of a core in the middle + :: like that. + :: + ++ route + |= [who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + ?: done-with-a + =^ events b (route:b who ovo) + [events ..start] + =^ events a (route:a who ovo) + =+ ^- [done=(list ph-event) other-events=(list ph-event)] + %+ skid events + |= e=ph-event + =(%test-done -.e) + ?~ done + [other-events ..start] + ?> ?=(%test-done -.i.done) + ?. p.i.done + [[%test-done |]~ ..start] + =. done-with-a & + =^ events-start b start:b + [(weld other-events events-start) ..start] + -- +:: +++ head-starts + |% + ++ marbud + ^- test-core + |% + ++ ships ~[~bud ~marbud] + ++ start + ^- (quip ph-event _..start) + :_ ..start + %- zing + :~ (init ~bud) + == + :: + ++ route + |= [who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + :_ ..start + %- zing + :~ + %- on-dojo-output + :^ ~bud who ovo + :- "+ /~bud/base/2/web/testing/udon" + |= ~ + (init ~marbud) + :: + %- on-dojo-output + :^ ~marbud who ovo + :- "; ~bud is your neighbor" + |= ~ + [%test-done &]~ + == + -- + -- -- From 11adf30c72d06d62262dcd0c7a56098c1fe9e270 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 11 Feb 2019 15:53:23 -0800 Subject: [PATCH 020/133] more modular test headstarts --- app/ph.hoon | 33 +++++++++++-------------------- lib/ph.hoon | 56 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index 043a15538..dbe517b84 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -63,7 +63,7 @@ :: :- %hi |% - ++ ships ~[~bud ~marbud] + ++ ships ~[~bud ~dev] ++ start ^- (pair (list ph-event) _..start) :_ ..start @@ -80,36 +80,25 @@ (expect-dojo-output ~bud who ovo "hi ~dev successful") -- :: - [%headstart-marbud marbud:head-starts] + [%headstart-bud (galaxy:head-starts ~bud)] :: - :- %composed-child-sync - %+ compose-tests marbud:head-starts + :- %composed-child-boot + %+ compose-tests (planet:head-starts ~linnup-torsyx) ^- test-core |% - ++ ships ~[~bud ~marbud ~linnup-torsyx] + ++ ships ~ ++ start - :_ ..start - (init ~linnup-torsyx) + [(dojo ~linnup-torsyx "|hi ~bud") ..start] :: ++ route |= [who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start - %- zing - :~ - %- on-dojo-output - :^ ~linnup-torsyx who ovo - :- "; ~bud is your neighbor" - |= ~ - (dojo ~linnup-torsyx "|hi ~bud") - :: - %- on-dojo-output - :^ ~linnup-torsyx who ovo - :- "hi ~bud successful" - :: :- "; ~bud is your neighbor" - |= ~ - [%test-done &]~ - == + %- on-dojo-output + :^ ~linnup-torsyx who ovo + :- "hi ~bud successful" + |= ~ + [%test-done &]~ -- :: :- %child-sync diff --git a/lib/ph.hoon b/lib/ph.hoon index 725166d22..7d47c1650 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -138,35 +138,67 @@ :: ++ head-starts |% - ++ marbud + :: Don't use directly, or else you might not have a parent. + :: + :: Consider ++galaxy, ++star, ++planet, and ++ship-with-ancestors. + :: + ++ raw-ship + |= her=ship ^- test-core |% - ++ ships ~[~bud ~marbud] + ++ ships ~[her] ++ start ^- (quip ph-event _..start) - :_ ..start - %- zing - :~ (init ~bud) - == + [(init her) ..start] :: ++ route |= [who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start %- zing + :: This is a pretty bad heuristic, but in general galaxies will + :: hit the first of these cases, and other ships will hit the + :: second. + :: :~ %- on-dojo-output - :^ ~bud who ovo - :- "+ /~bud/base/2/web/testing/udon" + :^ her who ovo + :- "+ /{(scow %p her)}/base/2/web/testing/udon" |= ~ - (init ~marbud) + [%test-done &]~ :: %- on-dojo-output - :^ ~marbud who ovo - :- "; ~bud is your neighbor" + :^ her who ovo + :- "is your neighbor" |= ~ [%test-done &]~ == -- - -- + ++ galaxy + |= her=ship + ?> =(%czar (clan:title her)) + (raw-ship her) + :: + ++ star + |= her=ship + ?> =(%king (clan:title her)) + %+ compose-tests (galaxy (^sein:title her)) + (raw-ship her) + :: + ++ planet + |= her=ship + ?> =(%duke (clan:title her)) + %+ compose-tests (star (^sein:title her)) + (raw-ship her) + :: + ++ ship-with-ancestors + |= her=ship + %. her + ?- (clan:title her) + %czar galaxy + %king star + %duke planet + %earl ~|(%moon-not-implemented !!) + %pawn ~|(%comet-not-implemented !!) + == -- From 3336699660297e010fa5087193745b14acb1d565 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Mon, 11 Feb 2019 18:46:36 -0800 Subject: [PATCH 021/133] most of proper cache restoration --- app/aqua.hoon | 53 +++++++++++++++----- app/ph.hoon | 56 ++++++++++++++++----- lib/ph.hoon | 121 ++++++++++++++++++++++++++++------------------ sur/aquarium.hoon | 2 + 4 files changed, 160 insertions(+), 72 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index dc0b58cf9..ce9f29f4c 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -546,18 +546,8 @@ this :: [%restore-fleet lab=@tas] - =. this - %+ turn-ships (turn ~(tap by piers) head) - |= [who=ship thus=_this] - =. this thus - sleep:(pe who) - =. piers (~(got by fleet-snaps) lab.val) - =. this - %+ turn-ships (turn ~(tap by piers) head) - |= [who=ship thus=_this] - =. this thus - restore:(pe who) - this + =^ ms this (poke-aqua-events [%restore-snap lab.val]~) + (emit-moves ms) == :: :: Apply a list of events tagged by ship @@ -599,6 +589,33 @@ :: %pause-events stop-processing-events:(pe who.ovo) + :: + %snap-ships + =. fleet-snaps + %+ ~(put by fleet-snaps) lab.ovo + %- malt + %+ murn hers.ovo + |= her=ship + ^- (unit (pair ship pier)) + =+ per=(~(get by piers) her) + ?~ per + ~ + `[her u.per] + (pe -.hers.ovo) + :: + %restore-snap + =. this + %+ turn-ships (turn ~(tap by piers) head) + |= [who=ship thus=_this] + =. this thus + sleep:(pe who) + =. piers (~(got by fleet-snaps) lab.ovo) + =. this + %+ turn-ships (turn ~(tap by piers) head) + |= [who=ship thus=_this] + =. this thus + restore:(pe who) + (pe ~bud) :: XX why ~bud? need an example :: %event ~& ev=-.q.ovo.ovo @@ -711,6 +728,17 @@ =. this thus (take-sigh-tang:(pe who) t.way tan) :: +:: Handle scry to aqua +:: +++ peek-x-fleet-snap + |= pax=path + ^- (unit (unit [%noun noun])) + ~& [%peeking pax] + ?. ?=([@ ~] pax) + ~ + :^ ~ ~ %noun + (~(has by fleet-snaps) i.pax) +:: :: Trivial scry for mock :: ++ scry |=([* *] ~) @@ -720,6 +748,7 @@ ++ prep |= old/(unit noun) ^- [(list move) _+>.$] + ~& prep=%aqua ?~ old `+>.$ =+ new=((soft state) u.old) diff --git a/app/ph.hoon b/app/ph.hoon index dbe517b84..f2f94e4f9 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -33,17 +33,22 @@ state == ++ this . +++ test-lib ~(. ^test-lib our.hid) ++ install-tests ^+ this =. raw-test-cores + ~& jael=.^(noun %j /(scot %p our.hid)/code/(scot %da now.hid)/(scot %p our.hid)) + =, test-lib %- malt ^- (list (pair term test-core)) :~ :- %add =+ num=5 - |% + |_ [our=@p now=@da] + ++ label %add ++ ships ~[~bud] ++ start + |= now=@da ^- (pair (list ph-event) _..start) =. num +(num) :_ ..start @@ -53,7 +58,7 @@ == :: ++ route - |= [who=ship ovo=unix-effect] + |= [now=@da who=ship ovo=unix-effect] ^- (quip ph-event _..start) ~& [%num num] :_ ..start @@ -62,9 +67,11 @@ -- :: :- %hi - |% + |_ [our=@p now=@da] + ++ label %hi ++ ships ~[~bud ~dev] ++ start + |= now=@da ^- (pair (list ph-event) _..start) :_ ..start %- zing @@ -74,24 +81,26 @@ == :: ++ route - |= [who=ship ovo=unix-effect] + |= [now=@da who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start (expect-dojo-output ~bud who ovo "hi ~dev successful") -- :: - [%headstart-bud (galaxy:head-starts ~bud)] + [%headstart-bud (galaxy ~bud)] :: :- %composed-child-boot - %+ compose-tests (planet:head-starts ~linnup-torsyx) + %+ compose-tests (planet ~linnup-torsyx) ^- test-core - |% + |_ [our=@p now=@da] + ++ label %composed-child-boot ++ ships ~ ++ start + |= now=@da [(dojo ~linnup-torsyx "|hi ~bud") ..start] :: ++ route - |= [who=ship ovo=unix-effect] + |= [now=@da who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start %- on-dojo-output @@ -100,11 +109,34 @@ |= ~ [%test-done &]~ -- + :: + :- %composed-child-boot-2 + %+ compose-tests (planet ~haplun-todtus) + ^- test-core + |_ [our=@p now=@da] + ++ label %composed-child-boot-2 + ++ ships ~ + ++ start + |= now=@da + [(dojo ~haplun-todtus "|hi ~bud") ..start] + :: + ++ route + |= [now=@da who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + :_ ..start + %- on-dojo-output + :^ ~haplun-todtus who ovo + :- "hi ~bud successful" + |= ~ + [%test-done &]~ + -- :: :- %child-sync - |% + |_ [our=@p now=@da] + ++ label %child-sync ++ ships ~[~bud ~marbud ~linnup-torsyx] ++ start + |= now=@da ^- (pair (list ph-event) _..start) :_ ..start %- zing @@ -112,7 +144,7 @@ == :: ++ route - |= [who=ship ovo=unix-effect] + |= [now=@da who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start %- zing @@ -252,7 +284,7 @@ ?+ arg ~|(%bad-noun-arg !!) [%run-test lab=@tas] =/ res=[events=(list ph-event) new-state=test-core] - start:(~(got by raw-test-cores) lab.arg) + (start:(~(got by raw-test-cores) lab.arg) now.hid) =. test-cores (~(put by test-cores) lab.arg [ships .]:new-state.res) =^ moves-1 this (subscribe-to-effects lab.arg ships.new-state.res) =^ moves-2 this (run-events lab.arg events.res) @@ -274,7 +306,7 @@ ?~ ovo.ova [~ u.test-cor] =^ events-1 cor.u.test-cor - (route:cor.u.test-cor who.ova i.ovo.ova) + (route:cor.u.test-cor now.hid who.ova i.ovo.ova) =^ events-2 u.test-cor $(ovo.ova t.ovo.ova) [(weld events-1 events-2) u.test-cor] diff --git a/lib/ph.hoon b/lib/ph.hoon index 7d47c1650..3a15b80d7 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -22,9 +22,10 @@ ++ test-core $_ ^? |% + ++ label *term ++ ships *(list ship) - ++ start *(quip ph-event _^?(..start)) - ++ route |~([ship unix-effect] *(quip ph-event _^?(..start))) + ++ start |~(@da *(quip ph-event _^?(..start))) + ++ route |~([@da [ship unix-effect]] *(quip ph-event _^?(..start))) -- :: ++ ph-event @@ -92,52 +93,73 @@ |= ~ [%test-done &]~ :: -++ compose-tests - |= [a=test-core b=test-core] - ^- test-core - =/ done-with-a | - |% - :: Union of ships in a and b - :: - ++ ships ~(tap in (~(uni in (silt ships.a)) (silt ships.b))) - :: - :: Start with start of a - :: - ++ start - ^- (quip ph-event _..start) - =^ events a start:a - [events ..start] - :: - :: Keep going on a until it's done. If success, go to b. - :: - :: In theory, we should be able to just swap out the whole core - :: for b, but in practice the types are hard, and we generally - :: try to avoid changing the structure of a core in the middle - :: like that. - :: - ++ route - |= [who=ship ovo=unix-effect] - ^- (quip ph-event _..start) - ?: done-with-a - =^ events b (route:b who ovo) +++ test-lib + |_ our=ship + ++ compose-tests + |= [a=test-core b=test-core] + ^- test-core + =/ done-with-a | + |% + :: + :: Cache lookup label + :: + ++ label :((cury cat 3) label:a '--1-' label:b) + :: + :: Union of ships in a and b + :: + ++ ships ~(tap in (~(uni in (silt ships.a)) (silt ships.b))) + :: + :: Start with start of a + :: + ++ start + |= now=@da + ^- (quip ph-event _..start) + =/ have-cache + .^ @f + %gx + (scot %p our) + %aqua + (scot %da now) + /fleet-snap/[label:a]/noun + == + ~& [%have-cache label:a have-cache] + ?: have-cache + =. done-with-a & + =/ restore-event [%restore-snap label:a] + =^ events-start b (start:b now) + [[restore-event events-start] ..start] + =^ events a (start:a now) [events ..start] - =^ events a (route:a who ovo) - =+ ^- [done=(list ph-event) other-events=(list ph-event)] - %+ skid events - |= e=ph-event - =(%test-done -.e) - ?~ done - [other-events ..start] - ?> ?=(%test-done -.i.done) - ?. p.i.done - [[%test-done |]~ ..start] - =. done-with-a & - =^ events-start b start:b - [(weld other-events events-start) ..start] - -- -:: -++ head-starts - |% + :: + :: Keep going on a until it's done. If success, go to b. + :: + :: In theory, we should be able to just swap out the whole core + :: for b, but in practice the types are hard, and we generally + :: try to avoid changing the structure of a core in the middle + :: like that. + :: + ++ route + |= [now=@da who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + ?: done-with-a + =^ events b (route:b now who ovo) + [events ..start] + =^ events a (route:a now who ovo) + =+ ^- [done=(list ph-event) other-events=(list ph-event)] + %+ skid events + |= e=ph-event + =(%test-done -.e) + ?~ done + [other-events ..start] + ?> ?=(%test-done -.i.done) + ?. p.i.done + [[%test-done |]~ ..start] + =. done-with-a & + =/ snap-event [%snap-ships label:a ships:a] + =^ events-start b (start:b now) + [(welp other-events [snap-event events-start]) ..start] + -- + :: :: Don't use directly, or else you might not have a parent. :: :: Consider ++galaxy, ++star, ++planet, and ++ship-with-ancestors. @@ -146,13 +168,15 @@ |= her=ship ^- test-core |% + ++ label (cat 3 'iinit-' (scot %p her)) ++ ships ~[her] ++ start + |= now=@da ^- (quip ph-event _..start) [(init her) ..start] :: ++ route - |= [who=ship ovo=unix-effect] + |= [now=@da who=ship ovo=unix-effect] ^- (quip ph-event _..start) :_ ..start %- zing @@ -201,4 +225,5 @@ %earl ~|(%moon-not-implemented !!) %pawn ~|(%comet-not-implemented !!) == + -- -- diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index 24a9a3fe5..1adaec11e 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -2,6 +2,8 @@ ++ aqua-event $% [%init-ship who=ship] [%pause-events who=ship] + [%snap-ships lab=term hers=(list ship)] + [%restore-snap lab=term] [%event who=ship ovo=unix-event] == :: From 42d5c9004c412e1d8d146c4e4f1c5548b3de5ff2 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Tue, 12 Feb 2019 11:26:48 -0800 Subject: [PATCH 022/133] small fixes and docs --- app/aqua.hoon | 2 +- app/ph.hoon | 4 +++- lib/ph.hoon | 37 ++++++++++++++++++++----------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index ce9f29f4c..a39fd714f 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -609,7 +609,7 @@ |= [who=ship thus=_this] =. this thus sleep:(pe who) - =. piers (~(got by fleet-snaps) lab.ovo) + =. piers (~(uni by piers) (~(got by fleet-snaps) lab.ovo)) =. this %+ turn-ships (turn ~(tap by piers) head) |= [who=ship thus=_this] diff --git a/app/ph.hoon b/app/ph.hoon index f2f94e4f9..b9142f413 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -111,7 +111,9 @@ -- :: :- %composed-child-boot-2 - %+ compose-tests (planet ~haplun-todtus) + %+ compose-tests + %+ compose-tests (planet ~mitnep-todsut) + (planet ~haplun-todtus) ^- test-core |_ [our=@p now=@da] ++ label %composed-child-boot-2 diff --git a/lib/ph.hoon b/lib/ph.hoon index 3a15b80d7..477cfa7b2 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -6,26 +6,28 @@ |% :: Defines a complete integration test. :: -:: Perhaps route should take a unix-effect rather than a sign. -:: Similarly, perhaps ++abet should produce a list of -:: unix-events. Also, perhaps we should support state. -:: -:: Perhaps closer to this: -:: ++ test-core -:: $_ ^? -:: |% -:: ++ start ^?(..abet) -:: ++ route |~([wire unix-effect] ^?(..abet)) -:: ++ abet *(list unix-event) -:: -- -:: ++ test-core $_ ^? |% + :: + :: Unique name, used as a cache label. + :: ++ label *term + :: + :: List of ships that are part of the test. + :: + :: We'll only hear effects from these ships, and only these will + :: be in the cache points. + :: ++ ships *(list ship) - ++ start |~(@da *(quip ph-event _^?(..start))) - ++ route |~([@da [ship unix-effect]] *(quip ph-event _^?(..start))) + :: + :: Called first to kick off the test. + :: + ++ start |~(now=@da *(quip ph-event _^?(..start))) + :: + :: Called on every effect from a ship. + :: + ++ route |~([now=@da ship unix-effect] *(quip ph-event _^?(..start))) -- :: ++ ph-event @@ -103,7 +105,7 @@ :: :: Cache lookup label :: - ++ label :((cury cat 3) label:a '--1-' label:b) + ++ label :((cury cat 3) label:a '--' label:b) :: :: Union of ships in a and b :: @@ -168,7 +170,7 @@ |= her=ship ^- test-core |% - ++ label (cat 3 'iinit-' (scot %p her)) + ++ label (cat 3 'init-' (scot %p her)) ++ ships ~[her] ++ start |= now=@da @@ -198,6 +200,7 @@ [%test-done &]~ == -- + :: ++ galaxy |= her=ship ?> =(%czar (clan:title her)) From 6337c9162bbcec507019622d3afd1d244a992b7f Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Tue, 12 Feb 2019 16:11:19 -0800 Subject: [PATCH 023/133] no barcabs anymore --- app/ph.hoon | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index b9142f413..9b512cee7 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -44,7 +44,7 @@ :~ :- %add =+ num=5 - |_ [our=@p now=@da] + |% ++ label %add ++ ships ~[~bud] ++ start @@ -67,7 +67,7 @@ -- :: :- %hi - |_ [our=@p now=@da] + |% ++ label %hi ++ ships ~[~bud ~dev] ++ start @@ -92,7 +92,7 @@ :- %composed-child-boot %+ compose-tests (planet ~linnup-torsyx) ^- test-core - |_ [our=@p now=@da] + |% ++ label %composed-child-boot ++ ships ~ ++ start @@ -115,7 +115,7 @@ %+ compose-tests (planet ~mitnep-todsut) (planet ~haplun-todtus) ^- test-core - |_ [our=@p now=@da] + |% ++ label %composed-child-boot-2 ++ ships ~ ++ start @@ -134,7 +134,7 @@ -- :: :- %child-sync - |_ [our=@p now=@da] + |% ++ label %child-sync ++ ships ~[~bud ~marbud ~linnup-torsyx] ++ start From 7f8e3daaaf64bfca42b51443b6f4cace23f6efce Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 14 Feb 2019 17:18:04 -0800 Subject: [PATCH 024/133] add test for changing a file --- app/aqua.hoon | 27 +++++++++++++++++++--- app/ph.hoon | 63 ++++++++++++++++----------------------------------- lib/ph.hoon | 30 ++++++++++++++++-------- 3 files changed, 65 insertions(+), 55 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index a39fd714f..b9e75e231 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -111,8 +111,13 @@ =/ res (mox +46.snap) ?> ?=(%0 -.res) =/ peek p.res - ~& [who=who %peeked (slum peek [now.hid p])] - ..abet-pe + =/ pax (path p) + ~& [who=who %peeking-in tym pax] + ?> ?=([@ @ @ @ *] pax) + =. i.t.t.t.pax (scot %da tym) + =/ pek (slum peek [tym pax]) + ~& [who=who %peeked] + pek :: :: Wish :: @@ -521,7 +526,8 @@ %+ turn-ships ((list ship) hers.val) |= [who=ship thus=_this] =. this thus - (peek:(pe who) p.val) + ~& [who=who %peek-result (peek:(pe who) p.val)] + (pe who) :: [%wish hers=* p=@t] %+ turn-ships ((list ship) hers.val) @@ -739,6 +745,21 @@ :^ ~ ~ %noun (~(has by fleet-snaps) i.pax) :: +:: +:: +++ peek-x-i + |= pax=path + ^- (unit (unit [%noun noun])) + ~& [%peeking-i pax] + ?. ?=([@ @ @ *] pax) + ~ + =/ who (slav %p i.pax) + =/ pier (~(get by piers) who) + ?~ pier + ~ + :^ ~ ~ %noun + (peek:(pe who) [%cx pax]) +:: :: Trivial scry for mock :: ++ scry |=([* *] ~) diff --git a/app/ph.hoon b/app/ph.hoon index 9b512cee7..2ad41a615 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -133,16 +133,23 @@ [%test-done &]~ -- :: - :- %child-sync + :- %change-file + %+ compose-tests (galaxy ~bud) + ^- test-core + =| warped=@t |% - ++ label %child-sync - ++ ships ~[~bud ~marbud ~linnup-torsyx] + ++ label %change-file + ++ ships ~ ++ start |= now=@da ^- (pair (list ph-event) _..start) + =/ pax + /(scot %p our.hid)/home/(scot %da now.hid)/sur/aquarium/hoon + =. warped (cat 3 '=> . ' .^(@t %cx pax)) :_ ..start %- zing - :~ (init ~bud) + :~ (dojo ~bud "|mount %") + (insert-file ~bud pax warped) == :: ++ route @@ -150,47 +157,17 @@ ^- (quip ph-event _..start) :_ ..start %- zing - :~ - %- on-dojo-output - :^ ~bud who ovo - :- "+ /~bud/base/2/web/testing/udon" - |= ~ - (init ~marbud) - :: - %- on-dojo-output - :^ ~marbud who ovo - :- "; ~bud is your neighbor" - |= ~ - (init ~linnup-torsyx) - :: - %- on-dojo-output - :^ ~linnup-torsyx who ovo - :- "; ~bud is your neighbor" - |= ~ - (dojo ~linnup-torsyx "|hi ~bud") - :: - %- on-dojo-output - :^ ~linnup-torsyx who ovo - :- "hi ~bud successful" - :: :- "; ~bud is your neighbor" - |= ~ - [%test-done &]~ + :~ %- on-ergo + :^ ~bud who ovo + |= $~ + =/ pax /i/~bud/home/(scot %da now)/sur/aquarium/hoon/noun + ~& [%compare (met 3 warped) (met 3 (need (scry-aqua (unit @) now pax)))] + ?: =(warped (need (scry-aqua (unit @) now pax))) + [%test-done &]~ + ~& %not-done-yet + ~ == -- - :: (dojo ~bud "\"magic-go\":[.^(") - :: (dojo ~bud "|mount %") - :: %+ insert-file ~bud - :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon - :: (init ~marbud) - :: (dojo ~marbud "|mount %") - :: %+ insert-file ~marbud - :: /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/clay/hoon - :: - :: (init ~zod) - :: (init ~marzod) - :: wait for initial sync - :: change file on zod - :: check on ~marzod :: :- %individual-breach *test-core diff --git a/lib/ph.hoon b/lib/ph.hoon index 477cfa7b2..67f88a6d4 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -62,10 +62,10 @@ == :: ++ insert-file - |= [who=ship pax=path] + |= [who=ship pax=path txt=@t] ^- (list ph-event) ?> ?=([@ @ @ *] pax) - =/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] + =/ file [/text/plain (as-octs:mimes:html txt)] %+ send-events-to who :~ [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~] @@ -95,6 +95,14 @@ |= ~ [%test-done &]~ :: +++ on-ergo + |= [who=ship her=ship ovo=unix-effect fun=$-($~ (list ph-event))] + ?. =(who her) + ~ + ?. ?=(%ergo -.q.ovo) + ~ + (fun) +:: ++ test-lib |_ our=ship ++ compose-tests @@ -117,13 +125,7 @@ |= now=@da ^- (quip ph-event _..start) =/ have-cache - .^ @f - %gx - (scot %p our) - %aqua - (scot %da now) - /fleet-snap/[label:a]/noun - == + (scry-aqua ? now /fleet-snap/[label:a]/noun) ~& [%have-cache label:a have-cache] ?: have-cache =. done-with-a & @@ -228,5 +230,15 @@ %earl ~|(%moon-not-implemented !!) %pawn ~|(%comet-not-implemented !!) == + :: + ++ scry-aqua + |* [a=mold now=@da pax=path] + .^ a + %gx + (scot %p our) + %aqua + (scot %da now) + pax + == -- -- From c3faca01aaee293c7eec41c560db53dbbbec5189 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 14 Feb 2019 17:36:30 -0800 Subject: [PATCH 025/133] factor out ++touch-file --- app/ph.hoon | 34 +--------------------------------- lib/ph.hoon | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index 2ad41a615..13a8586b8 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -135,39 +135,7 @@ :: :- %change-file %+ compose-tests (galaxy ~bud) - ^- test-core - =| warped=@t - |% - ++ label %change-file - ++ ships ~ - ++ start - |= now=@da - ^- (pair (list ph-event) _..start) - =/ pax - /(scot %p our.hid)/home/(scot %da now.hid)/sur/aquarium/hoon - =. warped (cat 3 '=> . ' .^(@t %cx pax)) - :_ ..start - %- zing - :~ (dojo ~bud "|mount %") - (insert-file ~bud pax warped) - == - :: - ++ route - |= [now=@da who=ship ovo=unix-effect] - ^- (quip ph-event _..start) - :_ ..start - %- zing - :~ %- on-ergo - :^ ~bud who ovo - |= $~ - =/ pax /i/~bud/home/(scot %da now)/sur/aquarium/hoon/noun - ~& [%compare (met 3 warped) (met 3 (need (scry-aqua (unit @) now pax)))] - ?: =(warped (need (scry-aqua (unit @) now pax))) - [%test-done &]~ - ~& %not-done-yet - ~ - == - -- + (touch-file ~bud) :: :- %individual-breach *test-core diff --git a/lib/ph.hoon b/lib/ph.hoon index 67f88a6d4..edf45ba65 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -231,6 +231,45 @@ %pawn ~|(%comet-not-implemented !!) == :: + :: Touches /sur/aquarium/hoon on the given ship. + :: + :: You must have started the ship or this will fail. + :: + ++ touch-file + |= her=ship + ^- test-core + =| warped=@t + |% + ++ label %touch-file + ++ ships ~ + ++ start + |= now=@da + ^- (pair (list ph-event) _..start) + =/ pax + /(scot %p our)/home/(scot %da now)/sur/aquarium/hoon + =. warped (cat 3 '=> . ' .^(@t %cx pax)) + :_ ..start + %- zing + :~ (dojo her "|mount %") + (insert-file her pax warped) + == + :: + ++ route + |= [now=@da who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + :_ ..start + %- zing + :~ %- on-ergo + :^ her who ovo + |= $~ + =/ pax /i/[(scot %p her)]/home/(scot %da now)/sur/aquarium/hoon/noun + ?: =(warped (need (scry-aqua (unit @) now pax))) + [%test-done &]~ + ~& %not-done-yet + ~ + == + -- + :: ++ scry-aqua |* [a=mold now=@da pax=path] .^ a From c4f3614f7b3b5118c57bc99b26bea813dfbfa508 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Sat, 16 Feb 2019 01:24:37 -0800 Subject: [PATCH 026/133] various fixes, add ++check-file-touched --- app/aqua.hoon | 11 +++++++++- app/ph.hoon | 7 +++++++ lib/ph.hoon | 52 ++++++++++++++++++++++++++++++++++++++++------ sys/vane/clay.hoon | 7 +++++-- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index b9e75e231..5fe6b6f37 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -4,6 +4,10 @@ :: |start %aqua :: /- aquarium :: :aqua &pill .^(pill:aquarium %cx %/urbit/pill) +:: OR +:: :aqua &pill +solid +:: +:: Then try stuff: :: :aqua [%init ~[~bud ~dev]] :: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] :: :aqua [%dojo ~[~bud] "|hi ~dev"] @@ -495,7 +499,7 @@ =. this thus %- push-events:(pe who) ^- (list unix-event) - :~ + :~ [//term/1 %belt %ctl `@c`%e] [//term/1 %belt %ctl `@c`%u] [//term/1 %belt %txt ((list @c) (tape command.val))] @@ -554,6 +558,11 @@ [%restore-fleet lab=@tas] =^ ms this (poke-aqua-events [%restore-snap lab.val]~) (emit-moves ms) + :: + [%clear-snap lab=@tas] + =. fleet-snaps ~ :: (~(del by fleet-snaps) lab.val) + =. init-cache ~ + this == :: :: Apply a list of events tagged by ship diff --git a/app/ph.hoon b/app/ph.hoon index 13a8586b8..ef94d4562 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -136,6 +136,13 @@ :- %change-file %+ compose-tests (galaxy ~bud) (touch-file ~bud) + :: + :- %child-sync + %+ compose-tests + %+ compose-tests + (star ~marbud) + (touch-file ~bud) + (check-file-touched ~marbud) :: :- %individual-breach *test-core diff --git a/lib/ph.hoon b/lib/ph.hoon index edf45ba65..fddc4e768 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -79,7 +79,7 @@ ?. ?=(%blit -.q.ovo) ~ ?. %+ lien p.q.ovo - |= =blit:dill + |= =blit:dill ?. ?=(%lin -.blit) | !=(~ (find what p.blit)) @@ -113,7 +113,7 @@ :: :: Cache lookup label :: - ++ label :((cury cat 3) label:a '--' label:b) + ++ label `@tas`:((cury cat 3) label:a '--' label:b) :: :: Union of ships in a and b :: @@ -124,10 +124,10 @@ ++ start |= now=@da ^- (quip ph-event _..start) - =/ have-cache + =/ have-cache (scry-aqua ? now /fleet-snap/[label:a]/noun) - ~& [%have-cache label:a have-cache] ?: have-cache + ~& [%caching-in label:a label] =. done-with-a & =/ restore-event [%restore-snap label:a] =^ events-start b (start:b now) @@ -156,6 +156,7 @@ ?~ done [other-events ..start] ?> ?=(%test-done -.i.done) + ~& [%transitioning label] ?. p.i.done [[%test-done |]~ ..start] =. done-with-a & @@ -233,14 +234,14 @@ :: :: Touches /sur/aquarium/hoon on the given ship. :: - :: You must have started the ship or this will fail. + :: Ship must have been started. :: ++ touch-file |= her=ship ^- test-core =| warped=@t |% - ++ label %touch-file + ++ label (cat 3 'touch-file-' (scot %p her)) ++ ships ~ ++ start |= now=@da @@ -270,6 +271,45 @@ == -- :: + :: Checks that /sur/aquarium/hoon has been touched, as by ++touch-file + :: + :: Ship must have been started. + :: + ++ check-file-touched + |= her=ship + ^- test-core + |% + ++ label (cat 3 'check-file-touched-' (scot %p her)) + ++ ships ~ + ++ start + |= now=@da + :: mounting is not strictly necessary since we check via scry, + :: but this way we don't have to check on every event, just + :: ergos (and dojo because we can't guarantee an ergo if the desk + :: is already mounted) + :: + ~& %mounting + [(dojo her "|mount %") ..start] + :: + ++ route + |= [now=@da who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + =/ cb + |= $~ + ~& %cbing + =/ pax /home/(scot %da now)/sur/aquarium/hoon + =/ warped (cat 3 '=> . ' .^(@t %cx (weld /(scot %p our) pax))) + =/ aqua-pax :(weld /i/(scot %p her) pax /noun) + ?: =(warped (need (scry-aqua (unit @) now aqua-pax))) + [%test-done &]~ + ~& %not-done-yet + ~ + :_ ..start + %- zing + :~ (on-ergo her who ovo cb) + (on-dojo-output her who ovo ">=" cb) + == + -- ++ scry-aqua |* [a=mold now=@da pax=path] .^ a diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index c6c2113ed..5f6e651cf 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -2397,8 +2397,8 @@ ^+ bar ?- -.mys $ins :: insert if not exist - ?: (~(has by bar) pax) ~|([%ins-bar pax] !!) :: - ?: (~(has by hat) pax) ~|([%ins-hat pax] !!) :: + ?: (~(has by bar) pax) ~|([%ins-bar pax hen] !!) :: + ?: (~(has by hat) pax) ~|([%ins-hat pax hen] !!) :: %+ ~(put by bar) pax %- make-direct-blob ?: &(?=($mime -.p.mys) =([%hoon ~] (slag (dec (lent pax)) pax))) @@ -4231,6 +4231,9 @@ :: $note [[hen %give +.q.hin]~ ..^$] $wake + ?: ?=([%tyme ~] tea) + ~& %out-of-tyme + `..^$ :: dear reader, if it crashes here, check the wire. If it came :: from ++bait, then I don't think we have any handling for that :: sort of thing. From ad4750fb93a60267933e2b321b8b0cf15bdd003b Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 21 Feb 2019 15:13:40 -0800 Subject: [PATCH 027/133] add swap-vanes to aqua --- app/aqua.hoon | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 5fe6b6f37..ac8ebee23 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -406,7 +406,6 @@ ?~ pers ~ ?: &(?=(^ next-events.q.i.pers) processing-events.q.i.pers) - ~& [%new-events p.i.pers] `p.i.pers $(pers t.pers) ~& plowing=who @@ -439,6 +438,8 @@ ~& lent=(met 3 (jam boot-ova.pil)) =/ res=toon :: (each * (list tank)) (mock [boot-ova.pil [2 [0 3] [0 2]]] scry) + =. fleet-snaps ~ + =. init-cache ~ ?- -.res %0 ~& %suc @@ -470,6 +471,31 @@ :: boilerplate :: ?+ val ~|(%bad-noun-arg !!) + [%swap-vanes vs=*] + ?> ?=([[%7 * %1 installed=*] ~] boot-ova.pil) + =. installed.boot-ova.pil + %+ roll (,(list term) vs.val) + |= [v=term _installed.boot-ova.pil] + %^ slum installed.boot-ova.pil now.hid + =/ vane + ?+ v ~|([%unknown-vane v] !!) + %a %ames + %b %behn + %c %clay + %d %dill + %e %eyre + %f %ford + %g %gall + %j %ford + == + =/ pax + /(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/[vane] + =/ txt .^(@ %cx (weld pax /hoon)) + [/vane/[vane] [%veer v pax txt]] + => .(this ^+(this this)) + =^ ms this (poke-pill pil) + (emit-moves ms) + :: [%init hers=*] =/ hers ((list ship) hers.val) ?~ hers From 3e1d742deb99a36cabb18070b26a309d7ea45d03 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 21 Feb 2019 15:56:46 -0800 Subject: [PATCH 028/133] add control flow to |verb --- sys/arvo.hoon | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/sys/arvo.hoon b/sys/arvo.hoon index 5e0872812..3cbb8683a 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -50,7 +50,7 @@ ++ mill (each vase milt) :: vase+metavase ++ milt {p/* q/*} :: metavase ++ monk (each ship {p/@tas q/@ta}) :: general identity -++ muse {p/@tas q/duct r/arvo} :: sourced move +++ muse {p/@tas q/duct r/arvo s/@ud} :: sourced move ++ move {p/duct q/arvo} :: arvo move ++ ovum {p/wire q/curd} :: typeless ovum ++ pane (list {p/@tas q/vase}) :: kernel modules @@ -462,7 +462,7 @@ :: ++ hurl :: start loop |= {lac/? ovo/ovum} - ~? &(!lac !=(%belt -.q.ovo)) [%unix -.q.ovo p.ovo] + ~? &(!lac !=(%belt -.q.ovo)) ["" %unix -.q.ovo p.ovo] :: ^- {p/(list ovum) q/(pair worm (list {p/@tas q/vase}))} ^- {p/(list ovum) q=(list [label=@tas =vane])} ?> ?=(^ p.ovo) @@ -474,6 +474,7 @@ :+ %& [%cell [%atom %tas `%soft] %noun] [%soft q.ovo] + 0 == == :: @@ -486,7 +487,7 @@ (swim:win org pux hen hil) :: ++ fire :: execute - |= {org/term lal/term pux/(unit wire) hen/duct hil/mill} + |= {org/term deh/@ud lal/term pux/(unit wire) hen/duct hil/mill} ^- {{p/(list ovum) q/(list muse)} _vanes} ?: &(?=(^ pux) ?=($~ hen)) [[[[lal u.pux] (curd +>.hil)]~ ~] vanes] @@ -498,7 +499,8 @@ [-.tuh [+<.tuh [i.naf +>.tuh]]] :: =+ fiq=(race org lal pux hen hil vane.i.naf) - [[~ (turn p.fiq |=(a/move [lal a]))] [[label.i.naf q.fiq] t.naf]] + :- [~ (turn p.fiq |=(a/move [lal p.a q.a +(deh)]))] + [[label.i.naf q.fiq] t.naf] :: ++ jack :: dispatch card |= {lac/? gum/muse} @@ -506,11 +508,13 @@ ~| %failed-jack :: =. lac |(lac ?=(?(%g %f) p.gum)) :: =. lac &(lac !?=($b p.gum)) - %+ fire - p.gum + %^ fire + p.gum + s.gum ?- -.r.gum $pass ~? &(!lac !=(%$ p.gum)) + :- (runt [s.gum '|'] "") :^ %pass [p.gum p.q.r.gum] [(symp +>-.q.q.r.gum) p.r.gum] q.gum @@ -522,11 +526,14 @@ ~| [%jack-bad-card p.gum (symp +>-.p.r.gum)] !! ~? &(!lac |(!=(%blit +>-.p.r.gum) !=(%d p.gum))) + :- (runt [s.gum '|'] "") [%give p.gum (symp +>-.p.r.gum) `duct`q.gum] [i.i.q.gum [~ t.i.q.gum] t.q.gum p.r.gum] :: $slip - ~? !lac [%slip p.gum (symp +>-.q.p.r.gum) q.gum] + ~? !lac + :- (runt [s.gum '|'] "") + [%slip p.gum (symp +>-.q.p.r.gum) q.gum] [p.p.r.gum ~ q.gum q.p.r.gum] == :: @@ -551,7 +558,7 @@ [%soft q.ovo] %+ kick lac %+ turn vanes - |=([label=@tas *] [label ~ [%pass p.ovo label card]]) + |=([label=@tas *] [label ~ [%pass p.ovo label card] 0]) -- -- =< :: Arvo larval stage @@ -584,11 +591,7 @@ :: ++ poke |= * :: 47 ^- [(list ovum) *] - ~& =+ a=+< - =+ (met 3 (jam a)) - [%larval-poking ?:((gth - 10.000) - `a)] => .(+< ((hard ,[now=@da ovo=ovum]) +<)) - ~& [%larval-harded now p.ovo p.q.ovo] ^- [(list ovum) *] =. +>.$ ?+ -.q.ovo From 99b6111597f4cd40fc9fd15793a177b748bbfeb2 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 21 Feb 2019 15:57:51 -0800 Subject: [PATCH 029/133] wip --- app/ph.hoon | 10 ++++--- lib/ph.hoon | 67 +++++++++++++++++++++++++++++++++++----------- sys/arvo.hoon | 2 +- sys/vane/clay.hoon | 29 ++++++++++++++------ sys/vane/ford.hoon | 1 + 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index ef94d4562..937f50ef7 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -139,9 +139,13 @@ :: :- %child-sync %+ compose-tests - %+ compose-tests - (star ~marbud) - (touch-file ~bud) + :: %+ compose-tests + :: %+ compose-tests + %+ compose-tests + (galaxy ~bud) + :: (reload-vane ~bud %clay) + (raw-ship ~marbud) + :: (touch-file ~bud) (check-file-touched ~marbud) :: :- %individual-breach diff --git a/lib/ph.hoon b/lib/ph.hoon index fddc4e768..958766d55 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -109,6 +109,25 @@ |= [a=test-core b=test-core] ^- test-core =/ done-with-a | + => + |% + ++ filter-a + |= [now=@da events=(list ph-event)] + ^- (quip ph-event _..filter-a) + =+ ^- [done=(list ph-event) other-events=(list ph-event)] + %+ skid events + |= e=ph-event + =(%test-done -.e) + ?~ done + [other-events ..filter-a] + ?> ?=(%test-done -.i.done) + ?. p.i.done + [[%test-done |]~ ..filter-a] + =. done-with-a & + =/ snap-event [%snap-ships label:a ships:a] + =^ events-start b (start:b now) + [(welp other-events [snap-event events-start]) ..filter-a] + -- |% :: :: Cache lookup label @@ -131,7 +150,8 @@ =. done-with-a & =/ restore-event [%restore-snap label:a] =^ events-start b (start:b now) - [[restore-event events-start] ..start] + =^ events ..filter-a (filter-a now restore-event events-start) + [events ..start] =^ events a (start:a now) [events ..start] :: @@ -149,20 +169,8 @@ =^ events b (route:b now who ovo) [events ..start] =^ events a (route:a now who ovo) - =+ ^- [done=(list ph-event) other-events=(list ph-event)] - %+ skid events - |= e=ph-event - =(%test-done -.e) - ?~ done - [other-events ..start] - ?> ?=(%test-done -.i.done) - ~& [%transitioning label] - ?. p.i.done - [[%test-done |]~ ..start] - =. done-with-a & - =/ snap-event [%snap-ships label:a ships:a] - =^ events-start b (start:b now) - [(welp other-events [snap-event events-start]) ..start] + =^ events ..filter-a (filter-a now events) + [events ..start] -- :: :: Don't use directly, or else you might not have a parent. @@ -310,6 +318,35 @@ (on-dojo-output her who ovo ">=" cb) == -- + :: + :: Reload vane from filesystem + :: + :: Ship must have been started. + :: + ++ reload-vane + |= [her=ship vane=term] + ^- test-core + |% + ++ label :((cury cat 3) 'reload-vane-' (scot %p her) '-' vane) + ++ ships ~ + ++ start + |= now=@da + ^- (pair (list ph-event) _..start) + =/ pax + /(scot %p our)/home/(scot %da now)/sys/vane/[vane]/hoon + :_ ..start + %- zing + :~ (dojo her "|mount %") + (insert-file her pax .^(@t %cx pax)) + [%test-done &]~ + == + :: + ++ route + |= [now=@da who=ship ovo=unix-effect] + ^- (quip ph-event _..start) + `..start + -- + :: ++ scry-aqua |* [a=mold now=@da pax=path] .^ a diff --git a/sys/arvo.hoon b/sys/arvo.hoon index 3cbb8683a..164ea8758 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -644,7 +644,7 @@ :: =/ pit=vase !>(..is) :: =/ vil=vile (viol p.pit) :: cached reflexives -=| $: lac=? :: laconic bit +=| $: lac=_| :: laconic bit eny=@ :: entropy our=ship :: identity bud=vase :: %zuse diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index 5f6e651cf..5e67a3798 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -1171,6 +1171,7 @@ ?~ hat +>.$ wake:(print-changes:(checkout-ankh u.hat) wen lem) + ~& [%edit our hen] ?. =(~ dok) ~& %already-applying-changes +> :: @@ -2376,6 +2377,7 @@ ++ apply-changes :: apply-changes:ze |= lar/(list {p/path q/misu}) :: store changes ^- (map path blob) + ~& [%apply-changes our hen] =+ ^= hat :: current state ?: =(let.dom 0) :: initial commit ~ :: has nothing @@ -3768,6 +3770,17 @@ wrapped-task ((hard task:able) p.wrapped-task) :: + :: only one of these should be going at once, so queue + :: + ?: &(?=(?(%info %into %merg) -.req) |(=(now tip.ruf) ?=(^ cue.ruf))) + =. cue.ruf (~(put to cue.ruf) [hen req]) + =/ wait=(list move) + ?~(cue.ruf ~ [hen %pass /queued-request %b %wait now]~) + [wait ..^$] + (handle-task hen req) +:: +++ handle-task + |= [hen=duct req=task:able] ^+ [*(list move) ..^$] ?- -.req $boat @@ -3823,19 +3836,13 @@ [mos ..^$] :: $info - :: second write at :now gets enqueued with a timer to be run in next event - :: - ?: =(now tip.ruf) - =. cue.ruf (~(put to cue.ruf) [hen req]) - =/ =move [hen %pass /queued-request %b %wait now] - :: - [~[move] ..^$] :: set the last date to now so we'll know to enqueue a second write :: =. tip.ruf now :: ?: =(%$ des.req) [~ ..^$] + => .(ruf `raft`ruf) :: TMI =^ mos ruf =/ den ((de our now ski hen ruf) our des.req) abet:(edit:den now dit.req) @@ -3877,6 +3884,7 @@ $merg :: direct state up ?: =(%$ des.req) [~ ..^$] + => .(ruf `raft`ruf) :: TMI =^ mos ruf =/ den ((de our now ski hen ruf) our des.req) abet:abet:(start:(me:ze:den [her.req dem.req] ~ &) cas.req how.req) @@ -4246,7 +4254,12 @@ ~| [%mismatched-ducts %queued queued-duct %timer hen] ?> =(hen queued-duct) :: - (call hen [-:!>(*task:able) queued-task]) + =/ wait + ?~ cue.ruf + ~ + [hen %pass /queued-request %b %wait now]~ + =^ moves ..^$ (handle-task hen queued-task) + [(weld wait moves) ..^$] :: =^ mos=(list move) une :: wake:(un our now hen ruf) :: [mos ..^^$] diff --git a/sys/vane/ford.hoon b/sys/vane/ford.hoon index cde22f241..069789f4b 100644 --- a/sys/vane/ford.hoon +++ b/sys/vane/ford.hoon @@ -5751,6 +5751,7 @@ :: =? state ?=(^ last-sent.live.duct-status) =/ old-build=^build build(date date.u.last-sent.live.duct-status) + ~& [%x-live-15 our (build-to-tape build) (build-to-tape old-build)] :: (remove-anchor-from-root old-build [%duct duct]) :: From e319df9e8daab31ea1b9916c8b850860f3661882 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 22 Feb 2019 14:11:53 -0800 Subject: [PATCH 030/133] trigger dill init on merge completion --- sys/vane/dill.hoon | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sys/vane/dill.hoon b/sys/vane/dill.hoon index 82113fd1a..1d85561e7 100644 --- a/sys/vane/dill.hoon +++ b/sys/vane/dill.hoon @@ -298,10 +298,15 @@ ++ init :: initialize ~& [%dill-init our ram] ^+ . + =. moz :_(moz [hen %pass / %c %merg %home our %base da+now %init]) + . + :: + ++ mere :: continue init + ~& [%dill-mere our ram] + ^+ . =/ myt (flop (need tem)) =/ can (clan:title our) =. tem ~ - =. moz :_(moz [hen %pass / %c %merg %home our %base da+now %init]) =. moz :_(moz [hen %pass ~ %g %conf [[our ram] %load our %home]]) =. +> (sync %home our %base) =. +> ?: ?=(?($czar $pawn) can) +> @@ -391,11 +396,6 @@ :: {$a $send *} +>(moz :_(moz [hen %give +.sih])) - :: - {$c $mere *} - ?: ?=(%& -.p.sih) - +>.$ - (mean >%dill-mere-fail< >p.p.p.sih< q.p.p.sih) :: {$g $onto *} :: ~& [%take-gall-onto +>.sih] @@ -420,6 +420,11 @@ :: {$c $writ *} init + :: + {$c $mere *} + ?: ?=(%& -.p.sih) + mere + (mean >%dill-mere-fail< >p.p.p.sih< q.p.p.sih) :: {$c $mack *} ?~ p.sih +>.$ From 3f74d30085d111b231b99f156304c447c5505b36 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 22 Feb 2019 14:16:22 -0800 Subject: [PATCH 031/133] add ford printf in bad situation --- sys/vane/ford.hoon | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/vane/ford.hoon b/sys/vane/ford.hoon index 069789f4b..796f69343 100644 --- a/sys/vane/ford.hoon +++ b/sys/vane/ford.hoon @@ -5751,7 +5751,10 @@ :: =? state ?=(^ last-sent.live.duct-status) =/ old-build=^build build(date date.u.last-sent.live.duct-status) - ~& [%x-live-15 our (build-to-tape build) (build-to-tape old-build)] + ~? =(date.build date.old-build) + :+ "old and new builds have same date, will probably crash!" + (build-to-tape build) + (build-to-tape old-build) :: (remove-anchor-from-root old-build [%duct duct]) :: From e22eac6a728c8608de1258cdadf3b1fa8d7d6f5c Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 22 Feb 2019 15:52:18 -0800 Subject: [PATCH 032/133] child-sync test passes --- app/ph.hoon | 14 +++++--------- lib/hood/drum.hoon | 8 ++++---- lib/ph.hoon | 27 ++++++++++++++++----------- sys/arvo.hoon | 4 ++-- sys/vane/clay.hoon | 11 ++++++++--- sys/vane/dill.hoon | 4 +++- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index 937f50ef7..b8c887d61 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -135,18 +135,14 @@ :: :- %change-file %+ compose-tests (galaxy ~bud) - (touch-file ~bud) + (touch-file ~bud %home) :: :- %child-sync %+ compose-tests - :: %+ compose-tests - :: %+ compose-tests - %+ compose-tests - (galaxy ~bud) - :: (reload-vane ~bud %clay) - (raw-ship ~marbud) - :: (touch-file ~bud) - (check-file-touched ~marbud) + %+ compose-tests + (star ~marbud) + (touch-file ~bud %base) + (check-file-touched ~marbud %home) :: :- %individual-breach *test-core diff --git a/lib/hood/drum.hoon b/lib/hood/drum.hoon index 0fa4ec657..33082ece8 100644 --- a/lib/hood/drum.hoon +++ b/lib/hood/drum.hoon @@ -80,11 +80,11 @@ :: ?: ?=($pawn myr) [[%base %collections] [%base %hall] [%base %talk] [%base %dojo] ~] - :~ [%home %collections] - [%home %acme] - [%home %dns] + :~ :: [%home %collections] + :: [%home %acme] + :: [%home %dns] [%home %dojo] - [%home %hall] + :: [%home %hall] [%home %talk] == :: diff --git a/lib/ph.hoon b/lib/ph.hoon index 958766d55..70295531b 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -62,13 +62,13 @@ == :: ++ insert-file - |= [who=ship pax=path txt=@t] + |= [who=ship des=desk pax=path txt=@t] ^- (list ph-event) ?> ?=([@ @ @ *] pax) =/ file [/text/plain (as-octs:mimes:html txt)] %+ send-events-to who :~ - [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~] + [//sync/0v1n.2m9vh %into des | [t.t.t.pax `file]~] == :: ++ on-dojo-output @@ -245,7 +245,7 @@ :: Ship must have been started. :: ++ touch-file - |= her=ship + |= [her=ship des=desk] ^- test-core =| warped=@t |% @@ -259,8 +259,8 @@ =. warped (cat 3 '=> . ' .^(@t %cx pax)) :_ ..start %- zing - :~ (dojo her "|mount %") - (insert-file her pax warped) + :~ (dojo her "|mount /={(trip des)}=") + (insert-file her des pax warped) == :: ++ route @@ -271,7 +271,7 @@ :~ %- on-ergo :^ her who ovo |= $~ - =/ pax /i/[(scot %p her)]/home/(scot %da now)/sur/aquarium/hoon/noun + =/ pax /i/(scot %p her)/[des]/(scot %da now)/sur/aquarium/hoon/noun ?: =(warped (need (scry-aqua (unit @) now pax))) [%test-done &]~ ~& %not-done-yet @@ -284,7 +284,7 @@ :: Ship must have been started. :: ++ check-file-touched - |= her=ship + |= [her=ship des=desk] ^- test-core |% ++ label (cat 3 'check-file-touched-' (scot %p her)) @@ -297,7 +297,7 @@ :: is already mounted) :: ~& %mounting - [(dojo her "|mount %") ..start] + [(dojo her "|mount /={(trip des)}=") ..start] :: ++ route |= [now=@da who=ship ovo=unix-effect] @@ -307,7 +307,12 @@ ~& %cbing =/ pax /home/(scot %da now)/sur/aquarium/hoon =/ warped (cat 3 '=> . ' .^(@t %cx (weld /(scot %p our) pax))) - =/ aqua-pax :(weld /i/(scot %p her) pax /noun) + =/ aqua-pax + ;: weld + /i/(scot %p her) + pax(- des) + /noun + == ?: =(warped (need (scry-aqua (unit @) now aqua-pax))) [%test-done &]~ ~& %not-done-yet @@ -336,8 +341,8 @@ /(scot %p our)/home/(scot %da now)/sys/vane/[vane]/hoon :_ ..start %- zing - :~ (dojo her "|mount %") - (insert-file her pax .^(@t %cx pax)) + :~ (dojo her "|mount /=home=") + (insert-file her %home pax .^(@t %cx pax)) [%test-done &]~ == :: diff --git a/sys/arvo.hoon b/sys/arvo.hoon index 164ea8758..801847e33 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -462,7 +462,7 @@ :: ++ hurl :: start loop |= {lac/? ovo/ovum} - ~? &(!lac !=(%belt -.q.ovo)) ["" %unix -.q.ovo p.ovo] + ~? &(!lac !=(%belt -.q.ovo)) ["" %unix -.q.ovo p.ovo now] :: ^- {p/(list ovum) q/(pair worm (list {p/@tas q/vase}))} ^- {p/(list ovum) q=(list [label=@tas =vane])} ?> ?=(^ p.ovo) @@ -644,7 +644,7 @@ :: =/ pit=vase !>(..is) :: =/ vil=vile (viol p.pit) :: cached reflexives -=| $: lac=_| :: laconic bit +=| $: lac=_& :: laconic bit eny=@ :: entropy our=ship :: identity bud=vase :: %zuse diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index 5e67a3798..879dbe13c 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -3773,9 +3773,9 @@ :: only one of these should be going at once, so queue :: ?: &(?=(?(%info %into %merg) -.req) |(=(now tip.ruf) ?=(^ cue.ruf))) - =. cue.ruf (~(put to cue.ruf) [hen req]) =/ wait=(list move) - ?~(cue.ruf ~ [hen %pass /queued-request %b %wait now]~) + ?^(cue.ruf ~ [hen %pass /queued-request %b %wait now]~) + =. cue.ruf (~(put to cue.ruf) [hen req]) [wait ..^$] (handle-task hen req) :: @@ -4251,13 +4251,18 @@ =/ queued-duct=duct -.queued =/ queued-task=task:able +.queued :: + ~& :* %x-clay-waking + queued-duct + hen + ?~(cue.ruf /empty -:(need ~(top to cue.ruf))) + == ~| [%mismatched-ducts %queued queued-duct %timer hen] ?> =(hen queued-duct) :: =/ wait ?~ cue.ruf ~ - [hen %pass /queued-request %b %wait now]~ + [-:(need ~(top to cue.ruf)) %pass /queued-request %b %wait now]~ =^ moves ..^$ (handle-task hen queued-task) [(weld wait moves) ..^$] :: =^ mos=(list move) une diff --git a/sys/vane/dill.hoon b/sys/vane/dill.hoon index 1d85561e7..d71ad0699 100644 --- a/sys/vane/dill.hoon +++ b/sys/vane/dill.hoon @@ -298,7 +298,9 @@ ++ init :: initialize ~& [%dill-init our ram] ^+ . - =. moz :_(moz [hen %pass / %c %merg %home our %base da+now %init]) + =. moz + :_ moz + [hen %pass /merg/home %c %merg %home our %base da+now %init] . :: ++ mere :: continue init From 855cb26b52b311bf518afbf27992002f99906336 Mon Sep 17 00:00:00 2001 From: Fang Date: Mon, 4 Mar 2019 23:17:10 +0100 Subject: [PATCH 033/133] Update leap second lists --- sys/zuse.hoon | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/sys/zuse.hoon b/sys/zuse.hoon index 45deef347..6acc4cbcd 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -6882,28 +6882,33 @@ :: :: ++lef:yu:chrono: ++ lef :: leapsecond dates ^- (list @da) - :~ ~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 + :~ ~2016.12.31..23.59.59 ~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 == - :: :: ++les:yu:chrono: - ++ les :: leapsecond days + :: + :: +les:yu:chrono: leapsecond days + :: + :: https://www.ietf.org/timezones/data/leap-seconds.list + :: + ++ les ^- (list @da) - :~ ~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 + :~ ~2017.1.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 == -- ::yu -- ::chrono From 3ef6007930c79e786d8a43e5e9b2519d36889f4b Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 6 Mar 2019 16:50:05 +0100 Subject: [PATCH 034/133] Fix topics decoding to work with zero values --- sys/zuse.hoon | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/zuse.hoon b/sys/zuse.hoon index 97d147769..fbc14e3ca 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -7758,10 +7758,9 @@ :: tox: list of hex words |* [tox=(lest @ux) tys=(list etyp)] =- (decode-arguments (crip -) tys) - %+ render-hex-bytes (mul 32 (lent tox)) %+ roll `(list @ux)`tox - |= [top=@ux tos=@] - (cat 8 top tos) + |= [top=@ tos=tape] + (weld tos (render-hex-bytes 32 top)) :: ++ decode-results :: rex: string of hex bytes with leading 0x. From 1ab6fea917a0323f4953e83ff5ddb94bfc8c8c85 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 6 Mar 2019 12:22:37 -0800 Subject: [PATCH 035/133] keep logs --- app/aqua.hoon | 143 +++++++++++++++++++++++++++++++++------------- app/ph.hoon | 52 +++++++++++++---- lib/ph.hoon | 63 +++++++++++++++++--- sur/aquarium.hoon | 40 ++++++++++--- sys/arvo.hoon | 2 +- 5 files changed, 232 insertions(+), 68 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 48f29b6ed..29b70f950 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -23,25 +23,35 @@ /- aquarium =, aquarium => $~ |% - ++ move (pair bone card) - ++ card + +$ move (pair bone card) + +$ card $% [%wait wire p=@da] [%rest wire p=@da] [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] - [%diff %aqua-effects aqua-effects] + [%diff diff-type] == - ++ state + :: + :: Outgoing subscription updates + :: + +$ diff-type + $% [%aqua-effects aqua-effects] + [%aqua-events aqua-events] + [%aqua-boths aqua-boths] + == + :: + +$ state $: %0 pil=pill assembled=* tym=@da - init-cache=(map ship pier) + init-cache=(map [ship (unit dawn-event)] pier) fleet-snaps=(map term (map ship pier)) piers=(map ship pier) == - ++ pier + :: + +$ pier $: snap=* - event-log=(list [@da unix-event]) + event-log=(list unix-timed-event) next-events=(qeu unix-event) processing-events=? next-timer=(unit @da) @@ -55,6 +65,8 @@ :: moves: Hoist moves into state for cleaner state management :: =| unix-effects=(jar ship unix-effect) +=| unix-events=(jar ship unix-timed-event) +=| unix-boths=(jar ship unix-both) =| moves=(list move) |_ $: hid=bowl state @@ -103,8 +115,8 @@ =/ poke p.res =. tym (max +(tym) now.hid) =/ res (slum poke tym ovo) - =. event-log [[tym ovo] event-log] =. snap +3.res + =. ..abet-pe (publish-event tym ovo) =. ..abet-pe (handle-effects ((list ovum) -.res)) $ :: @@ -307,6 +319,7 @@ ~& [who=who %cant-cancel-thus num=num] =. http-requests (~(del in http-requests) num) ..abet-pe + ~& [who=who %requesting u.req] =. http-requests (~(put in http-requests) num) %- emit-moves :_ ~ :* ost.hid @@ -360,6 +373,17 @@ |= ovo=unix-effect ^+ ..abet-pe =. unix-effects (~(add ja unix-effects) who ovo) + =. unix-boths (~(add ja unix-boths) who [%effect ovo]) + ..abet-pe + :: + :: Give event to our subscribers + :: + ++ publish-event + |= ovo=unix-timed-event + ^+ ..abet-pe + =. event-log [ovo event-log] + =. unix-events (~(add ja unix-events) who ovo) + =. unix-boths (~(add ja unix-boths) who [%event ovo]) ..abet-pe -- :: @@ -369,8 +393,10 @@ :: ++ apex-aqua ^+ this - =: moves ~ + =: moves ~ unix-effects ~ + unix-events ~ + unix-boths ~ == this :: @@ -381,13 +407,28 @@ %+ murn ~(tap by sup.hid) |= [b=bone her=ship pax=path] ^- (unit move) - ?. ?=([%effects @ ~] pax) - ~ - =/ who (slav %p i.t.pax) - =/ fx (~(get ja unix-effects) who) - ?~ fx - ~ - `[b %diff %aqua-effects who fx] + ?+ pax ~ + [%effects @ ~] + =/ who (slav %p i.t.pax) + =/ fx (~(get ja unix-effects) who) + ?~ fx + ~ + `[b %diff %aqua-effects who fx] + :: + [%events @ ~] + =/ who (slav %p i.t.pax) + =/ ve (~(get ja unix-events) who) + ?~ ve + ~ + `[b %diff %aqua-events who ve] + :: + [%boths @ ~] + =/ who (slav %p i.t.pax) + =/ bo (~(get ja unix-boths) who) + ?~ bo + ~ + `[b %diff %aqua-boths who bo] + == [(flop moves) this] :: ++ emit-moves @@ -427,6 +468,32 @@ !! `this :: +:: Subscribe to events to a ship +:: +++ peer-events + |= pax=path + ^- (quip move _this) + ?. ?=([@ ~] pax) + ~& [%aqua-bad-peer-events pax] + `this + ?~ (slaw %p i.pax) + ~& [%aqua-bad-peer-events-ship pax] + !! + `this +:: +:: Subscribe to both events and effects of a ship +:: +++ peer-boths + |= pax=path + ^- (quip move _this) + ?. ?=([@ ~] pax) + ~& [%aqua-bad-peer-boths pax] + `this + ?~ (slaw %p i.pax) + ~& [%aqua-bad-peer-boths-ship pax] + !! + `this +:: :: Load a pill and assemble arvo. Doesn't send any of the initial :: events. :: @@ -500,24 +567,8 @@ =/ hers ((list ship) hers.val) ?~ hers this - =^ ms this (poke-aqua-events [%init-ship i.hers]~) + =^ ms this (poke-aqua-events [%init-ship i.hers ~]~) (emit-moves ms) - :: %+ turn-ships ((list ship) hers.val) - :: |= [who=ship thus=_this] - :: =. this thus - :: ~& [%initting who] - :: %- push-events:apex:(pe who) - :: ^- (list unix-event) - :: :~ `unix-event`[/ %wack 0] :: eny - :: `unix-event`[/ %whom who] :: eny - :: `unix-event`[//newt/0v1n.2m9vh %barn ~] - :: `unix-event`[//behn/0v1n.2m9vh %born ~] - :: `unix-event`[//term/1 %boot %fake who] - :: `unix-event`-.userspace-ova.pil - :: `unix-event`[//http/0v1n.2m9vh %born ~] - :: `unix-event`[//http/0v1n.2m9vh %live 8.080 `8.445] - :: `unix-event`[//term/1 %belt %ctl `@c`%x] - :: == :: [%dojo hers=* command=*] %+ turn-ships ((list ship) hers.val) @@ -602,11 +653,11 @@ =. this thus ?- -.ovo %init-ship - =/ prev (~(get by init-cache) who.ovo) - ?: &(?=(^ prev) (lth who.ovo ~marzod)) - ~& [%loading-cached-ship who.ovo] - =. this (restore-ships ~[who.ovo] init-cache) - (pe who.ovo) + :: =/ prev (~(get by init-cache) [who keys]:ovo) + :: ?: &(?=(^ prev) (lth who.ovo ~marzod)) + :: ~& [%loading-cached-ship who.ovo] + :: =. this (restore-ship who.ovo u.prev) + :: (pe who.ovo) =. this abet-pe:sleep:(pe who.ovo) =/ initted =< plow @@ -616,14 +667,17 @@ [/ %whom who.ovo] :: eny [//newt/0v1n.2m9vh %barn ~] [//behn/0v1n.2m9vh %born ~] - [//term/1 %boot %fake who.ovo] + :+ //term/1 %boot + ?~ keys.ovo + [%fake who.ovo] + [%dawn u.keys.ovo] -.userspace-ova.pil [//http/0v1n.2m9vh %born ~] [//http/0v1n.2m9vh %live 8.080 `8.445] == =. this abet-pe:initted =. init-cache - %+ ~(put by init-cache) who.ovo + %+ ~(put by init-cache) [who keys]:ovo (~(got by piers) who.ovo) (pe who.ovo) :: @@ -727,6 +781,15 @@ restore:(pe who) this :: +:: Restore ships from pier +:: +++ restore-ship + |= [her=ship per=pier] + =. this abet-pe:plow:sleep:(pe her) + =. piers (~(put by piers) her per) + =. this abet-pe:plow:restore:(pe her) + this +:: :: Received timer wake :: ++ wake diff --git a/app/ph.hoon b/app/ph.hoon index b8c887d61..8da418eb2 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -12,20 +12,27 @@ =, aquarium =, ph => $~ |% - ++ move (pair bone card) - ++ card + +$ move (pair bone card) + +$ card $% [%poke wire dock %aqua-events (list aqua-event)] [%peer wire dock path] [%pull wire dock ~] == :: - ++ state + +$ state $: %0 raw-test-cores=(map term test-core) - test-cores=(map term [hers=(list ship) cor=test-core]) + test-cores=(map term test-core-state) other-state == - ++ other-state + :: + +$ test-core-state + $: hers=(list ship) + cor=test-core + effect-log=(list [who=ship ovo=unix-effect]) + == + :: + +$ other-state $~ -- =, gall @@ -53,7 +60,7 @@ =. num +(num) :_ ..start %- zing - :~ (init ~bud) + :~ (init ~bud ~) (dojo ~bud "[%test-result (add 2 3)]") == :: @@ -63,7 +70,6 @@ ~& [%num num] :_ ..start (expect-dojo-output ~bud who ovo "[%test-result 5]") - :: XX if it's been five minutes, we failed -- :: :- %hi @@ -75,8 +81,8 @@ ^- (pair (list ph-event) _..start) :_ ..start %- zing - :~ (init ~bud) - (init ~dev) + :~ (init ~bud ~) + (init ~dev ~) (dojo ~bud "|hi ~dev") == :: @@ -143,6 +149,16 @@ (star ~marbud) (touch-file ~bud %base) (check-file-touched ~marbud %home) + :: + :- %boot-azimuth + %+ compose-tests + %+ compose-tests + (raw-ship ~bud `(dawn:azimuth ~bud)) + (touch-file ~bud %home) + :: %- assert-happens + :: :~ + :: == + *test-core :: :- %individual-breach *test-core @@ -239,10 +255,24 @@ [%run-test lab=@tas] =/ res=[events=(list ph-event) new-state=test-core] (start:(~(got by raw-test-cores) lab.arg) now.hid) - =. test-cores (~(put by test-cores) lab.arg [ships .]:new-state.res) + =. test-cores (~(put by test-cores) lab.arg [ships . ~]:new-state.res) =^ moves-1 this (subscribe-to-effects lab.arg ships.new-state.res) =^ moves-2 this (run-events lab.arg events.res) [(weld moves-1 moves-2) this] + :: + [%print lab=@tas] + =/ log effect-log:(~(got by test-cores) lab.arg) + ~& lent=(lent log) + ~& %+ roll log + |= [[who=ship ovo=unix-effect] ~] + ?: ?=(?(%blit %doze) -.q.ovo) + ~ + ?: ?=(%ergo -.q.ovo) + ~& [who [- +<]:ovo %omitted-by-ph] + ~ + ~& [who ovo] + ~ + `this == :: ++ diff-aqua-effects @@ -259,6 +289,8 @@ |- ^- (quip ph-event _u.test-cor) ?~ ovo.ova [~ u.test-cor] + =. effect-log.u.test-cor + [[who i.ovo]:ova effect-log.u.test-cor] =^ events-1 cor.u.test-cor (route:cor.u.test-cor now.hid who.ova i.ovo.ova) =^ events-2 u.test-cor diff --git a/lib/ph.hoon b/lib/ph.hoon index 70295531b..17d727217 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -12,7 +12,7 @@ :: :: Unique name, used as a cache label. :: - ++ label *term + ++ label *@ta :: :: List of ships that are part of the test. :: @@ -43,9 +43,9 @@ [%event who ovo] :: ++ init - |= who=ship + |= [who=ship keys=(unit dawn-event)] ^- (list ph-event) - [%init-ship who]~ + [%init-ship who keys]~ :: :: factor out send-events-to :: @@ -103,6 +103,51 @@ ~ (fun) :: +++ azimuth + |% + ++ dawn + |= who=ship + ^- dawn-event + :* (need (private-key who)) + (^sein:title who) + czar + ~[~['arvo' 'netw' 'ork']] + 0 + `(need (de-purl:html 'http://localhost:8545')) + ~ + == + :: + ++ czar + ^- (map ship [life pass]) + %- my + ^- (list (pair ship [life pass])) + %+ murn (gulf 0x0 0xff) + |= her=ship + ^- (unit [ship life pass]) + =/ pub (public-key her) + ?~ pub + ~ + `[her u.pub] + :: + ++ private-key + |= who=ship + =- (~(get by -) who) + ^- (map ship seed:able:jael) + %- my + :~ [~bud ~bud 1 'BbudB' ~] + [~dev ~dev 1 'Bdev' ~] + == + :: + ++ public-key + |= who=ship + ^- (unit [life pass]) + =/ priv (private-key who) + ?~ priv + ~ + =/ cub (nol:nu:crub:crypto key.u.priv) + `[lyf.u.priv pub:ex:cub] + -- +:: ++ test-lib |_ our=ship ++ compose-tests @@ -178,15 +223,15 @@ :: Consider ++galaxy, ++star, ++planet, and ++ship-with-ancestors. :: ++ raw-ship - |= her=ship + |= [her=ship keys=(unit dawn-event)] ^- test-core |% - ++ label (cat 3 'init-' (scot %p her)) + ++ label :((cury cat 3) 'init-' (scot %p her) '-' (scot %uw (mug (fall keys *dawn-event)))) ++ ships ~[her] ++ start |= now=@da ^- (quip ph-event _..start) - [(init her) ..start] + [(init her keys) ..start] :: ++ route |= [now=@da who=ship ovo=unix-effect] @@ -215,19 +260,19 @@ ++ galaxy |= her=ship ?> =(%czar (clan:title her)) - (raw-ship her) + (raw-ship her ~) :: ++ star |= her=ship ?> =(%king (clan:title her)) %+ compose-tests (galaxy (^sein:title her)) - (raw-ship her) + (raw-ship her ~) :: ++ planet |= her=ship ?> =(%duke (clan:title her)) %+ compose-tests (star (^sein:title her)) - (raw-ship her) + (raw-ship her ~) :: ++ ship-with-ancestors |= her=ship diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index 1adaec11e..bfec9f638 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -1,26 +1,39 @@ |% -++ aqua-event - $% [%init-ship who=ship] ++$ aqua-event + $% [%init-ship who=ship keys=(unit dawn-event)] [%pause-events who=ship] [%snap-ships lab=term hers=(list ship)] [%restore-snap lab=term] [%event who=ship ovo=unix-event] == :: -++ aqua-effects - ,[who=ship ovo=(list unix-effect)] ++$ aqua-effects + [who=ship ovo=(list unix-effect)] :: -++ unix-event ++$ aqua-events + [who=ship ovo=(list unix-timed-event)] +:: ++$ aqua-boths + [who=ship ovo=(list unix-both)] +:: ++$ unix-both + $% [%event unix-timed-event] + [%effect unix-effect] + == +:: ++$ unix-timed-event [tym=@da ovo=unix-event] +:: ++$ unix-event %+ pair wire $% [%wack p=@] [%whom p=ship] [%live p=@ud q=(unit @ud)] [%barn ~] - [%boot %fake p=ship] + [%boot $%([%fake p=ship] [%dawn p=dawn-event])] unix-task == :: -++ unix-effect ++$ unix-effect %+ pair wire $% [%blit p=(list blit:dill)] [%send p=lane:ames q=@] @@ -28,5 +41,16 @@ [%thus p=@ud q=(unit hiss:eyre)] [%ergo p=@tas q=mode:clay] == -+= pill [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] ++$ pill + [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] +:: ++$ dawn-event + $: =seed:able:jael + spon=ship + czar=(map ship [=life =pass]) + turf=(list turf) + bloq=@ud + node=(unit purl:eyre) + snap=(unit snapshot:jael) + == -- diff --git a/sys/arvo.hoon b/sys/arvo.hoon index a9e85ba03..10b548506 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -644,7 +644,7 @@ :: =/ pit=vase !>(..is) :: =/ vil=vile (viol p.pit) :: cached reflexives -=| $: lac=_& :: laconic bit +=| $: lac=_| :: laconic bit eny=@ :: entropy our=ship :: identity bud=vase :: %zuse From 68d3ebd8d4cb30ffc12552c5cb4471960e457790 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 6 Mar 2019 12:24:27 -0800 Subject: [PATCH 036/133] remove init-cache --- app/aqua.hoon | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index 29b70f950..cf172a477 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -44,7 +44,6 @@ pil=pill assembled=* tym=@da - init-cache=(map [ship (unit dawn-event)] pier) fleet-snaps=(map term (map ship pier)) piers=(map ship pier) == @@ -506,7 +505,6 @@ =/ res=toon :: (each * (list tank)) (mock [boot-ova.pil [2 [0 3] [0 2]]] scry) =. fleet-snaps ~ - =. init-cache ~ ?- -.res %0 ~& %suc @@ -638,7 +636,6 @@ :: [%clear-snap lab=@tas] =. fleet-snaps ~ :: (~(del by fleet-snaps) lab.val) - =. init-cache ~ this == :: @@ -653,11 +650,6 @@ =. this thus ?- -.ovo %init-ship - :: =/ prev (~(get by init-cache) [who keys]:ovo) - :: ?: &(?=(^ prev) (lth who.ovo ~marzod)) - :: ~& [%loading-cached-ship who.ovo] - :: =. this (restore-ship who.ovo u.prev) - :: (pe who.ovo) =. this abet-pe:sleep:(pe who.ovo) =/ initted =< plow @@ -676,9 +668,6 @@ [//http/0v1n.2m9vh %live 8.080 `8.445] == =. this abet-pe:initted - =. init-cache - %+ ~(put by init-cache) [who keys]:ovo - (~(got by piers) who.ovo) (pe who.ovo) :: %pause-events From 186984fb1d0444f4fc4516aa730653aaa4b8f353 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 6 Mar 2019 13:14:32 -0800 Subject: [PATCH 037/133] style --- app/aqua.hoon | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/app/aqua.hoon b/app/aqua.hoon index cf172a477..1964d8069 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -59,8 +59,8 @@ -- =, gall :: -:: aqua-effect-list: collect list of aqua effects to broadcast at once -:: to avoid gall backpressure +:: unix-{effects,events,boths}: collect jar of effects and events to +:: brodcast all at once to avoid gall backpressure :: moves: Hoist moves into state for cleaner state management :: =| unix-effects=(jar ship unix-effect) @@ -78,23 +78,32 @@ =+ (fall (~(get by piers) who) *pier) =* pier-data - |% + :: + :: Done; install data + :: ++ abet-pe ^+ this =. piers (~(put by piers) who pier-data) this :: + :: Initialize new ship + :: ++ apex =. pier-data *pier =. snap assembled - ~& r=(met 3 (jam snap)) + ~& pill-size=(met 3 (jam snap)) ..abet-pe :: + :: Enqueue events to child arvo + :: ++ push-events |= ova=(list unix-event) ^+ ..abet-pe =. next-events (~(gas to next-events) ova) ..abet-pe :: + :: Send moves to host arvo + :: ++ emit-moves |= ms=(list move) =. this (^emit-moves ms) @@ -109,14 +118,14 @@ ?. processing-events ..abet-pe =^ ovo next-events ~(get to next-events) - =/ res (mox +47.snap) - ?> ?=(%0 -.res) - =/ poke p.res + =/ poke-arm (mox +47.snap) + ?> ?=(%0 -.poke-arm) + =/ poke p.poke-arm =. tym (max +(tym) now.hid) - =/ res (slum poke tym ovo) - =. snap +3.res + =/ poke-result (slum poke tym ovo) + =. snap +.poke-result =. ..abet-pe (publish-event tym ovo) - =. ..abet-pe (handle-effects ((list ovum) -.res)) + =. ..abet-pe (handle-effects ((list ovum) -.poke-result)) $ :: :: Peek @@ -170,6 +179,7 @@ ?~ next-timer ..abet-pe cancel-timer + :: :: Sleep eyre :: :: Eyre doesn't support cancelling HTTP requests from userspace. From dab83cd28e4a2e560b9f8efd72c7f6aa6909b04a Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Wed, 6 Mar 2019 23:31:14 -0800 Subject: [PATCH 038/133] restructure to separate vane apps --- app/aqua-ames.hoon | 72 ++++++ app/aqua-behn.hoon | 120 ++++++++++ app/aqua-dill.hoon | 78 +++++++ app/aqua-eyre.hoon | 148 ++++++++++++ app/aqua.hoon | 438 +++++------------------------------- app/ph.hoon | 129 +++++++---- gen/aqua/dojo.hoon | 14 ++ gen/aqua/file.hoon | 8 + gen/aqua/init.hoon | 6 + gen/aqua/raw-event.hoon | 6 + gen/aqua/restore-fleet.hoon | 6 + gen/aqua/snap-fleet.hoon | 8 + lib/ph.hoon | 107 +++++---- sur/aquarium.hoon | 50 +++- 14 files changed, 723 insertions(+), 467 deletions(-) create mode 100644 app/aqua-ames.hoon create mode 100644 app/aqua-behn.hoon create mode 100644 app/aqua-dill.hoon create mode 100644 app/aqua-eyre.hoon create mode 100644 gen/aqua/dojo.hoon create mode 100644 gen/aqua/file.hoon create mode 100644 gen/aqua/init.hoon create mode 100644 gen/aqua/raw-event.hoon create mode 100644 gen/aqua/restore-fleet.hoon create mode 100644 gen/aqua/snap-fleet.hoon diff --git a/app/aqua-ames.hoon b/app/aqua-ames.hoon new file mode 100644 index 000000000..97265440d --- /dev/null +++ b/app/aqua-ames.hoon @@ -0,0 +1,72 @@ +:: This needs a better SDN solution. Every ship should have an IP +:: address, and we should eventually test changing those IP +:: addresses. +:: +:: For now, we broadcast every packet to every ship and rely on them +:: to drop them. +:: +/- aquarium +=, aquarium +=> $~ |% + +$ move (pair bone card) + +$ card + $% [%poke wire dock %aqua-events (list aqua-event)] + [%peer wire dock path] + [%pull wire dock ~] + == + :: + +$ state + $: %0 + subscribed=_| + == + -- +=, gall +=| moves=(list move) +|_ $: bowl + state + == +++ this . +++ apex %_(this moves ~) +++ abet [(flop moves) this] +++ emit-moves + |= ms=(list move) + %_(this moves (weld ms moves)) +:: +++ emit-aqua-events + |= aes=(list aqua-event) + %- emit-moves + [%poke /aqua-events [our %aqua] %aqua-events aes]~ +:: +++ poke-aqua-vane-control + |= command=?(%subscribe %unsubscribe) + :_ this(subscribed =(command %subscribe) + (aqua-vane-control-handler subscribed) +:: +++ diff-aqua-effects + |= [way=wire afs=aqua-effects] + ^- (quip move _this) + =. this apex =< abet + |- ^+ this + ?~ ufs.afs + this + =. this + ?+ -.q.i.ufs.afs this + %restore handle-restore + %send (handle-send i.ufs.afs) + -- + $(ufs.afs t.ufs.afs) +:: +++ handle-restore + %- emit-aqua-events + [%event who [//newt/0v1n.2m9vh %barn ~]]~ +:: +++ handle-send + |= [way=wire %send lan=lane:ames pac=@] + ^+ this + =/ hear [//newt/0v1n.2m9vh %hear lan pac] + %- emit-aqua-events + %+ turn + .^((list ship) %gx /(scot %p our)/aqua/(scot %da now)/ships/noun) + |= who=ship + [%event who hear] +-- diff --git a/app/aqua-behn.hoon b/app/aqua-behn.hoon new file mode 100644 index 000000000..b8005a30e --- /dev/null +++ b/app/aqua-behn.hoon @@ -0,0 +1,120 @@ +/- aquarium +=, aquarium +=> $~ |% + +$ move (pair bone card) + +$ card + $% [%poke wire dock %aqua-events (list aqua-event)] + [%peer wire dock path] + [%pull wire dock ~] + [%wait wire p=@da] + [%rest wire p=@da] + == + :: + +$ state + $: %0 + subscribed=_| + piers=(map ship next-timer=(unit @da)) + == + -- +=, gall +=| moves=(list move) +|_ $: bowl + state + == +++ this . +++ apex %_(this moves ~) +++ abet [(flop moves) this] +++ emit-moves + |= ms=(list move) + %_(this moves (weld ms moves)) +:: +++ emit-aqua-events + |= aes=(list aqua-event) + %- emit-moves + [%poke /aqua-events [our %aqua] %aqua-events aes]~ +:: +++ poke-aqua-vane-control + |= command=?(%subscribe %unsubscribe) + :_ this(subscribed =(command %subscribe) + (aqua-vane-control-handler subscribed) +:: +++ diff-aqua-effects + |= [way=wire afs=aqua-effects] + ^- (quip move _this) + =. this apex =< abet + |- ^+ this + ?~ ufs.afs + this + =. this + ?+ -.q.i.ufs.afs this + %sleep abet-pe:handle-sleep:(pe who.afs) + %restore abet-pe:handle-restore:(pe who.afs) + %doze abet-pe:(handle-doze:(pe who.afs) i.ufs.afs) + -- + $(ufs.afs t.ufs.afs) +:: +:: Received timer wake +:: +++ wake + |= [way=wire ~] + ^- (quip move _this) + =. this apex =< abet + ?> ?=([@ *] way) + =/ who (,@p (slav %p i.way)) + abet-pe:(take-wake:(pe who) t.way ~) +:: +++ pe + |= who=ship + =+ (fall (~(get by piers) who) *pier) + =* pier-data - + |% + ++ abet-pe + ^+ this + =. piers (~(put by piers) who pier-data) + this + :: + ++ handle-sleep + ^+ ..abet-pe + =< ..abet-pe(pier-data *pier) + ?~ next-timer + ..abet-pe + cancel-timer + :: + ++ handle-restore + ^+ ..abet-pe + %- emit-aqua-events + [%event who [//behn/0v1n.2m9vh %born ~]]~ + :: + ++ handle-doze + |= [way=wire %doze tim=(unit @da)] + ^+ ..abet-pe + ?~ tim + ?~ next-timer + this + cancel-timer + ?~ next-timer + (set-timer u.tim) + (set-timer:cancel-timer u.tim) + :: + ++ set-timer + |= tim=@da + =. tim +(tim) :: nobody's perfect + ~& [who=who %setting-timer tim] + =. next-timer `tim + (emit-moves [ost.hid %wait /(scot %p who) tim]~) + :: + ++ cancel-timer + ~& [who=who %cancell-timer (need next-timer)] + =. next-timer ~ + (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) + :: + ++ take-wake + |= [way=wire ~] + ~& [who=who %aqua-behn-wake now.hid] + =. next-timer ~ + =. this + %- emit-aqua-events + [%event who [//behn/0v1n.2m9vh %wake ~]]~ + ..abet-pe + -- +-- diff --git a/app/aqua-dill.hoon b/app/aqua-dill.hoon new file mode 100644 index 000000000..c01be9754 --- /dev/null +++ b/app/aqua-dill.hoon @@ -0,0 +1,78 @@ +:: Would love to see a proper stateful terminal handler. Ideally, +:: you'd be able to ^X into the virtual ship, like the old ^W. +:: +:: However, that's probably not the primary way of interacting with +:: it. In practice, most of the time you'll be running from a file +:: (eg for automated testing) or fanning the same command to multiple +:: ships or otherwise making use of the fact that we can +:: programmatically send events. +:: +/- aquarium +=, aquarium +=> $~ |% + +$ move (pair bone card) + +$ card + $% [%poke wire dock %aqua-events (list aqua-event)] + [%peer wire dock path] + [%pull wire dock ~] + == + :: + +$ state + $: %0 + subscribed=_| + == + -- +=, gall +=| moves=(list move) +|_ $: bowl + state + == +++ this . +++ apex %_(this moves ~) +++ abet [(flop moves) this] +++ emit-moves + |= ms=(list move) + %_(this moves (weld ms moves)) +:: +++ emit-aqua-events + |= aes=(list aqua-event) + %- emit-moves + [%poke /aqua-events [our %aqua] %aqua-events aes]~ +:: +++ poke-aqua-vane-control + |= command=?(%subscribe %unsubscribe) + :_ this(subscribed =(command %subscribe) + (aqua-vane-control-handler subscribed) +:: +++ diff-aqua-effects + |= [way=wire afs=aqua-effects] + ^- (quip move _this) + =. this apex =< abet + |- ^+ this + ?~ ufs.afs + this + =. this + ?+ -.q.i.ufs.afs this + %blit (handle-blit i.ufs.afs) + -- + $(ufs.afs t.ufs.afs) +:: +++ handle-blit + |= [way=wire %blit blits=(list blit:dill)] + ^+ ..abet-pe + =/ last-line + %+ roll blits + |= [b=blit:dill line=tape] + ?- -.b + %lin (tape p.b) + %mor ~& "{}: {line}" "" + %hop line + %bel line + %clr "" + %sag ~& [%save-jamfile-to p.b] line + %sav ~& [%save-file-to p.b] line + %url ~& [%activate-url p.b] line + == + ~& last-line + ..abet-pe +-- diff --git a/app/aqua-eyre.hoon b/app/aqua-eyre.hoon new file mode 100644 index 000000000..653a7aecf --- /dev/null +++ b/app/aqua-eyre.hoon @@ -0,0 +1,148 @@ +:: Pass-through Eyre driver +:: +/- aquarium +=, aquarium +=> $~ |% + +$ move (pair bone card) + +$ card + $% [%poke wire dock %aqua-events (list aqua-event)] + [%peer wire dock path] + [%pull wire dock ~] + [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] + == + :: + +$ state + $: %0 + subscribed=_| + piers=(map ship http-requests=(set @ud)) + == + -- +=, gall +=| moves=(list move) +|_ $: bowl + state + == +++ this . +++ apex %_(this moves ~) +++ abet [(flop moves) this] +++ emit-moves + |= ms=(list move) + %_(this moves (weld ms moves)) +:: +++ emit-aqua-events + |= aes=(list aqua-event) + %- emit-moves + [%poke /aqua-events [our %aqua] %aqua-events aes]~ +:: +++ poke-aqua-vane-control + |= command=?(%subscribe %unsubscribe) + :_ this(subscribed =(command %subscribe) + (aqua-vane-control-handler subscribed) +:: +++ diff-aqua-effects + |= [way=wire afs=aqua-effects] + ^- (quip move _this) + =. this apex =< abet + |- ^+ this + ?~ ufs.afs + this + =. this + ?+ -.q.i.ufs.afs this + %sleep abet-pe:handle-sleep:(pe who.afs) + %restore abet-pe:handle-restore:(pe who.afs) + %thus abet-pe:(handle-thus:(pe who.afs) i.ufs.afs) + -- + $(ufs.afs t.ufs.afs) +:: +:: Received inbound HTTP response +:: +++ sigh-httr + |= [way=wire res=httr:eyre] + ^- (quip move _this) + =. this apex-aqua =< abet-aqua + ?> ?=([@ *] way) + =/ who (,@p (slav %p i.way)) + ~& [%received-httr who] + abet-pe:(take-sigh-httr:(pe who) t.way res) +:: +:: Received inbound HTTP response error +:: +++ sigh-tang + |= [way=wire tan=tang] + ^- (quip move _this) + =. this apex-aqua =< abet-aqua + ?> ?=([@ *] way) + =/ who (,@p (slav %p i.way)) + ~& [%received-httr who] + abet-pe:(take-sigh-tang:(pe who) t.way tan) +:: +++ pe + |= who=ship + =+ (fall (~(get by piers) who) *pier) + =* pier-data - + |% + ++ abet-pe + ^+ this + =. piers (~(put by piers) who pier-data) + this + :: + ++ handle-sleep + ^+ ..abet-pe + ..abet-pe(pier-data *pier) + :: + ++ handle-restore + ^+ ..abet-pe + %- emit-aqua-events + [%event who [//http/0v1n.2m9vh %born ~]]~ + :: + ++ handle-thus + |= [way=wire %thus num=@ud req=(unit hiss:eyre)] + ^+ ..abet-pe + ?~ req + ?. (~(has in http-requests) num) + ..abet-pe + :: Eyre doesn't support cancelling HTTP requests from userspace, + :: so we remove it from our state so we won't pass along the + :: response. + :: + ~& [who=who %aqua-eyre-cant-cancel-thus num=num] + =. http-requests (~(del in http-requests) num) + ..abet-pe + ~& [who=who %aqua-eyre-requesting u.req] + =. http-requests (~(put in http-requests) num) + %- emit-moves :_ ~ + :* ost.hid + %hiss + /(scot %p who)/(scot %ud num) + ~ + %httr + [%hiss u.req] + == + :: + :: Pass HTTP response back to virtual ship + :: + ++ take-sigh-httr + |= [way=wire res=httr:eyre] + ^+ ..abet-pe + ?> ?=([@ ~] way) + =/ num (slav %ud i.way) + ?. (~(has in http-requests) num) + ~& [who=who %ignoring-httr num=num] + ..abet-pe + =. http-requests (~(del in http-requests) num) + (emit-aqua-events [%event who [//http/0v1n.2m9vh %they num res]~) + :: + :: Got error in HTTP response + :: + ++ take-sigh-tang + |= [way=wire tan=tang] + ^+ ..abet-pe + ?> ?=([@ ~] way) + =/ num (slav %ud i.way) + ?. (~(has in http-requests) num) + ~& [who=who %ignoring-httr num=num] + ..abet-pe + =. http-requests (~(del in http-requests) num) + %- (slog tan) + ..abet-pe +-- diff --git a/app/aqua.hoon b/app/aqua.hoon index 1964d8069..4c6e01ccd 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -25,10 +25,7 @@ => $~ |% +$ move (pair bone card) +$ card - $% [%wait wire p=@da] - [%rest wire p=@da] - [%hiss wire p=(unit user:eyre) q=mark r=(cask hiss:eyre)] - [%diff diff-type] + $% [%diff diff-type] == :: :: Outgoing subscription updates @@ -53,8 +50,6 @@ event-log=(list unix-timed-event) next-events=(qeu unix-event) processing-events=? - next-timer=(unit @da) - http-requests=(set @ud) == -- =, gall @@ -117,14 +112,14 @@ ..abet-pe ?. processing-events ..abet-pe - =^ ovo next-events ~(get to next-events) + =^ ue next-events ~(get to next-events) =/ poke-arm (mox +47.snap) ?> ?=(%0 -.poke-arm) =/ poke p.poke-arm =. tym (max +(tym) now.hid) - =/ poke-result (slum poke tym ovo) + =/ poke-result (slum poke tym ue) =. snap +.poke-result - =. ..abet-pe (publish-event tym ovo) + =. ..abet-pe (publish-event tym ue) =. ..abet-pe (handle-effects ((list ovum) -.poke-result)) $ :: @@ -153,40 +148,6 @@ ~& [who=who %wished (slum wish txt)] ..abet-pe :: - :: Restart outstanding requests - :: - ++ restore - ^+ ..abet-pe - :: Restore behn - :: - =. ..abet-pe - ?~ next-timer - ..abet-pe - (set-timer u.next-timer) - :: Restore eyre - :: - =. http-requests ~ - =. ..abet-pe (push-events [//http/0v1n.2m9vh %born ~]~) - ..abet-pe - :: - :: Cancel outstanding requests - :: - ++ sleep - ^+ ..abet-pe - :: Sleep behn - :: - =. ..abet-pe - ?~ next-timer - ..abet-pe - cancel-timer - :: - :: Sleep eyre - :: - :: Eyre doesn't support cancelling HTTP requests from userspace. - :: - =. http-requests ~ - ..abet-pe - :: ++ mox |=(* (mock [snap +<] scry)) :: :: Start/stop processing events. When stopped, events are added to @@ -207,192 +168,26 @@ ?~ sof ~& [who=who %unknown-effect i.effects] ..abet-pe - =. ..abet-pe - ?- -.q.u.sof - %blit (handle-blit u.sof) - %send (handle-send u.sof) - %doze (handle-doze u.sof) - %thus (handle-thus u.sof) - %ergo (handle-ergo u.sof) - == (publish-effect u.sof) $(effects t.effects) :: - :: Would love to see a proper stateful terminal handler. Ideally, - :: you'd be able to ^X into the virtual ship, like the old ^W. - :: - :: However, that's porbably not the primary way of interacting with - :: it. In practice, most of the time you'll be running from a file - :: (eg for automated testing) or fanning the same command to multiple - :: ships or otherwise making use of the fact that we can - :: programmatically send events. - :: - ++ handle-blit - |= [way=wire %blit blits=(list blit:dill)] - ^+ ..abet-pe - =/ last-line - %+ roll blits - |= [b=blit:dill line=tape] - ?- -.b - %lin (tape p.b) - %mor ~& "{}: {line}" "" - %hop line - %bel line - %clr "" - %sag ~& [%save-jamfile-to p.b] line - %sav ~& [%save-file-to p.b] line - %url ~& [%activate-url p.b] line - == - ~& last-line - ..abet-pe - :: - :: This needs a better SDN solution. Every ship should have an IP - :: address, and we should eventually test changing those IP - :: addresses. - :: - :: For now, we broadcast every packet to every ship and rely on them - :: to drop them. - :: - ++ handle-send - |= [way=wire %send lan=lane:ames pac=@] - ^+ ..abet-pe - =/ dest-ip - |- ^- (unit @if) - ?- -.lan - %if `r.lan - %is ?~(q.lan ~ $(lan u.q.lan)) - %ix `r.lan - == - ?~ dest-ip - ~& [%sending-no-destination who lan] - ..abet-pe - ?. &(=(0 (rsh 0 16 u.dest-ip)) =(1 (rsh 0 8 u.dest-ip))) - ~& [%havent-implemented-direct-lanes who lan] - ..abet-pe - :: ~& [who=who %blast-sending] - =/ hear [//newt/0v1n.2m9vh %hear lan pac] - =. this (blast-event hear) - :: =/ her ?:(=(~dev who) ~bud ~dev) ::ship (dis u.dest-ip 0xff) - :: ?. (~(has by piers) her) - :: ~& [%dropping who=who her=her] - :: ..abet-pe - :: ~& [%sending who=who her=her ip=`@ux`u.dest-ip] - :: =^ ms this - :: abet-pe:(push-events:(pe her) ~[hear]) - ..abet-pe - :: - :: Would love to be able to control time more precisely, jumping - :: forward and whatnot. - :: - ++ handle-doze - |= [way=wire %doze tim=(unit @da)] - ^+ ..abet-pe - ?~ tim - ?~ next-timer - ..abet-pe - cancel-timer - ?~ next-timer - (set-timer u.tim) - (set-timer:cancel-timer u.tim) - :: - ++ set-timer - |= tim=@da - =. tim +(tim) :: nobody's perfect - ~& [who=who %setting-timer tim] - =. next-timer `tim - (emit-moves [ost.hid %wait /(scot %p who) tim]~) - :: - ++ cancel-timer - ~& [who=who %cancell-timer (need next-timer)] - (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) - :: - ++ take-wake - |= [way=wire ~] - ~& [who=who %wakey now.hid] - =. next-timer ~ - %- push-events:(pe who) - [//behn/0v1n.2m9vh %wake ~]~ - :: - :: Handle outgoing HTTP request - :: - ++ handle-thus - |= [way=wire %thus num=@ud req=(unit hiss:eyre)] - ^+ ..abet-pe - ?~ req - ?. (~(has in http-requests) num) - ..abet-pe - :: Eyre doesn't support cancelling HTTP requests from userspace, - :: so we remove it from our state so we won't pass along the - :: response. - :: - ~& [who=who %cant-cancel-thus num=num] - =. http-requests (~(del in http-requests) num) - ..abet-pe - ~& [who=who %requesting u.req] - =. http-requests (~(put in http-requests) num) - %- emit-moves :_ ~ - :* ost.hid - %hiss - /(scot %p who)/(scot %ud num) - ~ - %httr - [%hiss u.req] - == - :: - :: Pass HTTP response back to virtual ship - :: - ++ take-sigh-httr - |= [way=wire res=httr:eyre] - ^+ ..abet-pe - ?> ?=([@ ~] way) - =/ num (slav %ud i.way) - ?. (~(has in http-requests) num) - ~& [who=who %ignoring-httr num=num] - ..abet-pe - =. http-requests (~(del in http-requests) num) - (push-events [//http/0v1n.2m9vh %they num res]~) - :: - :: Got error in HTTP response - :: - ++ take-sigh-tang - |= [way=wire tan=tang] - ^+ ..abet-pe - ?> ?=([@ ~] way) - =/ num (slav %ud i.way) - ?. (~(has in http-requests) num) - ~& [who=who %ignoring-httr num=num] - ..abet-pe - =. http-requests (~(del in http-requests) num) - %- (slog tan) - ..abet-pe - :: - :: We should mirror a mount point of child to a clay desk of host. - :: For now, we just allow injecting a change to the child, so we - :: throw away ergos. - :: - ++ handle-ergo - |= [way=wire %ergo mount-point=@tas mod=mode:clay] - ^+ ..abet-pe - ~& [who=who %file-changes (lent mod)] :: (turn mod head)] - ..abet-pe - :: :: Give effect to our subscribers :: ++ publish-effect - |= ovo=unix-effect + |= uf=unix-effect ^+ ..abet-pe - =. unix-effects (~(add ja unix-effects) who ovo) - =. unix-boths (~(add ja unix-boths) who [%effect ovo]) + =. unix-effects (~(add ja unix-effects) who uf) + =. unix-boths (~(add ja unix-boths) who [%effect uf]) ..abet-pe :: :: Give event to our subscribers :: ++ publish-event - |= ovo=unix-timed-event + |= ute=unix-timed-event ^+ ..abet-pe - =. event-log [ovo event-log] - =. unix-events (~(add ja unix-events) who ovo) - =. unix-boths (~(add ja unix-boths) who [%event ovo]) + =. event-log [ute event-log] + =. unix-events (~(add ja unix-events) who ute) + =. unix-boths (~(add ja unix-boths) who [%event ute]) ..abet-pe -- :: @@ -413,30 +208,37 @@ ^- (quip move _this) =. this %- emit-moves - %+ murn ~(tap by sup.hid) + %- zing ^- (list (list move)) + %+ turn ~(tap by sup.hid) |= [b=bone her=ship pax=path] - ^- (unit move) + ^- (list move) ?+ pax ~ [%effects @ ~] =/ who (slav %p i.t.pax) - =/ fx (~(get ja unix-effects) who) - ?~ fx + =/ ufs (~(get ja unix-effects) who) + ?~ ufs ~ - `[b %diff %aqua-effects who fx] + [b %diff %aqua-effects who ufs]~ + :: + [%effects ~] + %+ turn + ~(tap by unix-effects) + |= [who=ship ufs=(list unix-effect)] + [b %diff %aqua-effects who ufs] :: [%events @ ~] =/ who (slav %p i.t.pax) =/ ve (~(get ja unix-events) who) ?~ ve ~ - `[b %diff %aqua-events who ve] + [b %diff %aqua-events who ve]~ :: [%boths @ ~] =/ who (slav %p i.t.pax) =/ bo (~(get ja unix-boths) who) ?~ bo ~ - `[b %diff %aqua-boths who bo] + [b %diff %aqua-boths who bo]~ == [(flop moves) this] :: @@ -469,7 +271,7 @@ ++ peer-effects |= pax=path ^- (quip move _this) - ?. ?=([@ ~] pax) + ?: ?=([@ @ *] pax) ~& [%aqua-bad-peer-effects pax] `this ?~ (slaw %p i.pax) @@ -570,53 +372,6 @@ => .(this ^+(this this)) =^ ms this (poke-pill pil) (emit-moves ms) - :: - [%init hers=*] - =/ hers ((list ship) hers.val) - ?~ hers - this - =^ ms this (poke-aqua-events [%init-ship i.hers ~]~) - (emit-moves ms) - :: - [%dojo hers=* command=*] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - %- push-events:(pe who) - ^- (list unix-event) - :~ - [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] - [//term/1 %belt %txt ((list @c) (tape command.val))] - [//term/1 %belt %ret ~] - == - :: - [%raw-event hers=* ovo=*] - =/ ovo ((soft unix-event) ovo.val) - ?~ ovo - ~& %ovo-not-an-event - this - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - (push-events:(pe who) ~[u.ovo]) - :: - [%file hers=* pax=*] - =/ pax (path pax.val) - ?> ?=([@ @ @ *] pax) - =/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - %- push-events:(pe who) - [//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~]~ - :: - [%peek hers=* p=*] - %+ turn-ships ((list ship) hers.val) - |= [who=ship thus=_this] - =. this thus - ~& [who=who %peek-result (peek:(pe who) p.val)] - (pe who) :: [%wish hers=* p=@t] %+ turn-ships ((list ship) hers.val) @@ -635,14 +390,6 @@ |= [who=ship thus=_this] =. this thus stop-processing-events:(pe who) - :: - [%snap-fleet lab=@tas] - =. fleet-snaps (~(put by fleet-snaps) lab.val piers) - this - :: - [%restore-fleet lab=@tas] - =^ ms this (poke-aqua-events [%restore-snap lab.val]~) - (emit-moves ms) :: [%clear-snap lab=@tas] =. fleet-snaps ~ :: (~(del by fleet-snaps) lab.val) @@ -656,63 +403,63 @@ ^- (quip move _this) =. this apex-aqua =< abet-aqua %+ turn-events events - |= [ovo=aqua-event thus=_this] + |= [ae=aqua-event thus=_this] =. this thus - ?- -.ovo + ?- -.ae %init-ship - =. this abet-pe:sleep:(pe who.ovo) + =. this abet-pe:(publish-effect:(pe who.ae) [/ %sleep ~]) =/ initted =< plow - %- push-events:apex:(pe who.ovo) + %- push-events:apex:(pe who.ae) ^- (list unix-event) :~ [/ %wack 0] :: eny - [/ %whom who.ovo] :: eny + [/ %whom who.ae] :: eny [//newt/0v1n.2m9vh %barn ~] [//behn/0v1n.2m9vh %born ~] :+ //term/1 %boot - ?~ keys.ovo - [%fake who.ovo] - [%dawn u.keys.ovo] + ?~ keys.ae + [%fake who.ae] + [%dawn u.keys.ae] -.userspace-ova.pil [//http/0v1n.2m9vh %born ~] [//http/0v1n.2m9vh %live 8.080 `8.445] == =. this abet-pe:initted - (pe who.ovo) + (pe who.ae) :: %pause-events - stop-processing-events:(pe who.ovo) + stop-processing-events:(pe who.ae) :: %snap-ships =. fleet-snaps - %+ ~(put by fleet-snaps) lab.ovo + %+ ~(put by fleet-snaps) lab.ae %- malt - %+ murn hers.ovo + %+ murn hers.ae |= her=ship ^- (unit (pair ship pier)) =+ per=(~(get by piers) her) ?~ per ~ `[her u.per] - (pe -.hers.ovo) + (pe -.hers.ae) :: %restore-snap =. this %+ turn-ships (turn ~(tap by piers) head) |= [who=ship thus=_this] =. this thus - sleep:(pe who) - =. piers (~(uni by piers) (~(got by fleet-snaps) lab.ovo)) + (publish-effect:(pe who) [/ %sleep ~]) + =. piers (~(uni by piers) (~(got by fleet-snaps) lab.ae)) =. this %+ turn-ships (turn ~(tap by piers) head) |= [who=ship thus=_this] =. this thus - restore:(pe who) + (publish-effect:(pe who) [/ %restore ~]) (pe ~bud) :: XX why ~bud? need an example :: %event - ~& ev=-.q.ovo.ovo - (push-events:(pe who.ovo) [ovo.ovo]~) + ~& ev=-.q.ue.ae + (push-events:(pe who.ae) [ue.ae]~) == :: :: Run a callback function against a list of ships, aggregating state @@ -747,90 +494,7 @@ ++ turn-ships (turn-plow ship) ++ turn-events (turn-plow aqua-event) :: -:: Send the same event to all ships -:: -++ blast-event - |= ovo=unix-event - =/ pers ~(tap by piers) - |- ^+ this - ?~ pers - this - =. this - abet-pe:(push-events:(pe p.i.pers) ~[ovo]) - $(pers t.pers) -:: -:: Restore ships -:: -++ restore-ships - |= [hers=(list ship) from=(map ship pier)] - =. this - %+ turn-ships hers - |= [who=ship thus=_this] - =. this thus - sleep:(pe who) - =. piers - %- ~(gas by piers) - %+ turn hers - |= her=ship - [her (~(got by from) her)] - =. this - %+ turn-ships hers - |= [who=ship thus=_this] - =. this thus - restore:(pe who) - this -:: -:: Restore ships from pier -:: -++ restore-ship - |= [her=ship per=pier] - =. this abet-pe:plow:sleep:(pe her) - =. piers (~(put by piers) her per) - =. this abet-pe:plow:restore:(pe her) - this -:: -:: Received timer wake -:: -++ wake - |= [way=wire ~] - ^- (quip move _this) - =. this apex-aqua =< abet-aqua - ?> ?=([@ *] way) - =/ who (,@p (slav %p i.way)) - %+ turn-ships ~[who] - |= [who=ship thus=_this] - =. this thus - (take-wake:(pe who) t.way ~) -:: -:: Received inbound HTTP response -:: -++ sigh-httr - |= [way=wire res=httr:eyre] - ^- (quip move _this) - =. this apex-aqua =< abet-aqua - ?> ?=([@ *] way) - =/ who (,@p (slav %p i.way)) - ~& [%received-httr who] - %+ turn-ships ~[who] - |= [who=ship thus=_this] - =. this thus - (take-sigh-httr:(pe who) t.way res) -:: -:: Received inbound HTTP response error -:: -++ sigh-tang - |= [way=wire tan=tang] - ^- (quip move _this) - =. this apex-aqua =< abet-aqua - ?> ?=([@ *] way) - =/ who (,@p (slav %p i.way)) - ~& [%received-httr who] - %+ turn-ships ~[who] - |= [who=ship thus=_this] - =. this thus - (take-sigh-tang:(pe who) t.way tan) -:: -:: Handle scry to aqua +:: Check whether we have a snapshot :: ++ peek-x-fleet-snap |= pax=path @@ -841,7 +505,7 @@ :^ ~ ~ %noun (~(has by fleet-snaps) i.pax) :: -:: +:: Pass scry into child ship :: ++ peek-x-i |= pax=path @@ -856,6 +520,16 @@ :^ ~ ~ %noun (peek:(pe who) [%cx pax]) :: +:: Get all created ships +:: +++ peek-x-ships + |= pax=path + ^- (unit (unit %noun (list ship))) + ?. ?=(~ pax) + ~ + :^ ~ ~ %noun + (turn ~(tap by piers) head) +:: :: Trivial scry for mock :: ++ scry |=([* *] ~) diff --git a/app/ph.hoon b/app/ph.hoon index 8da418eb2..87a50e0ed 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -14,22 +14,27 @@ => $~ |% +$ move (pair bone card) +$ card - $% [%poke wire dock %aqua-events (list aqua-event)] + $% [%poke wire dock poke-types] [%peer wire dock path] [%pull wire dock ~] == :: + +$ poke-types + $% [%aqua-events (list aqua-event)] + [%drum-start term term] + == + :: +$ state $: %0 - raw-test-cores=(map term test-core) + raw-test-cores=(map term raw-test-core) test-cores=(map term test-core-state) other-state == :: +$ test-core-state $: hers=(list ship) - cor=test-core - effect-log=(list [who=ship ovo=unix-effect]) + cor=raw-test-core + effect-log=(list [who=ship uf=unix-effect]) == :: +$ other-state @@ -47,9 +52,10 @@ ~& jael=.^(noun %j /(scot %p our.hid)/code/(scot %da now.hid)/(scot %p our.hid)) =, test-lib %- malt - ^- (list (pair term test-core)) + ^- (list (pair term raw-test-core)) :~ :- %add + ^- raw-test-core =+ num=5 |% ++ label %add @@ -65,14 +71,16 @@ == :: ++ route - |= [now=@da who=ship ovo=unix-effect] - ^- (quip ph-event _..start) + |= [now=@da who=ship uf=unix-effect] + ^- [? (quip ph-event _..start)] ~& [%num num] + :- ? :_ ..start - (expect-dojo-output ~bud who ovo "[%test-result 5]") + (expect-dojo-output ~bud who uf "[%test-result 5]") -- :: :- %hi + ^- raw-test-core |% ++ label %hi ++ ships ~[~bud ~dev] @@ -87,30 +95,29 @@ == :: ++ route - |= [now=@da who=ship ovo=unix-effect] - ^- (quip ph-event _..start) + |= [now=@da who=ship uf=unix-effect] + ^- [? (quip ph-event _..start)] + :- ? :_ ..start - (expect-dojo-output ~bud who ovo "hi ~dev successful") + (expect-dojo-output ~bud who uf "hi ~dev successful") -- :: [%headstart-bud (galaxy ~bud)] :: :- %composed-child-boot %+ compose-tests (planet ~linnup-torsyx) - ^- test-core + %+ porcelain-test %composed-child-boot |% - ++ label %composed-child-boot - ++ ships ~ ++ start |= now=@da [(dojo ~linnup-torsyx "|hi ~bud") ..start] :: ++ route - |= [now=@da who=ship ovo=unix-effect] + |= [now=@da who=ship uf=unix-effect] ^- (quip ph-event _..start) :_ ..start %- on-dojo-output - :^ ~linnup-torsyx who ovo + :^ ~linnup-torsyx who uf :- "hi ~bud successful" |= ~ [%test-done &]~ @@ -120,20 +127,19 @@ %+ compose-tests %+ compose-tests (planet ~mitnep-todsut) (planet ~haplun-todtus) - ^- test-core + %+ porcelain-test + %composed-child-boot-2 |% - ++ label %composed-child-boot-2 - ++ ships ~ ++ start |= now=@da [(dojo ~haplun-todtus "|hi ~bud") ..start] :: ++ route - |= [now=@da who=ship ovo=unix-effect] + |= [now=@da who=ship uf=unix-effect] ^- (quip ph-event _..start) :_ ..start %- on-dojo-output - :^ ~haplun-todtus who ovo + :^ ~haplun-todtus who uf :- "hi ~bud successful" |= ~ [%test-done &]~ @@ -158,10 +164,10 @@ :: %- assert-happens :: :~ :: == - *test-core + *raw-test-core :: :- %individual-breach - *test-core + *raw-test-core :: :: (init ~zod) :: (init ~marzod) @@ -188,6 +194,16 @@ `this `this(+<+>+> u.new) :: +++ publish-aqua-effects + |= afs=aqua-effects + ^- (list move) + %+ murn ~(tap by sup.hid) + |= [b=bone her=ship pax=path] + ^- (unit move) + ?. ?=([%effects ~] pax) + ~ + `[b %diff %aqua-effects ae] +:: ++ run-events |= [lab=term what=(list ph-event)] ^- (quip move _this) @@ -252,8 +268,19 @@ ~& %herm ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) + %init + :_ this + %- zing ^- (list (list move)) + %+ turn + ^- (list term) + ~[%aqua-ames %aqua-behn %aqua-dill %aqua-eyre] + |= vane-app=term + :~ [ost.hid %poke /start [our.hid %hood] %drum-start %home vane-app] + [ost.hid %poke /init [our.hid vane-app] %aqua-vane-control %subscribe] + == + :: [%run-test lab=@tas] - =/ res=[events=(list ph-event) new-state=test-core] + =/ res=[events=(list ph-event) new-state=raw-test-core] (start:(~(got by raw-test-cores) lab.arg) now.hid) =. test-cores (~(put by test-cores) lab.arg [ships . ~]:new-state.res) =^ moves-1 this (subscribe-to-effects lab.arg ships.new-state.res) @@ -264,38 +291,56 @@ =/ log effect-log:(~(got by test-cores) lab.arg) ~& lent=(lent log) ~& %+ roll log - |= [[who=ship ovo=unix-effect] ~] - ?: ?=(?(%blit %doze) -.q.ovo) + |= [[who=ship uf=unix-effect] ~] + ?: ?=(?(%blit %doze) -.q.uf) ~ - ?: ?=(%ergo -.q.ovo) - ~& [who [- +<]:ovo %omitted-by-ph] + ?: ?=(%ergo -.q.uf) + ~& [who [- +<]:uf %omitted-by-ph] ~ - ~& [who ovo] + ~& [who uf] ~ `this == :: ++ diff-aqua-effects - |= [way=wire ova=aqua-effects] + |= [way=wire afs=aqua-effects] ^- (quip move _this) - :: ~& [%diff-aqua-effect way who.ova] + :: ~& [%diff-aqua-effect way who.ae] ?> ?=([@tas @ ~] way) =/ lab i.way =/ test-cor (~(get by test-cores) lab) ?~ test-cor ~& [%ph-dropping lab] `this - =^ events u.test-cor - |- ^- (quip ph-event _u.test-cor) - ?~ ovo.ova - [~ u.test-cor] - =. effect-log.u.test-cor - [[who i.ovo]:ova effect-log.u.test-cor] - =^ events-1 cor.u.test-cor - (route:cor.u.test-cor now.hid who.ova i.ovo.ova) - =^ events-2 u.test-cor - $(ovo.ova t.ovo.ova) - [(weld events-1 events-2) u.test-cor] + =+ |- ^- $: thru-effects=(list unix-effects) + events=(list ph=event) + cor=_u.test-cor + == + ?~ ufs.ae + [~ ~ u.test-cor] + =. effect-log.u.test-cor + [[who i.ufs]:ae effect-log.u.test-cor] + =+ ^- [[thru=? events-1=(list ph-event)] cor=cor.u.test-cor] + (route:cor.u.test-cor now.hid who.ae i.ufs.ae) + =. cor.u.test-cor cor + =+ $(ufs.ae t.ufs.ae) + :+ ?: thru + [i.ufs.ae thru-effects] + thru-efects + (weld events-1 events) + cor + =. u.test=cor cor =. test-cores (~(put by test-cores) lab u.test-cor) + =^ moves this (publish-aqua-effects who.ae thru-effects) (run-events lab events) +:: +:: Subscribe to effects +:: +++ peer-effects + |= pax=path + ^- (quip move _this) + ?. ?=(~ pax) + ~& [%ph-bad-peer-effects pax] + `this + `this -- diff --git a/gen/aqua/dojo.hoon b/gen/aqua/dojo.hoon new file mode 100644 index 000000000..5d9fa23b0 --- /dev/null +++ b/gen/aqua/dojo.hoon @@ -0,0 +1,14 @@ +/- aquarium +=, aquarium +:- %say +|= [* [her=ship command=tape] ~] +:- %aqua-events +%+ turn + ^- (list unix-event) + :~ [//term/1 %belt %ctl `@c`%e] + [//term/1 %belt %ctl `@c`%u] + [//term/1 %belt %txt ((list @c) command)] + [//term/1 %belt %ret ~] + == +|= ue=unix-event +[%event her ue] diff --git a/gen/aqua/file.hoon b/gen/aqua/file.hoon new file mode 100644 index 000000000..bcc9d28a4 --- /dev/null +++ b/gen/aqua/file.hoon @@ -0,0 +1,8 @@ +/- aquarium +=, aquarium +:- %say +|= [* [her=ship pax=path] ~] +:- %aqua-events :_ ~ +:+ %event her +=/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] +[//sync/0v1n.2m9vh %into i.t.pax | [t.t.t.pax `file]~]~ diff --git a/gen/aqua/init.hoon b/gen/aqua/init.hoon new file mode 100644 index 000000000..4a47a73b7 --- /dev/null +++ b/gen/aqua/init.hoon @@ -0,0 +1,6 @@ +/- aquarium +=, aquarium +:- %say +|= [* [her=ship] ~] +:- %aqua-events +[%init-ship her ~]~ diff --git a/gen/aqua/raw-event.hoon b/gen/aqua/raw-event.hoon new file mode 100644 index 000000000..b6d53e65a --- /dev/null +++ b/gen/aqua/raw-event.hoon @@ -0,0 +1,6 @@ +/- aquarium +=, aquarium +:- %say +|= [* [her=ship ue=unix-event] ~] +:- %aqua-events +[%event her ue]~ diff --git a/gen/aqua/restore-fleet.hoon b/gen/aqua/restore-fleet.hoon new file mode 100644 index 000000000..3a38cdaee --- /dev/null +++ b/gen/aqua/restore-fleet.hoon @@ -0,0 +1,6 @@ +/- aquarium +=, aquarium +:- %say +|= [* [label=@ta] ~] +:- %aqua-events +[%snap-ships label]~ diff --git a/gen/aqua/snap-fleet.hoon b/gen/aqua/snap-fleet.hoon new file mode 100644 index 000000000..6fcdf0ab3 --- /dev/null +++ b/gen/aqua/snap-fleet.hoon @@ -0,0 +1,8 @@ +/- aquarium +=, aquarium +:- %say +|= [[now=@da eny=@uvJ bec=beak] [label=@ta] ships=(list ship)] +:- %aqua-events +=? ships ?=(~ ships) + .^((list ship) %gx /(scot %p p.bec)/aqua/(scot %da now)/ships/noun) +[%snap-ships label ships]~ diff --git a/lib/ph.hoon b/lib/ph.hoon index 17d727217..6cb86cd83 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -6,7 +6,7 @@ |% :: Defines a complete integration test. :: -++ test-core +++ raw-test-core $_ ^? |% :: @@ -27,6 +27,18 @@ :: :: Called on every effect from a ship. :: + ++ route |~([now=@da ship unix-effect] *[? (quip ph-event _^?(..start)])) + -- +:: +++ porcelain-test-core + $_ ^? + |% + :: Called first to kick off the test. + :: + ++ start |~(now=@da *(quip ph-event _^?(..start))) + :: + :: Called on every effect from a ship. + :: ++ route |~([now=@da ship unix-effect] *(quip ph-event _^?(..start))) -- :: @@ -35,12 +47,29 @@ aqua-event == :: +++ porcelain-test + |= [label=@ta porcelain=porcelain-test-core] + ^- raw-test-core + |% + ++ label ^label + ++ ships ~ + ++ start + |= now=@da + =^ events porcelain (start:porcelain now) + [events ..start] + :: + ++ route + |= args=[@da ship unix-effect] + =^ events porcelain (route:porcelain args) + [& events ..start] + -- +:: ++ send-events-to |= [who=ship what=(list unix-event)] ^- (list ph-event) %+ turn what - |= ovo=unix-event - [%event who ovo] + |= ue=unix-event + [%event who ue] :: ++ init |= [who=ship keys=(unit dawn-event)] @@ -72,13 +101,13 @@ == :: ++ on-dojo-output - |= [who=ship her=ship ovo=unix-effect what=tape fun=$-($~ (list ph-event))] + |= [who=ship her=ship uf=unix-effect what=tape fun=$-($~ (list ph-event))] ^- (list ph-event) ?. =(who her) ~ - ?. ?=(%blit -.q.ovo) + ?. ?=(%blit -.q.uf) ~ - ?. %+ lien p.q.ovo + ?. %+ lien p.q.uf |= =blit:dill ?. ?=(%lin -.blit) | @@ -87,19 +116,19 @@ (fun) :: ++ expect-dojo-output - |= [who=ship her=ship ovo=unix-effect what=tape] + |= [who=ship her=ship uf=unix-effect what=tape] ^- (list ph-event) %- on-dojo-output - :^ who her ovo + :^ who her uf :- what |= ~ [%test-done &]~ :: ++ on-ergo - |= [who=ship her=ship ovo=unix-effect fun=$-($~ (list ph-event))] + |= [who=ship her=ship uf=unix-effect fun=$-($~ (list ph-event))] ?. =(who her) ~ - ?. ?=(%ergo -.q.ovo) + ?. ?=(%ergo -.q.uf) ~ (fun) :: @@ -151,8 +180,8 @@ ++ test-lib |_ our=ship ++ compose-tests - |= [a=test-core b=test-core] - ^- test-core + |= [a=raw-test-core b=raw-test-core] + ^- raw-test-core =/ done-with-a | => |% @@ -208,14 +237,18 @@ :: like that. :: ++ route - |= [now=@da who=ship ovo=unix-effect] - ^- (quip ph-event _..start) + |= [now=@da who=ship uf=unix-effect] + ^- [? (quip ph-event _..start)] ?: done-with-a - =^ events b (route:b now who ovo) - [events ..start] - =^ events a (route:a now who ovo) + =+ ^- [thru=? events=(list ph-event) cor=raw-test-core] + (route:b now who uf) + =. b cor + [thru events ..start] + =+ ^- [thru=? events=(list ph-event) cor=raw-test-core] + (route:a now who uf) + =. a cor =^ events ..filter-a (filter-a now events) - [events ..start] + [thru events ..start] -- :: :: Don't use directly, or else you might not have a parent. @@ -224,7 +257,7 @@ :: ++ raw-ship |= [her=ship keys=(unit dawn-event)] - ^- test-core + ^- raw-test-core |% ++ label :((cury cat 3) 'init-' (scot %p her) '-' (scot %uw (mug (fall keys *dawn-event)))) ++ ships ~[her] @@ -234,8 +267,9 @@ [(init her keys) ..start] :: ++ route - |= [now=@da who=ship ovo=unix-effect] - ^- (quip ph-event _..start) + |= [now=@da who=ship uf=unix-effect] + ^- [? (quip ph-event _..start)] + :- & :_ ..start %- zing :: This is a pretty bad heuristic, but in general galaxies will @@ -244,13 +278,13 @@ :: :~ %- on-dojo-output - :^ her who ovo + :^ her who uf :- "+ /{(scow %p her)}/base/2/web/testing/udon" |= ~ [%test-done &]~ :: %- on-dojo-output - :^ her who ovo + :^ her who uf :- "is your neighbor" |= ~ [%test-done &]~ @@ -291,11 +325,10 @@ :: ++ touch-file |= [her=ship des=desk] - ^- test-core + %+ porcelain-test + (cat 3 'touch-file-' (scot %p her)) =| warped=@t |% - ++ label (cat 3 'touch-file-' (scot %p her)) - ++ ships ~ ++ start |= now=@da ^- (pair (list ph-event) _..start) @@ -309,12 +342,12 @@ == :: ++ route - |= [now=@da who=ship ovo=unix-effect] + |= [now=@da who=ship uf=unix-effect] ^- (quip ph-event _..start) :_ ..start %- zing :~ %- on-ergo - :^ her who ovo + :^ her who uf |= $~ =/ pax /i/(scot %p her)/[des]/(scot %da now)/sur/aquarium/hoon/noun ?: =(warped (need (scry-aqua (unit @) now pax))) @@ -330,10 +363,9 @@ :: ++ check-file-touched |= [her=ship des=desk] - ^- test-core + %+ porcelain-test + (cat 3 'check-file-touched-' (scot %p her)) |% - ++ label (cat 3 'check-file-touched-' (scot %p her)) - ++ ships ~ ++ start |= now=@da :: mounting is not strictly necessary since we check via scry, @@ -345,7 +377,7 @@ [(dojo her "|mount /={(trip des)}=") ..start] :: ++ route - |= [now=@da who=ship ovo=unix-effect] + |= [now=@da who=ship uf=unix-effect] ^- (quip ph-event _..start) =/ cb |= $~ @@ -364,8 +396,8 @@ ~ :_ ..start %- zing - :~ (on-ergo her who ovo cb) - (on-dojo-output her who ovo ">=" cb) + :~ (on-ergo her who uf cb) + (on-dojo-output her who uf ">=" cb) == -- :: @@ -375,10 +407,9 @@ :: ++ reload-vane |= [her=ship vane=term] - ^- test-core + %+ porcelain-test + :((cury cat 3) 'reload-vane-' (scot %p her) '-' vane) |% - ++ label :((cury cat 3) 'reload-vane-' (scot %p her) '-' vane) - ++ ships ~ ++ start |= now=@da ^- (pair (list ph-event) _..start) @@ -392,7 +423,7 @@ == :: ++ route - |= [now=@da who=ship ovo=unix-effect] + |= [now=@da who=ship uf=unix-effect] ^- (quip ph-event _..start) `..start -- diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index bfec9f638..bed8f3a97 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -1,27 +1,40 @@ +:: +:: Traditionally, ovo refers an event or card, and ova refers to a list +:: of them. We have several versions of each of these depending on +:: context, so we do away with that naming scheme and use the following +:: naming scheme. +:: +:: Every card is either a an `event` or an `effect`. Prepended to this +:: is `unix` if it has no ship associated with it, or `aqua` if it +:: does. `timed` is added if it includes the time of the event. +:: +:: Short names are simply the first letter of each word plus `s` if +:: it's a list. +:: |% +$ aqua-event $% [%init-ship who=ship keys=(unit dawn-event)] [%pause-events who=ship] [%snap-ships lab=term hers=(list ship)] [%restore-snap lab=term] - [%event who=ship ovo=unix-event] + [%event who=ship ue=unix-event] == :: +$ aqua-effects - [who=ship ovo=(list unix-effect)] + [who=ship ufs=(list unix-effect)] :: +$ aqua-events - [who=ship ovo=(list unix-timed-event)] + [who=ship utes=(list unix-timed-event)] :: +$ aqua-boths - [who=ship ovo=(list unix-both)] + [who=ship ub=(list unix-both)] :: +$ unix-both $% [%event unix-timed-event] [%effect unix-effect] == :: -+$ unix-timed-event [tym=@da ovo=unix-event] ++$ unix-timed-event [tym=@da ue=unix-event] :: +$ unix-event %+ pair wire @@ -40,6 +53,8 @@ [%doze p=(unit @da)] [%thus p=@ud q=(unit hiss:eyre)] [%ergo p=@tas q=mode:clay] + [%sleep ~] + [%restore ~] == +$ pill [boot-ova=* kernel-ova=(list unix-event) userspace-ova=(list unix-event)] @@ -53,4 +68,29 @@ node=(unit purl:eyre) snap=(unit snapshot:jael) == +:: ++$ vane-card + $% [%peer wire dock path] + [%pull wire dock ~] + == +:: +++ aqua-vane-control-handler + |= subscribed=? + |= command=?(%subscribe %unsubscribe) + ^- (list vane-cards) + ?- command + %subscribe + %+ weld + ^- (list vane-card) + ?. subscribed + ~ + [%pull /aqua [our %ph]]~ + ^- (list vane-card) + [%peer /aqua [our %ph] /effects]~ + :: + %unsubscribe + ?. subscribed + ~ + [%pull /aqua [our %ph]]~ + -- -- From b1d114066bb8a4613547d0ec420fac6e9092d224 Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 8 Mar 2019 00:34:01 +0100 Subject: [PATCH 039/133] Fix Ethereum ABI encoding for the %bytes data type Don't encode it like you do %bytes-n, which limits length to 32 bytes. --- sys/zuse.hoon | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/zuse.hoon b/sys/zuse.hoon index fbc14e3ca..c59236c99 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -7713,6 +7713,7 @@ :: enc(X) is the sequence of bytes in X padded with zero-bytes to a :: length of 32. :: Note that for any X, len(enc(X)) is a multiple of 32. + ~| [%bytes-n-too-long max=32 actual=p.p.dat] ?> (lte p.p.dat 32) (pad-to-multiple (render-hex-bytes p.dat) 64 %right) :: @@ -7722,7 +7723,7 @@ :: by the minimum number of zero-bytes such that len(enc(X)) is a :: multiple of 32. %+ weld $(dat [%uint p.p.dat]) - $(dat [%bytes-n p.dat]) + (pad-to-multiple (render-hex-bytes p.dat) 64 %right) :: %string :: enc(X) = enc(enc_utf8(X)), i.e. X is utf-8 encoded and this value is From 84f34412108915fa760c146feda5ac0f73ed2ce8 Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 8 Mar 2019 00:46:54 +0100 Subject: [PATCH 040/133] Refactor Ethereum ABI decoding logic to do less busywork ++decode-arguments now takes already-parsed words, rather than a @t of words, so that we operate on straight atom values instead of hex strings. For the ++decode-topics case, we no longer re-string and un-string the input data prior to processing. --- sys/zuse.hoon | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/sys/zuse.hoon b/sys/zuse.hoon index c59236c99..af14f9f3d 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -7755,23 +7755,19 @@ :: :: decoding :: - ++ decode-topics - :: tox: list of hex words - |* [tox=(lest @ux) tys=(list etyp)] - =- (decode-arguments (crip -) tys) - %+ roll `(list @ux)`tox - |= [top=@ tos=tape] - (weld tos (render-hex-bytes 32 top)) + ++ decode-topics decode-arguments :: ++ decode-results :: rex: string of hex bytes with leading 0x. |* [rex=@t tys=(list etyp)] - (decode-arguments (rsh 3 2 rex) tys) + =- (decode-arguments - tys) + %+ turn (rip 9 (rsh 3 2 rex)) + (curr rash hex) :: ++ decode-arguments - |* [res=@t tys=(list etyp)] + |* [wos=(list @) tys=(list etyp)] + =/ wos=(list @) wos :: get rid of tmi =| win=@ud - =/ wos=(list @t) (rip 9 res) =< (decode-from 0 tys) |% ++ decode-from @@ -7796,22 +7792,21 @@ ?(%address %bool %uint) :: %int %real %ureal :- +(win) ?- typ - %address `@ux`(rash wor hex) - %uint `@ud`(rash wor hex) - %bool =(1 (rash wor hex)) + %address `@ux`wor + %uint `@ud`wor + %bool =(1 wor) == :: %string =+ $(tys ~[%bytes]) - ~! - [nin (trip (swp 3 q.dat))] :: %bytes :- +(win) :: find the word index of the actual data. - =/ lic=@ud (div (rash wor hex) 32) + =/ lic=@ud (div wor 32) :: learn the bytelength of the data. - =/ len=@ud (rash (snag lic wos) hex) + =/ len=@ud (snag lic wos) (decode-bytes-n +(lic) len) :: [%bytes-n *] @@ -7821,11 +7816,11 @@ [%array *] :- +(win) :: find the word index of the actual data. - =. win (div (rash wor hex) 32) + =. win (div wor 32) :: read the elements from their location. %- tail %^ decode-array-n ~[t.typ] +(win) - (rash (snag win wos) hex) + (snag win wos) :: [%array-n *] (decode-array-n ~[t.typ] win n.typ) @@ -7835,18 +7830,16 @@ |= [fro=@ud bys=@ud] ^- octs :: parse {bys} bytes from {fro}. - =- [bys (rash - hex)] - %^ end 3 (mul 2 bys) - %+ can 9 - %+ turn - (swag [fro +((div (dec bys) 32))] wos) - |=(a=@t [1 a]) + :- bys + %^ rsh 3 (sub 32 (mod bys 33)) + %+ rep 8 + (flop (swag [fro +((div (dec bys) 32))] wos)) :: ++ decode-array-n ::NOTE we take (list etyp) even though we only operate on :: a single etyp as a workaround for urbit/arvo#673 + ::NOTE careful! produces lists without type info =| res=(list) - ~& %watch-out--arrays-without-typeinfo |* [tys=(list etyp) fro=@ud len=@ud] ^- [@ud (list)] ?~ tys !! From ae8966e5adbda93810f3b9572c93afaacb243049 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 7 Mar 2019 21:15:42 -0800 Subject: [PATCH 041/133] compiles --- app/aqua-ames.hoon | 11 ++++++----- app/aqua-behn.hoon | 28 +++++++++++++++++----------- app/aqua-dill.hoon | 16 ++++++++-------- app/aqua-eyre.hoon | 45 +++++++++++++++++++++++++++------------------ app/aqua.hoon | 10 +++++----- app/ph.hoon | 45 ++++++++++++++++++++++++++------------------- lib/ph.hoon | 2 +- sur/aquarium.hoon | 20 ++++++++++---------- 8 files changed, 100 insertions(+), 77 deletions(-) diff --git a/app/aqua-ames.hoon b/app/aqua-ames.hoon index 97265440d..cb9e86c28 100644 --- a/app/aqua-ames.hoon +++ b/app/aqua-ames.hoon @@ -35,12 +35,12 @@ ++ emit-aqua-events |= aes=(list aqua-event) %- emit-moves - [%poke /aqua-events [our %aqua] %aqua-events aes]~ + [ost %poke /aqua-events [our %aqua] %aqua-events aes]~ :: ++ poke-aqua-vane-control |= command=?(%subscribe %unsubscribe) - :_ this(subscribed =(command %subscribe) - (aqua-vane-control-handler subscribed) + :_ this(subscribed =(command %subscribe)) + (aqua-vane-control-handler our ost subscribed command) :: ++ diff-aqua-effects |= [way=wire afs=aqua-effects] @@ -51,12 +51,13 @@ this =. this ?+ -.q.i.ufs.afs this - %restore handle-restore + %restore (handle-restore who.afs) %send (handle-send i.ufs.afs) - -- + == $(ufs.afs t.ufs.afs) :: ++ handle-restore + |= who=@p %- emit-aqua-events [%event who [//newt/0v1n.2m9vh %barn ~]]~ :: diff --git a/app/aqua-behn.hoon b/app/aqua-behn.hoon index b8005a30e..8c8c71b68 100644 --- a/app/aqua-behn.hoon +++ b/app/aqua-behn.hoon @@ -13,8 +13,10 @@ +$ state $: %0 subscribed=_| - piers=(map ship next-timer=(unit @da)) + piers=(map ship pier) == + :: + +$ pier next-timer=(unit @da) -- =, gall =| moves=(list move) @@ -31,12 +33,12 @@ ++ emit-aqua-events |= aes=(list aqua-event) %- emit-moves - [%poke /aqua-events [our %aqua] %aqua-events aes]~ + [ost %poke /aqua-events [our %aqua] %aqua-events aes]~ :: ++ poke-aqua-vane-control |= command=?(%subscribe %unsubscribe) - :_ this(subscribed =(command %subscribe) - (aqua-vane-control-handler subscribed) + :_ this(subscribed =(command %subscribe)) + (aqua-vane-control-handler our ost subscribed command) :: ++ diff-aqua-effects |= [way=wire afs=aqua-effects] @@ -50,7 +52,7 @@ %sleep abet-pe:handle-sleep:(pe who.afs) %restore abet-pe:handle-restore:(pe who.afs) %doze abet-pe:(handle-doze:(pe who.afs) i.ufs.afs) - -- + == $(ufs.afs t.ufs.afs) :: :: Received timer wake @@ -82,15 +84,17 @@ :: ++ handle-restore ^+ ..abet-pe - %- emit-aqua-events - [%event who [//behn/0v1n.2m9vh %born ~]]~ + =. this + %- emit-aqua-events + [%event who [//behn/0v1n.2m9vh %born ~]]~ + ..abet-pe :: ++ handle-doze |= [way=wire %doze tim=(unit @da)] ^+ ..abet-pe ?~ tim ?~ next-timer - this + ..abet-pe cancel-timer ?~ next-timer (set-timer u.tim) @@ -101,16 +105,18 @@ =. tim +(tim) :: nobody's perfect ~& [who=who %setting-timer tim] =. next-timer `tim - (emit-moves [ost.hid %wait /(scot %p who) tim]~) + =. this (emit-moves [ost %wait /(scot %p who) tim]~) + ..abet-pe :: ++ cancel-timer ~& [who=who %cancell-timer (need next-timer)] =. next-timer ~ - (emit-moves [ost.hid %rest /(scot %p who) (need next-timer)]~) + =. this (emit-moves [ost %rest /(scot %p who) (need next-timer)]~) + ..abet-pe :: ++ take-wake |= [way=wire ~] - ~& [who=who %aqua-behn-wake now.hid] + ~& [who=who %aqua-behn-wake now] =. next-timer ~ =. this %- emit-aqua-events diff --git a/app/aqua-dill.hoon b/app/aqua-dill.hoon index c01be9754..4286b942c 100644 --- a/app/aqua-dill.hoon +++ b/app/aqua-dill.hoon @@ -37,12 +37,12 @@ ++ emit-aqua-events |= aes=(list aqua-event) %- emit-moves - [%poke /aqua-events [our %aqua] %aqua-events aes]~ + [ost %poke /aqua-events [our %aqua] %aqua-events aes]~ :: ++ poke-aqua-vane-control |= command=?(%subscribe %unsubscribe) - :_ this(subscribed =(command %subscribe) - (aqua-vane-control-handler subscribed) + :_ this(subscribed =(command %subscribe)) + (aqua-vane-control-handler our ost subscribed command) :: ++ diff-aqua-effects |= [way=wire afs=aqua-effects] @@ -53,13 +53,13 @@ this =. this ?+ -.q.i.ufs.afs this - %blit (handle-blit i.ufs.afs) - -- + %blit (handle-blit who.afs i.ufs.afs) + == $(ufs.afs t.ufs.afs) :: ++ handle-blit - |= [way=wire %blit blits=(list blit:dill)] - ^+ ..abet-pe + |= [who=@p way=wire %blit blits=(list blit:dill)] + ^+ this =/ last-line %+ roll blits |= [b=blit:dill line=tape] @@ -74,5 +74,5 @@ %url ~& [%activate-url p.b] line == ~& last-line - ..abet-pe + this -- diff --git a/app/aqua-eyre.hoon b/app/aqua-eyre.hoon index 653a7aecf..cc87ea667 100644 --- a/app/aqua-eyre.hoon +++ b/app/aqua-eyre.hoon @@ -14,8 +14,10 @@ +$ state $: %0 subscribed=_| - piers=(map ship http-requests=(set @ud)) + piers=(map ship pier) == + :: + +$ pier http-requests=(set @ud) -- =, gall =| moves=(list move) @@ -32,12 +34,12 @@ ++ emit-aqua-events |= aes=(list aqua-event) %- emit-moves - [%poke /aqua-events [our %aqua] %aqua-events aes]~ + [ost %poke /aqua-events [our %aqua] %aqua-events aes]~ :: ++ poke-aqua-vane-control |= command=?(%subscribe %unsubscribe) - :_ this(subscribed =(command %subscribe) - (aqua-vane-control-handler subscribed) + :_ this(subscribed =(command %subscribe)) + (aqua-vane-control-handler our ost subscribed command) :: ++ diff-aqua-effects |= [way=wire afs=aqua-effects] @@ -51,7 +53,7 @@ %sleep abet-pe:handle-sleep:(pe who.afs) %restore abet-pe:handle-restore:(pe who.afs) %thus abet-pe:(handle-thus:(pe who.afs) i.ufs.afs) - -- + == $(ufs.afs t.ufs.afs) :: :: Received inbound HTTP response @@ -59,7 +61,7 @@ ++ sigh-httr |= [way=wire res=httr:eyre] ^- (quip move _this) - =. this apex-aqua =< abet-aqua + =. this apex =< abet ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] @@ -70,7 +72,7 @@ ++ sigh-tang |= [way=wire tan=tang] ^- (quip move _this) - =. this apex-aqua =< abet-aqua + =. this apex =< abet ?> ?=([@ *] way) =/ who (,@p (slav %p i.way)) ~& [%received-httr who] @@ -92,8 +94,10 @@ :: ++ handle-restore ^+ ..abet-pe - %- emit-aqua-events - [%event who [//http/0v1n.2m9vh %born ~]]~ + =. this + %- emit-aqua-events + [%event who [//http/0v1n.2m9vh %born ~]]~ + ..abet-pe :: ++ handle-thus |= [way=wire %thus num=@ud req=(unit hiss:eyre)] @@ -110,14 +114,16 @@ ..abet-pe ~& [who=who %aqua-eyre-requesting u.req] =. http-requests (~(put in http-requests) num) - %- emit-moves :_ ~ - :* ost.hid - %hiss - /(scot %p who)/(scot %ud num) - ~ - %httr - [%hiss u.req] - == + =. this + %- emit-moves :_ ~ + :* ost + %hiss + /(scot %p who)/(scot %ud num) + ~ + %httr + [%hiss u.req] + == + ..abet-pe :: :: Pass HTTP response back to virtual ship :: @@ -130,7 +136,9 @@ ~& [who=who %ignoring-httr num=num] ..abet-pe =. http-requests (~(del in http-requests) num) - (emit-aqua-events [%event who [//http/0v1n.2m9vh %they num res]~) + =. this + (emit-aqua-events [%event who [//http/0v1n.2m9vh %they num res]]~) + ..abet-pe :: :: Got error in HTTP response :: @@ -145,4 +153,5 @@ =. http-requests (~(del in http-requests) num) %- (slog tan) ..abet-pe + -- -- diff --git a/app/aqua.hoon b/app/aqua.hoon index 4c6e01ccd..84c9e7494 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -92,9 +92,9 @@ :: Enqueue events to child arvo :: ++ push-events - |= ova=(list unix-event) + |= ues=(list unix-event) ^+ ..abet-pe - =. next-events (~(gas to next-events) ova) + =. next-events (~(gas to next-events) ues) ..abet-pe :: :: Send moves to host arvo @@ -271,7 +271,7 @@ ++ peer-effects |= pax=path ^- (quip move _this) - ?: ?=([@ @ *] pax) + ?. ?=([@ *] pax) ~& [%aqua-bad-peer-effects pax] `this ?~ (slaw %p i.pax) @@ -524,11 +524,11 @@ :: ++ peek-x-ships |= pax=path - ^- (unit (unit %noun (list ship))) + ^- (unit (unit [%noun (list ship)])) ?. ?=(~ pax) ~ :^ ~ ~ %noun - (turn ~(tap by piers) head) + `(list ship)`(turn ~(tap by piers) head) :: :: Trivial scry for mock :: diff --git a/app/ph.hoon b/app/ph.hoon index 87a50e0ed..c79055a79 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -14,14 +14,20 @@ => $~ |% +$ move (pair bone card) +$ card - $% [%poke wire dock poke-types] + $% [%poke wire dock poke-type] [%peer wire dock path] [%pull wire dock ~] + [%diff diff-type] == :: - +$ poke-types + +$ poke-type $% [%aqua-events (list aqua-event)] [%drum-start term term] + [%aqua-vane-control ?(%subscribe %unsubscribe)] + == + :: + +$ diff-type + $% [%aqua-effects aqua-effects] == :: +$ state @@ -74,7 +80,7 @@ |= [now=@da who=ship uf=unix-effect] ^- [? (quip ph-event _..start)] ~& [%num num] - :- ? + :- & :_ ..start (expect-dojo-output ~bud who uf "[%test-result 5]") -- @@ -97,7 +103,7 @@ ++ route |= [now=@da who=ship uf=unix-effect] ^- [? (quip ph-event _..start)] - :- ? + :- & :_ ..start (expect-dojo-output ~bud who uf "hi ~dev successful") -- @@ -106,7 +112,7 @@ :: :- %composed-child-boot %+ compose-tests (planet ~linnup-torsyx) - %+ porcelain-test %composed-child-boot + %+ porcelain-test %composed-child-boot |% ++ start |= now=@da @@ -202,7 +208,7 @@ ^- (unit move) ?. ?=([%effects ~] pax) ~ - `[b %diff %aqua-effects ae] + `[ost.hid %diff %aqua-effects afs] :: ++ run-events |= [lab=term what=(list ph-event)] @@ -305,34 +311,35 @@ ++ diff-aqua-effects |= [way=wire afs=aqua-effects] ^- (quip move _this) - :: ~& [%diff-aqua-effect way who.ae] + :: ~& [%diff-aqua-effect way who.afs] ?> ?=([@tas @ ~] way) =/ lab i.way =/ test-cor (~(get by test-cores) lab) ?~ test-cor ~& [%ph-dropping lab] `this - =+ |- ^- $: thru-effects=(list unix-effects) - events=(list ph=event) + =+ |- ^- $: thru-effects=(list unix-effect) + events=(list ph-event) cor=_u.test-cor == - ?~ ufs.ae + ?~ ufs.afs [~ ~ u.test-cor] =. effect-log.u.test-cor - [[who i.ufs]:ae effect-log.u.test-cor] - =+ ^- [[thru=? events-1=(list ph-event)] cor=cor.u.test-cor] - (route:cor.u.test-cor now.hid who.ae i.ufs.ae) + [[who i.ufs]:afs effect-log.u.test-cor] + =+ ^- [thru=? events-1=(list ph-event) cor=_cor.u.test-cor] + (route:cor.u.test-cor now.hid who.afs i.ufs.afs) =. cor.u.test-cor cor - =+ $(ufs.ae t.ufs.ae) + =+ $(ufs.afs t.ufs.afs) :+ ?: thru - [i.ufs.ae thru-effects] - thru-efects + [i.ufs.afs thru-effects] + thru-effects (weld events-1 events) cor - =. u.test=cor cor + =. u.test-cor cor =. test-cores (~(put by test-cores) lab u.test-cor) - =^ moves this (publish-aqua-effects who.ae thru-effects) - (run-events lab events) + =/ moves-1 (publish-aqua-effects who.afs thru-effects) + =^ moves-2 this (run-events lab events) + [(weld moves-1 moves-2) this] :: :: Subscribe to effects :: diff --git a/lib/ph.hoon b/lib/ph.hoon index 6cb86cd83..c4d3bcfb4 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -27,7 +27,7 @@ :: :: Called on every effect from a ship. :: - ++ route |~([now=@da ship unix-effect] *[? (quip ph-event _^?(..start)])) + ++ route |~([now=@da ship unix-effect] *[? (quip ph-event _^?(..start))]) -- :: ++ porcelain-test-core diff --git a/sur/aquarium.hoon b/sur/aquarium.hoon index bed8f3a97..3d04cd5e1 100644 --- a/sur/aquarium.hoon +++ b/sur/aquarium.hoon @@ -69,28 +69,28 @@ snap=(unit snapshot:jael) == :: -+$ vane-card ++$ vane-move + %+ pair bone $% [%peer wire dock path] [%pull wire dock ~] == :: ++ aqua-vane-control-handler - |= subscribed=? - |= command=?(%subscribe %unsubscribe) - ^- (list vane-cards) + |= [our=@p ost=bone subscribed=? command=?(%subscribe %unsubscribe)] + ^- (list vane-move) ?- command %subscribe %+ weld - ^- (list vane-card) + ^- (list vane-move) ?. subscribed ~ - [%pull /aqua [our %ph]]~ - ^- (list vane-card) - [%peer /aqua [our %ph] /effects]~ + [ost %pull /aqua [our %ph] ~]~ + ^- (list vane-move) + [ost %peer /aqua [our %ph] /effects]~ :: %unsubscribe ?. subscribed ~ - [%pull /aqua [our %ph]]~ - -- + [ost %pull /aqua [our %ph] ~]~ + == -- From e2619830945faab9ee206e2d0cc8783428d208ff Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 7 Mar 2019 21:27:07 -0800 Subject: [PATCH 042/133] clean up printfs --- sys/arvo.hoon | 2 +- sys/vane/clay.hoon | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/sys/arvo.hoon b/sys/arvo.hoon index 10b548506..a9e85ba03 100644 --- a/sys/arvo.hoon +++ b/sys/arvo.hoon @@ -644,7 +644,7 @@ :: =/ pit=vase !>(..is) :: =/ vil=vile (viol p.pit) :: cached reflexives -=| $: lac=_| :: laconic bit +=| $: lac=_& :: laconic bit eny=@ :: entropy our=ship :: identity bud=vase :: %zuse diff --git a/sys/vane/clay.hoon b/sys/vane/clay.hoon index 053653e77..53505c1f6 100644 --- a/sys/vane/clay.hoon +++ b/sys/vane/clay.hoon @@ -1171,7 +1171,6 @@ ?~ hat +>.$ wake:(print-changes:(checkout-ankh u.hat) wen lem) - ~& [%edit our hen] ?. =(~ dok) ~& %already-applying-changes +> :: @@ -2376,7 +2375,6 @@ ++ apply-changes :: apply-changes:ze |= lar/(list {p/path q/misu}) :: store changes ^- (map path blob) - ~& [%apply-changes our hen] =+ ^= hat :: current state ?: =(let.dom 0) :: initial commit ~ :: has nothing @@ -4250,11 +4248,11 @@ =/ queued-duct=duct -.queued =/ queued-task=task:able +.queued :: - ~& :* %x-clay-waking - queued-duct - hen - ?~(cue.ruf /empty -:(need ~(top to cue.ruf))) - == + :: ~& :* %x-clay-waking + :: queued-duct + :: hen + :: ?~(cue.ruf /empty -:(need ~(top to cue.ruf))) + :: == ~| [%mismatched-ducts %queued queued-duct %timer hen] ?> =(hen queued-duct) :: From 187aff92797b0a679cd5ee5fefd2e6b65120947a Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Thu, 7 Mar 2019 22:28:10 -0800 Subject: [PATCH 043/133] working after rearchitecture --- app/aqua-behn.hoon | 2 +- app/aqua.hoon | 8 ++++---- app/ph.hoon | 10 +++------- lib/ph.hoon | 14 +++++++------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/app/aqua-behn.hoon b/app/aqua-behn.hoon index 8c8c71b68..d483acb88 100644 --- a/app/aqua-behn.hoon +++ b/app/aqua-behn.hoon @@ -110,8 +110,8 @@ :: ++ cancel-timer ~& [who=who %cancell-timer (need next-timer)] - =. next-timer ~ =. this (emit-moves [ost %rest /(scot %p who) (need next-timer)]~) + =. next-timer ~ ..abet-pe :: ++ take-wake diff --git a/app/aqua.hoon b/app/aqua.hoon index 84c9e7494..94a81f798 100644 --- a/app/aqua.hoon +++ b/app/aqua.hoon @@ -218,27 +218,27 @@ =/ ufs (~(get ja unix-effects) who) ?~ ufs ~ - [b %diff %aqua-effects who ufs]~ + [b %diff %aqua-effects who (flop ufs)]~ :: [%effects ~] %+ turn ~(tap by unix-effects) |= [who=ship ufs=(list unix-effect)] - [b %diff %aqua-effects who ufs] + [b %diff %aqua-effects who (flop ufs)] :: [%events @ ~] =/ who (slav %p i.t.pax) =/ ve (~(get ja unix-events) who) ?~ ve ~ - [b %diff %aqua-events who ve]~ + [b %diff %aqua-events who (flop ve)]~ :: [%boths @ ~] =/ who (slav %p i.t.pax) =/ bo (~(get ja unix-boths) who) ?~ bo ~ - [b %diff %aqua-boths who bo]~ + [b %diff %aqua-boths who (flop bo)]~ == [(flop moves) this] :: diff --git a/app/ph.hoon b/app/ph.hoon index c79055a79..1ddee8e3f 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -62,14 +62,12 @@ :~ :- %add ^- raw-test-core - =+ num=5 |% ++ label %add ++ ships ~[~bud] ++ start |= now=@da ^- (pair (list ph-event) _..start) - =. num +(num) :_ ..start %- zing :~ (init ~bud ~) @@ -79,7 +77,6 @@ ++ route |= [now=@da who=ship uf=unix-effect] ^- [? (quip ph-event _..start)] - ~& [%num num] :- & :_ ..start (expect-dojo-output ~bud who uf "[%test-result 5]") @@ -208,7 +205,7 @@ ^- (unit move) ?. ?=([%effects ~] pax) ~ - `[ost.hid %diff %aqua-effects afs] + `[b %diff %aqua-effects afs] :: ++ run-events |= [lab=term what=(list ph-event)] @@ -220,7 +217,7 @@ ?~ what [%& ~] ?: ?=(%test-done -.i.what) - ~& ?~(p.i.what "test successful" "test failed") + ~& ?~(p.i.what "TEST SUCCESSFUL" "TEST FAILED") [%| ~] =/ nex $(what t.what) ?: ?=(%| -.nex) @@ -271,7 +268,6 @@ :: ++ poke-noun |= arg=* - ~& %herm ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) %init @@ -279,7 +275,7 @@ %- zing ^- (list (list move)) %+ turn ^- (list term) - ~[%aqua-ames %aqua-behn %aqua-dill %aqua-eyre] + ~[%aqua %aqua-ames %aqua-behn %aqua-dill %aqua-eyre] |= vane-app=term :~ [ost.hid %poke /start [our.hid %hood] %drum-start %home vane-app] [ost.hid %poke /init [our.hid vane-app] %aqua-vane-control %subscribe] diff --git a/lib/ph.hoon b/lib/ph.hoon index c4d3bcfb4..1def470a6 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -219,13 +219,13 @@ ^- (quip ph-event _..start) =/ have-cache (scry-aqua ? now /fleet-snap/[label:a]/noun) - ?: have-cache - ~& [%caching-in label:a label] - =. done-with-a & - =/ restore-event [%restore-snap label:a] - =^ events-start b (start:b now) - =^ events ..filter-a (filter-a now restore-event events-start) - [events ..start] + :: ?: have-cache + :: ~& [%caching-in label:a label] + :: =. done-with-a & + :: =/ restore-event [%restore-snap label:a] + :: =^ events-start b (start:b now) + :: =^ events ..filter-a (filter-a now restore-event events-start) + :: [events ..start] =^ events a (start:a now) [events ..start] :: From e029ce1e44af298712d8a942dd4f343006c20572 Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 8 Mar 2019 12:44:10 +0100 Subject: [PATCH 044/133] Fix off-by-ones in Ethereum ABI en/decoding logic --- sys/zuse.hoon | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/zuse.hoon b/sys/zuse.hoon index af14f9f3d..caf849407 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -7831,9 +7831,13 @@ ^- octs :: parse {bys} bytes from {fro}. :- bys - %^ rsh 3 (sub 32 (mod bys 33)) + %^ rsh 3 + =+ (mod bys 32) + ?:(=(0 -) - (sub 32 -)) %+ rep 8 - (flop (swag [fro +((div (dec bys) 32))] wos)) + %- flop + =- (swag [fro -] wos) + +((div (dec bys) 32)) :: ++ decode-array-n ::NOTE we take (list etyp) even though we only operate on @@ -8214,8 +8218,10 @@ |= [wat=tape mof=@ud wer=?(%left %right)] ^- tape =+ len=(lent wat) - ?: =(len mof) wat - =+ tad=(reap (sub mof (mod len mof)) '0') + ?: =(0 len) (reap mof '0') + =+ mad=(mod len mof) + ?: =(0 mad) wat + =+ tad=(reap (sub mof mad) '0') %- weld ?:(?=(%left wer) [tad wat] [wat tad]) :: From c2c2b04b0b96bd2c1be5cf2b71992dbb4341a520 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Fri, 8 Mar 2019 13:48:09 -0800 Subject: [PATCH 045/133] better init for ph --- app/ph.hoon | 41 +++++++++++++++++++++++++++++++---------- lib/ph.hoon | 3 ++- sys/vane/gall.hoon | 3 +-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/ph.hoon b/app/ph.hoon index 1ddee8e3f..a570df6da 100644 --- a/app/ph.hoon +++ b/app/ph.hoon @@ -47,6 +47,8 @@ $~ -- =, gall +=/ vane-apps=(list term) + ~[%aqua %aqua-ames %aqua-behn %aqua-dill %aqua-eyre] |_ $: hid=bowl state == @@ -266,20 +268,37 @@ /effects/(scot %p her) == :: +:: Start the vane drivers +:: +++ init-vanes + ^- (list move) + %+ murn + `(list term)`[%aqua vane-apps] + |= vane-app=term + ^- (unit move) + =/ app-started + .^(? %gu /(scot %p our.hid)/[vane-app]/(scot %da now.hid)) + ?: app-started + ~ + `[ost.hid %poke /start [our.hid %hood] %drum-start %home vane-app] +:: +:: Restart the vane drivers' subscriptions +:: +++ subscribe-vanes + ^- (list move) + %+ turn + vane-apps + |= vane-app=term + [ost.hid %poke /init [our.hid vane-app] %aqua-vane-control %subscribe] +:: +:: User interface +:: ++ poke-noun |= arg=* ^- (quip move _this) ?+ arg ~|(%bad-noun-arg !!) %init - :_ this - %- zing ^- (list (list move)) - %+ turn - ^- (list term) - ~[%aqua %aqua-ames %aqua-behn %aqua-dill %aqua-eyre] - |= vane-app=term - :~ [ost.hid %poke /start [our.hid %hood] %drum-start %home vane-app] - [ost.hid %poke /init [our.hid vane-app] %aqua-vane-control %subscribe] - == + [init-vanes this] :: [%run-test lab=@tas] =/ res=[events=(list ph-event) new-state=raw-test-core] @@ -287,7 +306,7 @@ =. test-cores (~(put by test-cores) lab.arg [ships . ~]:new-state.res) =^ moves-1 this (subscribe-to-effects lab.arg ships.new-state.res) =^ moves-2 this (run-events lab.arg events.res) - [(weld moves-1 moves-2) this] + [:(weld init-vanes subscribe-vanes moves-1 moves-2) this] :: [%print lab=@tas] =/ log effect-log:(~(got by test-cores) lab.arg) @@ -304,6 +323,8 @@ `this == :: +:: Receive effects back from aqua +:: ++ diff-aqua-effects |= [way=wire afs=aqua-effects] ^- (quip move _this) diff --git a/lib/ph.hoon b/lib/ph.hoon index 1def470a6..19ac2634b 100644 --- a/lib/ph.hoon +++ b/lib/ph.hoon @@ -337,7 +337,8 @@ =. warped (cat 3 '=> . ' .^(@t %cx pax)) :_ ..start %- zing - :~ (dojo her "|mount /={(trip des)}=") + :~ (dojo her "|verb") + (dojo her "|mount /={(trip des)}=") (insert-file her des pax warped) == :: diff --git a/sys/vane/gall.hoon b/sys/vane/gall.hoon index a8b0fc749..39cccb205 100644 --- a/sys/vane/gall.hoon +++ b/sys/vane/gall.hoon @@ -1363,9 +1363,8 @@ =(~ tyl) =([%$ %da now] lot) =(our his) - (~(has by bum.mast.all) syd) == - ``[%null !>(~)] + ``[%noun !>((~(has by bum.mast.all) syd))] ?. =(our his) ~ ?. =([%$ %da now] lot) From fe9648ea9be971b80e446e18424e9397d702c337 Mon Sep 17 00:00:00 2001 From: Isaac Visintainer Date: Tue, 12 Mar 2019 15:15:20 -0700 Subject: [PATCH 046/133] landscape: 1fcdc49935e6b1361270eb054611f06f765d5965 --- lib/landscape.hoon | 2 +- web/landscape/css/index.css | 2 +- web/landscape/js/index-min.js | 2 +- web/landscape/js/index.js | 83033 -------------------------- web/landscape/profile.hoon | 10 +- web/landscape/profile/settings.hoon | 4 +- 6 files changed, 10 insertions(+), 83043 deletions(-) delete mode 100644 web/landscape/js/index.js diff --git a/lib/landscape.hoon b/lib/landscape.hoon index 2969a0fa5..b36bcff72 100644 --- a/lib/landscape.hoon +++ b/lib/landscape.hoon @@ -15,7 +15,7 @@ ;div#root ;+ inner == - ;script@"/~~/landscape/js/index.js"; + ;script@"/~~/landscape/js/index-min.js"; == :: == diff --git a/web/landscape/css/index.css b/web/landscape/css/index.css index ca4831d0c..b18b3e056 100644 --- a/web/landscape/css/index.css +++ b/web/landscape/css/index.css @@ -1,2 +1,2 @@ @charset "UTF-8"; -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}[class*=col-]{width:100%;margin-bottom:1rem}.container{margin:0 auto;padding:0 2rem;max-width:960px}.row{display:flex}.flex,.row{flex-wrap:wrap}.align-vertical{align-items:center}.justify-center{justify-content:center}@media only screen and (min-width:0){.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-offset-0,.col-sm-offset-1,.col-sm-offset-2,.col-sm-offset-3,.col-sm-offset-4,.col-sm-offset-5,.col-sm-offset-6,.col-sm-offset-7,.col-sm-offset-8,.col-sm-offset-9,.col-sm-offset-10,.col-sm-offset-11,.col-sm-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-sm{flex-grow:1;flex-basis:0;max-width:100%}.col-sm-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-sm-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-sm-3{flex-basis:25%;max-width:25%}.col-sm-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-sm-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-sm-6{flex-basis:50%;max-width:50%}.col-sm-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-sm-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-sm-9{flex-basis:75%;max-width:75%}.col-sm-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-sm-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-sm-12{flex-basis:100%;max-width:100%}.col-sm-offset-0{margin-left:0}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-11{margin-left:91.66666667%}}@media only screen and (min-width:480px){.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-offset-0,.col-md-offset-1,.col-md-offset-2,.col-md-offset-3,.col-md-offset-4,.col-md-offset-5,.col-md-offset-6,.col-md-offset-7,.col-md-offset-8,.col-md-offset-9,.col-md-offset-10,.col-md-offset-11,.col-md-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-md{flex-grow:1;flex-basis:0;max-width:100%}.col-md-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-md-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-md-3{flex-basis:25%;max-width:25%}.col-md-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-md-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-md-6{flex-basis:50%;max-width:50%}.col-md-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-md-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-md-9{flex-basis:75%;max-width:75%}.col-md-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-md-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-md-12{flex-basis:100%;max-width:100%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-11{margin-left:91.66666667%}}@media only screen and (min-width:960px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-offset-0,.col-lg-offset-1,.col-lg-offset-2,.col-lg-offset-3,.col-lg-offset-4,.col-lg-offset-5,.col-lg-offset-6,.col-lg-offset-7,.col-lg-offset-8,.col-lg-offset-9,.col-lg-offset-10,.col-lg-offset-11,.col-lg-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-lg{flex-grow:1;flex-basis:0;max-width:100%}.col-lg-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-lg-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-lg-3{flex-basis:25%;max-width:25%}.col-lg-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-lg-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-lg-6{flex-basis:50%;max-width:50%}.col-lg-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-lg-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-lg-9{flex-basis:75%;max-width:75%}.col-lg-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-lg-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-lg-12{flex-basis:100%;max-width:100%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-11{margin-left:91.66666667%}}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Thin.ttf) format("truetype");font-weight:100}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-ExtraLight.ttf) format("truetype");font-weight:200}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Light.ttf) format("truetype");font-weight:300}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Regular.ttf) format("truetype");font-weight:400}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Medium.ttf) format("truetype");font-weight:500}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-SemiBold.ttf) format("truetype");font-weight:600}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Bold.ttf) format("truetype");font-weight:700}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-ExtraBold.ttf) format("truetype");font-weight:800}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Black.ttf) format("truetype");font-weight:900}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-extralight.woff);font-weight:200}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-light.woff);font-weight:300}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-regular.woff);font-weight:400}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-medium.woff);font-weight:500}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-semibold.woff);font-weight:600}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-bold.woff);font-weight:700}*{font-smoothing:antialiased;-webkit-font-smoothing:antialiased}body{font-family:-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;font-size:4rem;line-height:6rem;color:#373a3c}a{color:#000}p{margin:0 0 2rem}.text-heading,h1,h2,h3,h4,h5{margin:0;font-family:Work Sans;color:#373a3c}.h1,h1{font-size:12rem;line-height:16rem;margin:4rem 0}.h1,.h2,h1,h2{font-weight:600}.h2,h2{font-size:9rem;line-height:13rem;margin:3rem 0}.h3,h3{font-size:6rem;font-weight:600;line-height:8rem;margin:2rem 0}.h4,h4{font-weight:600}.h4,.h5,h4,h5{font-size:5rem;line-height:7rem;margin:1rem 0}.h5,h5{font-weight:500}.text-sm,caption{font-size:3rem;line-height:5rem}.text-md{font-size:4rem;line-height:6rem}.text-lg{font-size:5rem;line-height:7rem}code,pre{background-color:#f1f1f1;padding:1rem}.text-code,.text-mono,code,pre{font-family:Source Code Pro,Roboto mono,Courier New,monospace}.text-code{color:#000}.code-block,.text-code{background-color:#f1f1f1}.code-block{padding:5rem;white-space:pre-wrap}.code-block .text-code{font-weight:200}.underline,u{text-decoration:underline}.strikethrough,s{text-decoration:line-through}.italic,em{font-style:italic}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.text-300{font-weight:300}.text-400{font-weight:400}.text-500{font-weight:500}.text-600{font-weight:600}.text-700,b{font-weight:700}.text-800{font-weight:800}.h-font{font-family:Work Sans}.blue{color:#4330fc}.green{color:#6fdc74}.red{color:#ee3124}.gray-lighter{color:#f1f1f1}.gray-light{color:#d4d4d4}.gray{color:#5b5b5b}.gray-dark{color:#373a3c}.blue-hl{background-color:#4330fc;color:#fff}.green-hl{background-color:#6fdc74;color:#fff}.red-hl{background-color:#ee3124;color:#fff}.gray-lighter-hl{background-color:#f1f1f1;color:#fff}.gray-light-hl{background-color:#d4d4d4;color:#fff}.gray-hl{background-color:#5b5b5b;color:#fff}.gray-dark-hl{background-color:#373a3c;color:#fff}.black-hl{background-color:#000;color:#fff}.center{text-align:center}.right{text-align:right}.justify{text-align:justify}button{border:none;outline:none}.btn,button{font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;font-size:4rem;line-height:4rem;padding:3rem 6rem;color:#000;background-color:#d4d4d4;margin:0 0 6px}.btn-sm{font-size:3rem;line-height:3rem;padding:2rem 4rem}.btn-primary{color:#fff}.btn-tetiary{background-color:#5b5b5b;color:#fff}.btn-warning{background-color:#ee3124;color:#fff}.btn-group .btn{display:inline-block}.btn-group .btn:not(.active){background-color:#d4d4d4;color:#000}label{display:block;font-weight:700}input[type=text],textarea{border:2px solid #000;padding:12px;width:100%}.error-label{display:none;color:#f44;font-size:2.33rem;line-height:3rem;margin-top:1rem}.input-group{margin:0 0 2rem}.input-group.error input[type=text],.input-group.error textarea{border:.5rem solid #f44}.input-group.error .error-label{display:block}.checkbox-group input,.checkbox-group label,.radio-group input,.radio-group label{font-weight:400;display:inline-block}.select-dropdown{display:flex;border:2px solid #000;overflow:hidden;background-color:#fff}.select-dropdown select{padding:5px 8px;width:130%;border:none;box-shadow:none;background:transparent;background-image:none;-webkit-appearance:none}.select-dropdown select:focus{outline:none}.select-dropdown .triangle-down{border-width:2rem 1rem 0;position:relative;top:14px;right:8px}.icon-arrow-right:before{content:"→"}.icon-arrow-left:before{content:"←"}.icon-arrow-up:before{content:"↑"}.icon-arrow-down:before{content:"↓"}.icon-cross:before{content:"×"}.icon-ellipsis:before{content:"...";position:relative;bottom:6px}.selected:before{content:"∙"}.icon{margin-right:.6rem}.icon.prev{width:1px;height:1px;border:12.0006px solid transparent;border-right:18px solid #000;border-left:0 solid transparent}.icon.next{border:12.0006px solid transparent;border-left:18px solid #000;border-right:0 solid transparent;margin-right:0}.icon.next,.icon.up{width:1px;height:1px}.icon.up{border:12.0006px solid transparent;border-bottom:18px solid #000;border-top:0 solid transparent}.circle{display:inline-block;padding:2rem;border-radius:50%;border:2px solid #000;text-align:center}.circle-sm{padding:1rem}.circle-lg{padding:4rem}.circle-fill{background-color:#000}.circle-red{background-color:#ee3124;border-color:#ee3124}.circle-blue{background-color:#4330fc;border-color:#4330fc}.circle-blue-light{background-color:#a4d8e8;border-color:#a4d8e8}.circle-yellow{background-color:#ffc440;border-color:#ffc440}.circle-green{background-color:#6fdc74;border-color:#6fdc74}.circle-gray{background-color:#5b5b5b;border-color:#5b5b5b}.circle-gray-light{background-color:#d4d4d4;border-color:#d4d4d4}.circle-gray-lighter{background-color:#f1f1f1;border-color:#f1f1f1}.circle-gray-dark{background-color:#373a3c;border-color:#373a3c}.circle-pill{border-radius:9999px;width:10rem}.circle-pill.circle-lg{width:20rem}.square{display:inline-block;padding:2rem;border:2px solid #000;text-align:center}.square-sm{padding:1rem}.square-lg{padding:4rem}.square-fill{background-color:#000}.square-red{background-color:red;border-color:red}.square-rect{width:10rem}.square-rect.square-lg{width:20rem}.triangle-base{display:inline-block;width:0;height:0}.triangle-up{border-bottom:4rem solid #000}.triangle-down,.triangle-up{border-left:2rem solid transparent;border-right:2rem solid transparent}.triangle-down{border-top:4rem solid #000}.triangle-right{border-left:4rem solid #000}.triangle-left,.triangle-right{border-top:2rem solid transparent;border-bottom:2rem solid transparent}.triangle-left{border-right:4rem solid #000}.urbit-logo{width:72px;height:72px;border-radius:50%;border:5px solid #fff;background-color:transparent}.urbit-logo,.urbit-logo:before{display:inline-block;vertical-align:middle}.urbit-logo:before{content:"~";color:#fff;font-size:72px;line-height:54px;text-align:center;width:2rem;font-family:Work Sans;font-weight:600;margin-right:30px;margin-top:3px}.urbit-logo-solid{border-color:#000}.urbit-logo-solid:before{color:#000}section{margin:0 0 2rem;border:none}blockquote{border-left:6px solid #000;margin:24px 0;padding-left:18px}hr{margin:4rem 0;width:100%;height:1rem;border:0;background-color:#373a3c}ul{padding-left:4rem;list-style:disc outside}ul li{margin-bottom:2rem;padding-left:2rem}ol ul,ul ol,ul ul{margin:2rem}ol ul li,ul ol li,ul ul li{margin-bottom:1rem}ul.list-reset{list-style:none}ol,ul.list-reset,ul.list-reset li{padding-left:0}ol{list-style:none}ol>li{counter-increment:a;margin-left:0;margin-bottom:1rem}ol>li:before{content:counter(a);font-weight:700;vertical-align:center;display:inline-block;width:6rem;text-align:left}.w-0{width:0!important}.h-0{height:0!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mr-0{margin-right:0!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.pr-0{padding-right:0!important}.w-1{width:1rem!important}.h-1{height:1rem!important}.m-1{margin:1rem!important}.mt-1{margin-top:1rem!important}.mb-1{margin-bottom:1rem!important}.ml-1{margin-left:1rem!important}.mr-1{margin-right:1rem!important}.p-1{padding:1rem!important}.pt-1{padding-top:1rem!important}.pb-1{padding-bottom:1rem!important}.pl-1{padding-left:1rem!important}.pr-1{padding-right:1rem!important}.w-2{width:2rem!important}.h-2{height:2rem!important}.m-2{margin:2rem!important}.mt-2{margin-top:2rem!important}.mb-2{margin-bottom:2rem!important}.ml-2{margin-left:2rem!important}.mr-2{margin-right:2rem!important}.p-2{padding:2rem!important}.pt-2{padding-top:2rem!important}.pb-2{padding-bottom:2rem!important}.pl-2{padding-left:2rem!important}.pr-2{padding-right:2rem!important}.w-3{width:3rem!important}.h-3{height:3rem!important}.m-3{margin:3rem!important}.mt-3{margin-top:3rem!important}.mb-3{margin-bottom:3rem!important}.ml-3{margin-left:3rem!important}.mr-3{margin-right:3rem!important}.p-3{padding:3rem!important}.pt-3{padding-top:3rem!important}.pb-3{padding-bottom:3rem!important}.pl-3{padding-left:3rem!important}.pr-3{padding-right:3rem!important}.w-4{width:4rem!important}.h-4{height:4rem!important}.m-4{margin:4rem!important}.mt-4{margin-top:4rem!important}.mb-4{margin-bottom:4rem!important}.ml-4{margin-left:4rem!important}.mr-4{margin-right:4rem!important}.p-4{padding:4rem!important}.pt-4{padding-top:4rem!important}.pb-4{padding-bottom:4rem!important}.pl-4{padding-left:4rem!important}.pr-4{padding-right:4rem!important}.w-5{width:5rem!important}.h-5{height:5rem!important}.m-5{margin:5rem!important}.mt-5{margin-top:5rem!important}.mb-5{margin-bottom:5rem!important}.ml-5{margin-left:5rem!important}.mr-5{margin-right:5rem!important}.p-5{padding:5rem!important}.pt-5{padding-top:5rem!important}.pb-5{padding-bottom:5rem!important}.pl-5{padding-left:5rem!important}.pr-5{padding-right:5rem!important}.w-6{width:6rem!important}.h-6{height:6rem!important}.m-6{margin:6rem!important}.mt-6{margin-top:6rem!important}.mb-6{margin-bottom:6rem!important}.ml-6{margin-left:6rem!important}.mr-6{margin-right:6rem!important}.p-6{padding:6rem!important}.pt-6{padding-top:6rem!important}.pb-6{padding-bottom:6rem!important}.pl-6{padding-left:6rem!important}.pr-6{padding-right:6rem!important}.w-7{width:7rem!important}.h-7{height:7rem!important}.m-7{margin:7rem!important}.mt-7{margin-top:7rem!important}.mb-7{margin-bottom:7rem!important}.ml-7{margin-left:7rem!important}.mr-7{margin-right:7rem!important}.p-7{padding:7rem!important}.pt-7{padding-top:7rem!important}.pb-7{padding-bottom:7rem!important}.pl-7{padding-left:7rem!important}.pr-7{padding-right:7rem!important}.w-8{width:8rem!important}.h-8{height:8rem!important}.m-8{margin:8rem!important}.mt-8{margin-top:8rem!important}.mb-8{margin-bottom:8rem!important}.ml-8{margin-left:8rem!important}.mr-8{margin-right:8rem!important}.p-8{padding:8rem!important}.pt-8{padding-top:8rem!important}.pb-8{padding-bottom:8rem!important}.pl-8{padding-left:8rem!important}.pr-8{padding-right:8rem!important}.w-9{width:9rem!important}.h-9{height:9rem!important}.m-9{margin:9rem!important}.mt-9{margin-top:9rem!important}.mb-9{margin-bottom:9rem!important}.ml-9{margin-left:9rem!important}.mr-9{margin-right:9rem!important}.p-9{padding:9rem!important}.pt-9{padding-top:9rem!important}.pb-9{padding-bottom:9rem!important}.pl-9{padding-left:9rem!important}.pr-9{padding-right:9rem!important}.w-10{width:10rem!important}.h-10{height:10rem!important}.m-10{margin:10rem!important}.mt-10{margin-top:10rem!important}.mb-10{margin-bottom:10rem!important}.ml-10{margin-left:10rem!important}.mr-10{margin-right:10rem!important}.p-10{padding:10rem!important}.pt-10{padding-top:10rem!important}.pb-10{padding-bottom:10rem!important}.pl-10{padding-left:10rem!important}.pr-10{padding-right:10rem!important}.w-11{width:11rem!important}.h-11{height:11rem!important}.m-11{margin:11rem!important}.mt-11{margin-top:11rem!important}.mb-11{margin-bottom:11rem!important}.ml-11{margin-left:11rem!important}.mr-11{margin-right:11rem!important}.p-11{padding:11rem!important}.pt-11{padding-top:11rem!important}.pb-11{padding-bottom:11rem!important}.pl-11{padding-left:11rem!important}.pr-11{padding-right:11rem!important}.w-12{width:12rem!important}.h-12{height:12rem!important}.m-12{margin:12rem!important}.mt-12{margin-top:12rem!important}.mb-12{margin-bottom:12rem!important}.ml-12{margin-left:12rem!important}.mr-12{margin-right:12rem!important}.p-12{padding:12rem!important}.pt-12{padding-top:12rem!important}.pb-12{padding-bottom:12rem!important}.pl-12{padding-left:12rem!important}.pr-12{padding-right:12rem!important}.w-13{width:13rem!important}.h-13{height:13rem!important}.m-13{margin:13rem!important}.mt-13{margin-top:13rem!important}.mb-13{margin-bottom:13rem!important}.ml-13{margin-left:13rem!important}.mr-13{margin-right:13rem!important}.p-13{padding:13rem!important}.pt-13{padding-top:13rem!important}.pb-13{padding-bottom:13rem!important}.pl-13{padding-left:13rem!important}.pr-13{padding-right:13rem!important}.w-14{width:14rem!important}.h-14{height:14rem!important}.m-14{margin:14rem!important}.mt-14{margin-top:14rem!important}.mb-14{margin-bottom:14rem!important}.ml-14{margin-left:14rem!important}.mr-14{margin-right:14rem!important}.p-14{padding:14rem!important}.pt-14{padding-top:14rem!important}.pb-14{padding-bottom:14rem!important}.pl-14{padding-left:14rem!important}.pr-14{padding-right:14rem!important}.w-15{width:15rem!important}.h-15{height:15rem!important}.m-15{margin:15rem!important}.mt-15{margin-top:15rem!important}.mb-15{margin-bottom:15rem!important}.ml-15{margin-left:15rem!important}.mr-15{margin-right:15rem!important}.p-15{padding:15rem!important}.pt-15{padding-top:15rem!important}.pb-15{padding-bottom:15rem!important}.pl-15{padding-left:15rem!important}.pr-15{padding-right:15rem!important}.w-16{width:16rem!important}.h-16{height:16rem!important}.m-16{margin:16rem!important}.mt-16{margin-top:16rem!important}.mb-16{margin-bottom:16rem!important}.ml-16{margin-left:16rem!important}.mr-16{margin-right:16rem!important}.p-16{padding:16rem!important}.pt-16{padding-top:16rem!important}.pb-16{padding-bottom:16rem!important}.pl-16{padding-left:16rem!important}.pr-16{padding-right:16rem!important}.w-17{width:17rem!important}.h-17{height:17rem!important}.m-17{margin:17rem!important}.mt-17{margin-top:17rem!important}.mb-17{margin-bottom:17rem!important}.ml-17{margin-left:17rem!important}.mr-17{margin-right:17rem!important}.p-17{padding:17rem!important}.pt-17{padding-top:17rem!important}.pb-17{padding-bottom:17rem!important}.pl-17{padding-left:17rem!important}.pr-17{padding-right:17rem!important}.w-18{width:18rem!important}.h-18{height:18rem!important}.m-18{margin:18rem!important}.mt-18{margin-top:18rem!important}.mb-18{margin-bottom:18rem!important}.ml-18{margin-left:18rem!important}.mr-18{margin-right:18rem!important}.p-18{padding:18rem!important}.pt-18{padding-top:18rem!important}.pb-18{padding-bottom:18rem!important}.pl-18{padding-left:18rem!important}.pr-18{padding-right:18rem!important}.w-19{width:19rem!important}.h-19{height:19rem!important}.m-19{margin:19rem!important}.mt-19{margin-top:19rem!important}.mb-19{margin-bottom:19rem!important}.ml-19{margin-left:19rem!important}.mr-19{margin-right:19rem!important}.p-19{padding:19rem!important}.pt-19{padding-top:19rem!important}.pb-19{padding-bottom:19rem!important}.pl-19{padding-left:19rem!important}.pr-19{padding-right:19rem!important}.w-20{width:20rem!important}.h-20{height:20rem!important}.m-20{margin:20rem!important}.mt-20{margin-top:20rem!important}.mb-20{margin-bottom:20rem!important}.ml-20{margin-left:20rem!important}.mr-20{margin-right:20rem!important}.p-20{padding:20rem!important}.pt-20{padding-top:20rem!important}.pb-20{padding-bottom:20rem!important}.pl-20{padding-left:20rem!important}.pr-20{padding-right:20rem!important}.w-21{width:21rem!important}.h-21{height:21rem!important}.m-21{margin:21rem!important}.mt-21{margin-top:21rem!important}.mb-21{margin-bottom:21rem!important}.ml-21{margin-left:21rem!important}.mr-21{margin-right:21rem!important}.p-21{padding:21rem!important}.pt-21{padding-top:21rem!important}.pb-21{padding-bottom:21rem!important}.pl-21{padding-left:21rem!important}.pr-21{padding-right:21rem!important}.w-22{width:22rem!important}.h-22{height:22rem!important}.m-22{margin:22rem!important}.mt-22{margin-top:22rem!important}.mb-22{margin-bottom:22rem!important}.ml-22{margin-left:22rem!important}.mr-22{margin-right:22rem!important}.p-22{padding:22rem!important}.pt-22{padding-top:22rem!important}.pb-22{padding-bottom:22rem!important}.pl-22{padding-left:22rem!important}.pr-22{padding-right:22rem!important}.w-23{width:23rem!important}.h-23{height:23rem!important}.m-23{margin:23rem!important}.mt-23{margin-top:23rem!important}.mb-23{margin-bottom:23rem!important}.ml-23{margin-left:23rem!important}.mr-23{margin-right:23rem!important}.p-23{padding:23rem!important}.pt-23{padding-top:23rem!important}.pb-23{padding-bottom:23rem!important}.pl-23{padding-left:23rem!important}.pr-23{padding-right:23rem!important}.w-24{width:24rem!important}.h-24{height:24rem!important}.m-24{margin:24rem!important}.mt-24{margin-top:24rem!important}.mb-24{margin-bottom:24rem!important}.ml-24{margin-left:24rem!important}.mr-24{margin-right:24rem!important}.p-24{padding:24rem!important}.pt-24{padding-top:24rem!important}.pb-24{padding-bottom:24rem!important}.pl-24{padding-left:24rem!important}.pr-24{padding-right:24rem!important}.w-25{width:25rem!important}.h-25{height:25rem!important}.m-25{margin:25rem!important}.mt-25{margin-top:25rem!important}.mb-25{margin-bottom:25rem!important}.ml-25{margin-left:25rem!important}.mr-25{margin-right:25rem!important}.p-25{padding:25rem!important}.pt-25{padding-top:25rem!important}.pb-25{padding-bottom:25rem!important}.pl-25{padding-left:25rem!important}.pr-25{padding-right:25rem!important}.w-26{width:26rem!important}.h-26{height:26rem!important}.m-26{margin:26rem!important}.mt-26{margin-top:26rem!important}.mb-26{margin-bottom:26rem!important}.ml-26{margin-left:26rem!important}.mr-26{margin-right:26rem!important}.p-26{padding:26rem!important}.pt-26{padding-top:26rem!important}.pb-26{padding-bottom:26rem!important}.pl-26{padding-left:26rem!important}.pr-26{padding-right:26rem!important}.w-27{width:27rem!important}.h-27{height:27rem!important}.m-27{margin:27rem!important}.mt-27{margin-top:27rem!important}.mb-27{margin-bottom:27rem!important}.ml-27{margin-left:27rem!important}.mr-27{margin-right:27rem!important}.p-27{padding:27rem!important}.pt-27{padding-top:27rem!important}.pb-27{padding-bottom:27rem!important}.pl-27{padding-left:27rem!important}.pr-27{padding-right:27rem!important}.w-28{width:28rem!important}.h-28{height:28rem!important}.m-28{margin:28rem!important}.mt-28{margin-top:28rem!important}.mb-28{margin-bottom:28rem!important}.ml-28{margin-left:28rem!important}.mr-28{margin-right:28rem!important}.p-28{padding:28rem!important}.pt-28{padding-top:28rem!important}.pb-28{padding-bottom:28rem!important}.pl-28{padding-left:28rem!important}.pr-28{padding-right:28rem!important}.w-29{width:29rem!important}.h-29{height:29rem!important}.m-29{margin:29rem!important}.mt-29{margin-top:29rem!important}.mb-29{margin-bottom:29rem!important}.ml-29{margin-left:29rem!important}.mr-29{margin-right:29rem!important}.p-29{padding:29rem!important}.pt-29{padding-top:29rem!important}.pb-29{padding-bottom:29rem!important}.pl-29{padding-left:29rem!important}.pr-29{padding-right:29rem!important}.w-30{width:30rem!important}.h-30{height:30rem!important}.m-30{margin:30rem!important}.mt-30{margin-top:30rem!important}.mb-30{margin-bottom:30rem!important}.ml-30{margin-left:30rem!important}.mr-30{margin-right:30rem!important}.p-30{padding:30rem!important}.pt-30{padding-top:30rem!important}.pb-30{padding-bottom:30rem!important}.pl-30{padding-left:30rem!important}.pr-30{padding-right:30rem!important}.w-31{width:31rem!important}.h-31{height:31rem!important}.m-31{margin:31rem!important}.mt-31{margin-top:31rem!important}.mb-31{margin-bottom:31rem!important}.ml-31{margin-left:31rem!important}.mr-31{margin-right:31rem!important}.p-31{padding:31rem!important}.pt-31{padding-top:31rem!important}.pb-31{padding-bottom:31rem!important}.pl-31{padding-left:31rem!important}.pr-31{padding-right:31rem!important}.w-32{width:32rem!important}.h-32{height:32rem!important}.m-32{margin:32rem!important}.mt-32{margin-top:32rem!important}.mb-32{margin-bottom:32rem!important}.ml-32{margin-left:32rem!important}.mr-32{margin-right:32rem!important}.p-32{padding:32rem!important}.pt-32{padding-top:32rem!important}.pb-32{padding-bottom:32rem!important}.pl-32{padding-left:32rem!important}.pr-32{padding-right:32rem!important}.w-33{width:33rem!important}.h-33{height:33rem!important}.m-33{margin:33rem!important}.mt-33{margin-top:33rem!important}.mb-33{margin-bottom:33rem!important}.ml-33{margin-left:33rem!important}.mr-33{margin-right:33rem!important}.p-33{padding:33rem!important}.pt-33{padding-top:33rem!important}.pb-33{padding-bottom:33rem!important}.pl-33{padding-left:33rem!important}.pr-33{padding-right:33rem!important}.w-34{width:34rem!important}.h-34{height:34rem!important}.m-34{margin:34rem!important}.mt-34{margin-top:34rem!important}.mb-34{margin-bottom:34rem!important}.ml-34{margin-left:34rem!important}.mr-34{margin-right:34rem!important}.p-34{padding:34rem!important}.pt-34{padding-top:34rem!important}.pb-34{padding-bottom:34rem!important}.pl-34{padding-left:34rem!important}.pr-34{padding-right:34rem!important}.w-35{width:35rem!important}.h-35{height:35rem!important}.m-35{margin:35rem!important}.mt-35{margin-top:35rem!important}.mb-35{margin-bottom:35rem!important}.ml-35{margin-left:35rem!important}.mr-35{margin-right:35rem!important}.p-35{padding:35rem!important}.pt-35{padding-top:35rem!important}.pb-35{padding-bottom:35rem!important}.pl-35{padding-left:35rem!important}.pr-35{padding-right:35rem!important}.w-36{width:36rem!important}.h-36{height:36rem!important}.m-36{margin:36rem!important}.mt-36{margin-top:36rem!important}.mb-36{margin-bottom:36rem!important}.ml-36{margin-left:36rem!important}.mr-36{margin-right:36rem!important}.p-36{padding:36rem!important}.pt-36{padding-top:36rem!important}.pb-36{padding-bottom:36rem!important}.pl-36{padding-left:36rem!important}.pr-36{padding-right:36rem!important}.w-37{width:37rem!important}.h-37{height:37rem!important}.m-37{margin:37rem!important}.mt-37{margin-top:37rem!important}.mb-37{margin-bottom:37rem!important}.ml-37{margin-left:37rem!important}.mr-37{margin-right:37rem!important}.p-37{padding:37rem!important}.pt-37{padding-top:37rem!important}.pb-37{padding-bottom:37rem!important}.pl-37{padding-left:37rem!important}.pr-37{padding-right:37rem!important}.w-38{width:38rem!important}.h-38{height:38rem!important}.m-38{margin:38rem!important}.mt-38{margin-top:38rem!important}.mb-38{margin-bottom:38rem!important}.ml-38{margin-left:38rem!important}.mr-38{margin-right:38rem!important}.p-38{padding:38rem!important}.pt-38{padding-top:38rem!important}.pb-38{padding-bottom:38rem!important}.pl-38{padding-left:38rem!important}.pr-38{padding-right:38rem!important}.w-39{width:39rem!important}.h-39{height:39rem!important}.m-39{margin:39rem!important}.mt-39{margin-top:39rem!important}.mb-39{margin-bottom:39rem!important}.ml-39{margin-left:39rem!important}.mr-39{margin-right:39rem!important}.p-39{padding:39rem!important}.pt-39{padding-top:39rem!important}.pb-39{padding-bottom:39rem!important}.pl-39{padding-left:39rem!important}.pr-39{padding-right:39rem!important}.w-40{width:40rem!important}.h-40{height:40rem!important}.m-40{margin:40rem!important}.mt-40{margin-top:40rem!important}.mb-40{margin-bottom:40rem!important}.ml-40{margin-left:40rem!important}.mr-40{margin-right:40rem!important}.p-40{padding:40rem!important}.pt-40{padding-top:40rem!important}.pb-40{padding-bottom:40rem!important}.pl-40{padding-left:40rem!important}.pr-40{padding-right:40rem!important}.w-41{width:41rem!important}.h-41{height:41rem!important}.m-41{margin:41rem!important}.mt-41{margin-top:41rem!important}.mb-41{margin-bottom:41rem!important}.ml-41{margin-left:41rem!important}.mr-41{margin-right:41rem!important}.p-41{padding:41rem!important}.pt-41{padding-top:41rem!important}.pb-41{padding-bottom:41rem!important}.pl-41{padding-left:41rem!important}.pr-41{padding-right:41rem!important}.w-42{width:42rem!important}.h-42{height:42rem!important}.m-42{margin:42rem!important}.mt-42{margin-top:42rem!important}.mb-42{margin-bottom:42rem!important}.ml-42{margin-left:42rem!important}.mr-42{margin-right:42rem!important}.p-42{padding:42rem!important}.pt-42{padding-top:42rem!important}.pb-42{padding-bottom:42rem!important}.pl-42{padding-left:42rem!important}.pr-42{padding-right:42rem!important}.w-43{width:43rem!important}.h-43{height:43rem!important}.m-43{margin:43rem!important}.mt-43{margin-top:43rem!important}.mb-43{margin-bottom:43rem!important}.ml-43{margin-left:43rem!important}.mr-43{margin-right:43rem!important}.p-43{padding:43rem!important}.pt-43{padding-top:43rem!important}.pb-43{padding-bottom:43rem!important}.pl-43{padding-left:43rem!important}.pr-43{padding-right:43rem!important}.w-44{width:44rem!important}.h-44{height:44rem!important}.m-44{margin:44rem!important}.mt-44{margin-top:44rem!important}.mb-44{margin-bottom:44rem!important}.ml-44{margin-left:44rem!important}.mr-44{margin-right:44rem!important}.p-44{padding:44rem!important}.pt-44{padding-top:44rem!important}.pb-44{padding-bottom:44rem!important}.pl-44{padding-left:44rem!important}.pr-44{padding-right:44rem!important}.w-45{width:45rem!important}.h-45{height:45rem!important}.m-45{margin:45rem!important}.mt-45{margin-top:45rem!important}.mb-45{margin-bottom:45rem!important}.ml-45{margin-left:45rem!important}.mr-45{margin-right:45rem!important}.p-45{padding:45rem!important}.pt-45{padding-top:45rem!important}.pb-45{padding-bottom:45rem!important}.pl-45{padding-left:45rem!important}.pr-45{padding-right:45rem!important}.w-46{width:46rem!important}.h-46{height:46rem!important}.m-46{margin:46rem!important}.mt-46{margin-top:46rem!important}.mb-46{margin-bottom:46rem!important}.ml-46{margin-left:46rem!important}.mr-46{margin-right:46rem!important}.p-46{padding:46rem!important}.pt-46{padding-top:46rem!important}.pb-46{padding-bottom:46rem!important}.pl-46{padding-left:46rem!important}.pr-46{padding-right:46rem!important}.w-47{width:47rem!important}.h-47{height:47rem!important}.m-47{margin:47rem!important}.mt-47{margin-top:47rem!important}.mb-47{margin-bottom:47rem!important}.ml-47{margin-left:47rem!important}.mr-47{margin-right:47rem!important}.p-47{padding:47rem!important}.pt-47{padding-top:47rem!important}.pb-47{padding-bottom:47rem!important}.pl-47{padding-left:47rem!important}.pr-47{padding-right:47rem!important}.w-48{width:48rem!important}.h-48{height:48rem!important}.m-48{margin:48rem!important}.mt-48{margin-top:48rem!important}.mb-48{margin-bottom:48rem!important}.ml-48{margin-left:48rem!important}.mr-48{margin-right:48rem!important}.p-48{padding:48rem!important}.pt-48{padding-top:48rem!important}.pb-48{padding-bottom:48rem!important}.pl-48{padding-left:48rem!important}.pr-48{padding-right:48rem!important}.w-49{width:49rem!important}.h-49{height:49rem!important}.m-49{margin:49rem!important}.mt-49{margin-top:49rem!important}.mb-49{margin-bottom:49rem!important}.ml-49{margin-left:49rem!important}.mr-49{margin-right:49rem!important}.p-49{padding:49rem!important}.pt-49{padding-top:49rem!important}.pb-49{padding-bottom:49rem!important}.pl-49{padding-left:49rem!important}.pr-49{padding-right:49rem!important}.w-50{width:50rem!important}.h-50{height:50rem!important}.m-50{margin:50rem!important}.mt-50{margin-top:50rem!important}.mb-50{margin-bottom:50rem!important}.ml-50{margin-left:50rem!important}.mr-50{margin-right:50rem!important}.p-50{padding:50rem!important}.pt-50{padding-top:50rem!important}.pb-50{padding-bottom:50rem!important}.pl-50{padding-left:50rem!important}.pr-50{padding-right:50rem!important}.w-51{width:51rem!important}.h-51{height:51rem!important}.m-51{margin:51rem!important}.mt-51{margin-top:51rem!important}.mb-51{margin-bottom:51rem!important}.ml-51{margin-left:51rem!important}.mr-51{margin-right:51rem!important}.p-51{padding:51rem!important}.pt-51{padding-top:51rem!important}.pb-51{padding-bottom:51rem!important}.pl-51{padding-left:51rem!important}.pr-51{padding-right:51rem!important}.w-52{width:52rem!important}.h-52{height:52rem!important}.m-52{margin:52rem!important}.mt-52{margin-top:52rem!important}.mb-52{margin-bottom:52rem!important}.ml-52{margin-left:52rem!important}.mr-52{margin-right:52rem!important}.p-52{padding:52rem!important}.pt-52{padding-top:52rem!important}.pb-52{padding-bottom:52rem!important}.pl-52{padding-left:52rem!important}.pr-52{padding-right:52rem!important}.w-53{width:53rem!important}.h-53{height:53rem!important}.m-53{margin:53rem!important}.mt-53{margin-top:53rem!important}.mb-53{margin-bottom:53rem!important}.ml-53{margin-left:53rem!important}.mr-53{margin-right:53rem!important}.p-53{padding:53rem!important}.pt-53{padding-top:53rem!important}.pb-53{padding-bottom:53rem!important}.pl-53{padding-left:53rem!important}.pr-53{padding-right:53rem!important}.w-54{width:54rem!important}.h-54{height:54rem!important}.m-54{margin:54rem!important}.mt-54{margin-top:54rem!important}.mb-54{margin-bottom:54rem!important}.ml-54{margin-left:54rem!important}.mr-54{margin-right:54rem!important}.p-54{padding:54rem!important}.pt-54{padding-top:54rem!important}.pb-54{padding-bottom:54rem!important}.pl-54{padding-left:54rem!important}.pr-54{padding-right:54rem!important}.w-55{width:55rem!important}.h-55{height:55rem!important}.m-55{margin:55rem!important}.mt-55{margin-top:55rem!important}.mb-55{margin-bottom:55rem!important}.ml-55{margin-left:55rem!important}.mr-55{margin-right:55rem!important}.p-55{padding:55rem!important}.pt-55{padding-top:55rem!important}.pb-55{padding-bottom:55rem!important}.pl-55{padding-left:55rem!important}.pr-55{padding-right:55rem!important}.w-56{width:56rem!important}.h-56{height:56rem!important}.m-56{margin:56rem!important}.mt-56{margin-top:56rem!important}.mb-56{margin-bottom:56rem!important}.ml-56{margin-left:56rem!important}.mr-56{margin-right:56rem!important}.p-56{padding:56rem!important}.pt-56{padding-top:56rem!important}.pb-56{padding-bottom:56rem!important}.pl-56{padding-left:56rem!important}.pr-56{padding-right:56rem!important}.w-57{width:57rem!important}.h-57{height:57rem!important}.m-57{margin:57rem!important}.mt-57{margin-top:57rem!important}.mb-57{margin-bottom:57rem!important}.ml-57{margin-left:57rem!important}.mr-57{margin-right:57rem!important}.p-57{padding:57rem!important}.pt-57{padding-top:57rem!important}.pb-57{padding-bottom:57rem!important}.pl-57{padding-left:57rem!important}.pr-57{padding-right:57rem!important}.w-58{width:58rem!important}.h-58{height:58rem!important}.m-58{margin:58rem!important}.mt-58{margin-top:58rem!important}.mb-58{margin-bottom:58rem!important}.ml-58{margin-left:58rem!important}.mr-58{margin-right:58rem!important}.p-58{padding:58rem!important}.pt-58{padding-top:58rem!important}.pb-58{padding-bottom:58rem!important}.pl-58{padding-left:58rem!important}.pr-58{padding-right:58rem!important}.w-59{width:59rem!important}.h-59{height:59rem!important}.m-59{margin:59rem!important}.mt-59{margin-top:59rem!important}.mb-59{margin-bottom:59rem!important}.ml-59{margin-left:59rem!important}.mr-59{margin-right:59rem!important}.p-59{padding:59rem!important}.pt-59{padding-top:59rem!important}.pb-59{padding-bottom:59rem!important}.pl-59{padding-left:59rem!important}.pr-59{padding-right:59rem!important}.w-60{width:60rem!important}.h-60{height:60rem!important}.m-60{margin:60rem!important}.mt-60{margin-top:60rem!important}.mb-60{margin-bottom:60rem!important}.ml-60{margin-left:60rem!important}.mr-60{margin-right:60rem!important}.p-60{padding:60rem!important}.pt-60{padding-top:60rem!important}.pb-60{padding-bottom:60rem!important}.pl-60{padding-left:60rem!important}.pr-60{padding-right:60rem!important}.w-61{width:61rem!important}.h-61{height:61rem!important}.m-61{margin:61rem!important}.mt-61{margin-top:61rem!important}.mb-61{margin-bottom:61rem!important}.ml-61{margin-left:61rem!important}.mr-61{margin-right:61rem!important}.p-61{padding:61rem!important}.pt-61{padding-top:61rem!important}.pb-61{padding-bottom:61rem!important}.pl-61{padding-left:61rem!important}.pr-61{padding-right:61rem!important}.w-62{width:62rem!important}.h-62{height:62rem!important}.m-62{margin:62rem!important}.mt-62{margin-top:62rem!important}.mb-62{margin-bottom:62rem!important}.ml-62{margin-left:62rem!important}.mr-62{margin-right:62rem!important}.p-62{padding:62rem!important}.pt-62{padding-top:62rem!important}.pb-62{padding-bottom:62rem!important}.pl-62{padding-left:62rem!important}.pr-62{padding-right:62rem!important}.w-63{width:63rem!important}.h-63{height:63rem!important}.m-63{margin:63rem!important}.mt-63{margin-top:63rem!important}.mb-63{margin-bottom:63rem!important}.ml-63{margin-left:63rem!important}.mr-63{margin-right:63rem!important}.p-63{padding:63rem!important}.pt-63{padding-top:63rem!important}.pb-63{padding-bottom:63rem!important}.pl-63{padding-left:63rem!important}.pr-63{padding-right:63rem!important}.w-64{width:64rem!important}.h-64{height:64rem!important}.m-64{margin:64rem!important}.mt-64{margin-top:64rem!important}.mb-64{margin-bottom:64rem!important}.ml-64{margin-left:64rem!important}.mr-64{margin-right:64rem!important}.p-64{padding:64rem!important}.pt-64{padding-top:64rem!important}.pb-64{padding-bottom:64rem!important}.pl-64{padding-left:64rem!important}.pr-64{padding-right:64rem!important}.w-65{width:65rem!important}.h-65{height:65rem!important}.m-65{margin:65rem!important}.mt-65{margin-top:65rem!important}.mb-65{margin-bottom:65rem!important}.ml-65{margin-left:65rem!important}.mr-65{margin-right:65rem!important}.p-65{padding:65rem!important}.pt-65{padding-top:65rem!important}.pb-65{padding-bottom:65rem!important}.pl-65{padding-left:65rem!important}.pr-65{padding-right:65rem!important}.w-66{width:66rem!important}.h-66{height:66rem!important}.m-66{margin:66rem!important}.mt-66{margin-top:66rem!important}.mb-66{margin-bottom:66rem!important}.ml-66{margin-left:66rem!important}.mr-66{margin-right:66rem!important}.p-66{padding:66rem!important}.pt-66{padding-top:66rem!important}.pb-66{padding-bottom:66rem!important}.pl-66{padding-left:66rem!important}.pr-66{padding-right:66rem!important}.w-67{width:67rem!important}.h-67{height:67rem!important}.m-67{margin:67rem!important}.mt-67{margin-top:67rem!important}.mb-67{margin-bottom:67rem!important}.ml-67{margin-left:67rem!important}.mr-67{margin-right:67rem!important}.p-67{padding:67rem!important}.pt-67{padding-top:67rem!important}.pb-67{padding-bottom:67rem!important}.pl-67{padding-left:67rem!important}.pr-67{padding-right:67rem!important}.w-68{width:68rem!important}.h-68{height:68rem!important}.m-68{margin:68rem!important}.mt-68{margin-top:68rem!important}.mb-68{margin-bottom:68rem!important}.ml-68{margin-left:68rem!important}.mr-68{margin-right:68rem!important}.p-68{padding:68rem!important}.pt-68{padding-top:68rem!important}.pb-68{padding-bottom:68rem!important}.pl-68{padding-left:68rem!important}.pr-68{padding-right:68rem!important}.w-69{width:69rem!important}.h-69{height:69rem!important}.m-69{margin:69rem!important}.mt-69{margin-top:69rem!important}.mb-69{margin-bottom:69rem!important}.ml-69{margin-left:69rem!important}.mr-69{margin-right:69rem!important}.p-69{padding:69rem!important}.pt-69{padding-top:69rem!important}.pb-69{padding-bottom:69rem!important}.pl-69{padding-left:69rem!important}.pr-69{padding-right:69rem!important}.w-70{width:70rem!important}.h-70{height:70rem!important}.m-70{margin:70rem!important}.mt-70{margin-top:70rem!important}.mb-70{margin-bottom:70rem!important}.ml-70{margin-left:70rem!important}.mr-70{margin-right:70rem!important}.p-70{padding:70rem!important}.pt-70{padding-top:70rem!important}.pb-70{padding-bottom:70rem!important}.pl-70{padding-left:70rem!important}.pr-70{padding-right:70rem!important}.w-71{width:71rem!important}.h-71{height:71rem!important}.m-71{margin:71rem!important}.mt-71{margin-top:71rem!important}.mb-71{margin-bottom:71rem!important}.ml-71{margin-left:71rem!important}.mr-71{margin-right:71rem!important}.p-71{padding:71rem!important}.pt-71{padding-top:71rem!important}.pb-71{padding-bottom:71rem!important}.pl-71{padding-left:71rem!important}.pr-71{padding-right:71rem!important}.w-72{width:72rem!important}.h-72{height:72rem!important}.m-72{margin:72rem!important}.mt-72{margin-top:72rem!important}.mb-72{margin-bottom:72rem!important}.ml-72{margin-left:72rem!important}.mr-72{margin-right:72rem!important}.p-72{padding:72rem!important}.pt-72{padding-top:72rem!important}.pb-72{padding-bottom:72rem!important}.pl-72{padding-left:72rem!important}.pr-72{padding-right:72rem!important}.w-73{width:73rem!important}.h-73{height:73rem!important}.m-73{margin:73rem!important}.mt-73{margin-top:73rem!important}.mb-73{margin-bottom:73rem!important}.ml-73{margin-left:73rem!important}.mr-73{margin-right:73rem!important}.p-73{padding:73rem!important}.pt-73{padding-top:73rem!important}.pb-73{padding-bottom:73rem!important}.pl-73{padding-left:73rem!important}.pr-73{padding-right:73rem!important}.w-74{width:74rem!important}.h-74{height:74rem!important}.m-74{margin:74rem!important}.mt-74{margin-top:74rem!important}.mb-74{margin-bottom:74rem!important}.ml-74{margin-left:74rem!important}.mr-74{margin-right:74rem!important}.p-74{padding:74rem!important}.pt-74{padding-top:74rem!important}.pb-74{padding-bottom:74rem!important}.pl-74{padding-left:74rem!important}.pr-74{padding-right:74rem!important}.w-75{width:75rem!important}.h-75{height:75rem!important}.m-75{margin:75rem!important}.mt-75{margin-top:75rem!important}.mb-75{margin-bottom:75rem!important}.ml-75{margin-left:75rem!important}.mr-75{margin-right:75rem!important}.p-75{padding:75rem!important}.pt-75{padding-top:75rem!important}.pb-75{padding-bottom:75rem!important}.pl-75{padding-left:75rem!important}.pr-75{padding-right:75rem!important}.w-76{width:76rem!important}.h-76{height:76rem!important}.m-76{margin:76rem!important}.mt-76{margin-top:76rem!important}.mb-76{margin-bottom:76rem!important}.ml-76{margin-left:76rem!important}.mr-76{margin-right:76rem!important}.p-76{padding:76rem!important}.pt-76{padding-top:76rem!important}.pb-76{padding-bottom:76rem!important}.pl-76{padding-left:76rem!important}.pr-76{padding-right:76rem!important}.w-77{width:77rem!important}.h-77{height:77rem!important}.m-77{margin:77rem!important}.mt-77{margin-top:77rem!important}.mb-77{margin-bottom:77rem!important}.ml-77{margin-left:77rem!important}.mr-77{margin-right:77rem!important}.p-77{padding:77rem!important}.pt-77{padding-top:77rem!important}.pb-77{padding-bottom:77rem!important}.pl-77{padding-left:77rem!important}.pr-77{padding-right:77rem!important}.w-78{width:78rem!important}.h-78{height:78rem!important}.m-78{margin:78rem!important}.mt-78{margin-top:78rem!important}.mb-78{margin-bottom:78rem!important}.ml-78{margin-left:78rem!important}.mr-78{margin-right:78rem!important}.p-78{padding:78rem!important}.pt-78{padding-top:78rem!important}.pb-78{padding-bottom:78rem!important}.pl-78{padding-left:78rem!important}.pr-78{padding-right:78rem!important}.w-79{width:79rem!important}.h-79{height:79rem!important}.m-79{margin:79rem!important}.mt-79{margin-top:79rem!important}.mb-79{margin-bottom:79rem!important}.ml-79{margin-left:79rem!important}.mr-79{margin-right:79rem!important}.p-79{padding:79rem!important}.pt-79{padding-top:79rem!important}.pb-79{padding-bottom:79rem!important}.pl-79{padding-left:79rem!important}.pr-79{padding-right:79rem!important}.w-80{width:80rem!important}.h-80{height:80rem!important}.m-80{margin:80rem!important}.mt-80{margin-top:80rem!important}.mb-80{margin-bottom:80rem!important}.ml-80{margin-left:80rem!important}.mr-80{margin-right:80rem!important}.p-80{padding:80rem!important}.pt-80{padding-top:80rem!important}.pb-80{padding-bottom:80rem!important}.pl-80{padding-left:80rem!important}.pr-80{padding-right:80rem!important}.w-81{width:81rem!important}.h-81{height:81rem!important}.m-81{margin:81rem!important}.mt-81{margin-top:81rem!important}.mb-81{margin-bottom:81rem!important}.ml-81{margin-left:81rem!important}.mr-81{margin-right:81rem!important}.p-81{padding:81rem!important}.pt-81{padding-top:81rem!important}.pb-81{padding-bottom:81rem!important}.pl-81{padding-left:81rem!important}.pr-81{padding-right:81rem!important}.w-82{width:82rem!important}.h-82{height:82rem!important}.m-82{margin:82rem!important}.mt-82{margin-top:82rem!important}.mb-82{margin-bottom:82rem!important}.ml-82{margin-left:82rem!important}.mr-82{margin-right:82rem!important}.p-82{padding:82rem!important}.pt-82{padding-top:82rem!important}.pb-82{padding-bottom:82rem!important}.pl-82{padding-left:82rem!important}.pr-82{padding-right:82rem!important}.w-83{width:83rem!important}.h-83{height:83rem!important}.m-83{margin:83rem!important}.mt-83{margin-top:83rem!important}.mb-83{margin-bottom:83rem!important}.ml-83{margin-left:83rem!important}.mr-83{margin-right:83rem!important}.p-83{padding:83rem!important}.pt-83{padding-top:83rem!important}.pb-83{padding-bottom:83rem!important}.pl-83{padding-left:83rem!important}.pr-83{padding-right:83rem!important}.w-84{width:84rem!important}.h-84{height:84rem!important}.m-84{margin:84rem!important}.mt-84{margin-top:84rem!important}.mb-84{margin-bottom:84rem!important}.ml-84{margin-left:84rem!important}.mr-84{margin-right:84rem!important}.p-84{padding:84rem!important}.pt-84{padding-top:84rem!important}.pb-84{padding-bottom:84rem!important}.pl-84{padding-left:84rem!important}.pr-84{padding-right:84rem!important}.w-85{width:85rem!important}.h-85{height:85rem!important}.m-85{margin:85rem!important}.mt-85{margin-top:85rem!important}.mb-85{margin-bottom:85rem!important}.ml-85{margin-left:85rem!important}.mr-85{margin-right:85rem!important}.p-85{padding:85rem!important}.pt-85{padding-top:85rem!important}.pb-85{padding-bottom:85rem!important}.pl-85{padding-left:85rem!important}.pr-85{padding-right:85rem!important}.w-86{width:86rem!important}.h-86{height:86rem!important}.m-86{margin:86rem!important}.mt-86{margin-top:86rem!important}.mb-86{margin-bottom:86rem!important}.ml-86{margin-left:86rem!important}.mr-86{margin-right:86rem!important}.p-86{padding:86rem!important}.pt-86{padding-top:86rem!important}.pb-86{padding-bottom:86rem!important}.pl-86{padding-left:86rem!important}.pr-86{padding-right:86rem!important}.w-87{width:87rem!important}.h-87{height:87rem!important}.m-87{margin:87rem!important}.mt-87{margin-top:87rem!important}.mb-87{margin-bottom:87rem!important}.ml-87{margin-left:87rem!important}.mr-87{margin-right:87rem!important}.p-87{padding:87rem!important}.pt-87{padding-top:87rem!important}.pb-87{padding-bottom:87rem!important}.pl-87{padding-left:87rem!important}.pr-87{padding-right:87rem!important}.w-88{width:88rem!important}.h-88{height:88rem!important}.m-88{margin:88rem!important}.mt-88{margin-top:88rem!important}.mb-88{margin-bottom:88rem!important}.ml-88{margin-left:88rem!important}.mr-88{margin-right:88rem!important}.p-88{padding:88rem!important}.pt-88{padding-top:88rem!important}.pb-88{padding-bottom:88rem!important}.pl-88{padding-left:88rem!important}.pr-88{padding-right:88rem!important}.w-89{width:89rem!important}.h-89{height:89rem!important}.m-89{margin:89rem!important}.mt-89{margin-top:89rem!important}.mb-89{margin-bottom:89rem!important}.ml-89{margin-left:89rem!important}.mr-89{margin-right:89rem!important}.p-89{padding:89rem!important}.pt-89{padding-top:89rem!important}.pb-89{padding-bottom:89rem!important}.pl-89{padding-left:89rem!important}.pr-89{padding-right:89rem!important}.w-90{width:90rem!important}.h-90{height:90rem!important}.m-90{margin:90rem!important}.mt-90{margin-top:90rem!important}.mb-90{margin-bottom:90rem!important}.ml-90{margin-left:90rem!important}.mr-90{margin-right:90rem!important}.p-90{padding:90rem!important}.pt-90{padding-top:90rem!important}.pb-90{padding-bottom:90rem!important}.pl-90{padding-left:90rem!important}.pr-90{padding-right:90rem!important}.w-91{width:91rem!important}.h-91{height:91rem!important}.m-91{margin:91rem!important}.mt-91{margin-top:91rem!important}.mb-91{margin-bottom:91rem!important}.ml-91{margin-left:91rem!important}.mr-91{margin-right:91rem!important}.p-91{padding:91rem!important}.pt-91{padding-top:91rem!important}.pb-91{padding-bottom:91rem!important}.pl-91{padding-left:91rem!important}.pr-91{padding-right:91rem!important}.w-92{width:92rem!important}.h-92{height:92rem!important}.m-92{margin:92rem!important}.mt-92{margin-top:92rem!important}.mb-92{margin-bottom:92rem!important}.ml-92{margin-left:92rem!important}.mr-92{margin-right:92rem!important}.p-92{padding:92rem!important}.pt-92{padding-top:92rem!important}.pb-92{padding-bottom:92rem!important}.pl-92{padding-left:92rem!important}.pr-92{padding-right:92rem!important}.w-93{width:93rem!important}.h-93{height:93rem!important}.m-93{margin:93rem!important}.mt-93{margin-top:93rem!important}.mb-93{margin-bottom:93rem!important}.ml-93{margin-left:93rem!important}.mr-93{margin-right:93rem!important}.p-93{padding:93rem!important}.pt-93{padding-top:93rem!important}.pb-93{padding-bottom:93rem!important}.pl-93{padding-left:93rem!important}.pr-93{padding-right:93rem!important}.w-94{width:94rem!important}.h-94{height:94rem!important}.m-94{margin:94rem!important}.mt-94{margin-top:94rem!important}.mb-94{margin-bottom:94rem!important}.ml-94{margin-left:94rem!important}.mr-94{margin-right:94rem!important}.p-94{padding:94rem!important}.pt-94{padding-top:94rem!important}.pb-94{padding-bottom:94rem!important}.pl-94{padding-left:94rem!important}.pr-94{padding-right:94rem!important}.w-95{width:95rem!important}.h-95{height:95rem!important}.m-95{margin:95rem!important}.mt-95{margin-top:95rem!important}.mb-95{margin-bottom:95rem!important}.ml-95{margin-left:95rem!important}.mr-95{margin-right:95rem!important}.p-95{padding:95rem!important}.pt-95{padding-top:95rem!important}.pb-95{padding-bottom:95rem!important}.pl-95{padding-left:95rem!important}.pr-95{padding-right:95rem!important}.w-96{width:96rem!important}.h-96{height:96rem!important}.m-96{margin:96rem!important}.mt-96{margin-top:96rem!important}.mb-96{margin-bottom:96rem!important}.ml-96{margin-left:96rem!important}.mr-96{margin-right:96rem!important}.p-96{padding:96rem!important}.pt-96{padding-top:96rem!important}.pb-96{padding-bottom:96rem!important}.pl-96{padding-left:96rem!important}.pr-96{padding-right:96rem!important}.w-97{width:97rem!important}.h-97{height:97rem!important}.m-97{margin:97rem!important}.mt-97{margin-top:97rem!important}.mb-97{margin-bottom:97rem!important}.ml-97{margin-left:97rem!important}.mr-97{margin-right:97rem!important}.p-97{padding:97rem!important}.pt-97{padding-top:97rem!important}.pb-97{padding-bottom:97rem!important}.pl-97{padding-left:97rem!important}.pr-97{padding-right:97rem!important}.w-98{width:98rem!important}.h-98{height:98rem!important}.m-98{margin:98rem!important}.mt-98{margin-top:98rem!important}.mb-98{margin-bottom:98rem!important}.ml-98{margin-left:98rem!important}.mr-98{margin-right:98rem!important}.p-98{padding:98rem!important}.pt-98{padding-top:98rem!important}.pb-98{padding-bottom:98rem!important}.pl-98{padding-left:98rem!important}.pr-98{padding-right:98rem!important}.w-99{width:99rem!important}.h-99{height:99rem!important}.m-99{margin:99rem!important}.mt-99{margin-top:99rem!important}.mb-99{margin-bottom:99rem!important}.ml-99{margin-left:99rem!important}.mr-99{margin-right:99rem!important}.p-99{padding:99rem!important}.pt-99{padding-top:99rem!important}.pb-99{padding-bottom:99rem!important}.pl-99{padding-left:99rem!important}.pr-99{padding-right:99rem!important}*{box-sizing:border-box}html{font-size:4px}.icon-label{display:flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:4px}.icon-stream-chat{width:14px;height:14px;border:4px solid #4330fc;border-radius:100%}.icon-stream-dm{height:14px;width:14px;border:6px solid #4330fc;border-radius:100%}.icon-collection{height:12px;width:12px;position:relative;background-color:#6fdc74;border-radius:1px}.icon-collection:after{height:6px;width:6px;position:absolute;top:3px;left:3px;z-index:1;content:"";background-color:#fff;border-radius:100%}.icon-collection-comment:before{position:absolute;top:4px;left:4px;z-index:2;content:"";border-radius:100%}.icon-collection-comment:before,.icon-collection-post{height:4px;width:4px;background-color:#6fdc74}.icon-panini{width:32px;height:32px;position:relative}.icon-panini:after{position:absolute;content:"";left:4px;top:8px;border-top:4px solid #000;border-bottom:4px solid #000;height:8px;width:24px}.icon-x{position:relative;display:inline-block;width:32px;height:32px}.icon-x:after,.icon-x:before{position:absolute;top:10px;width:24px;height:24px;border-top:5px solid #000;border-color:inherit;content:""}.icon-x:before{left:-4px;transform:rotate(45deg)}.icon-x:after{left:13px;transform:rotate(-45deg)}.icon-lus{position:relative;display:inline-block;width:12px;height:12px}.icon-lus:after,.icon-lus:before{position:absolute;width:12px;height:12px;content:""}.icon-lus:before{border-top:2px solid #000;border-color:inherit;top:5px}.icon-lus:after{border-left:2px solid #000;border-color:inherit;left:5px}.icon-ellipsis-wrapper{display:flex;justify-content:space-between;align-items:center;padding:0 1px}.icon-ellipsis-dot{width:2px;height:2px;background-color:#000}body{overflow:overlay}a{cursor:pointer}a.vanilla{text-decoration:none}ul.vanilla{list-style-type:none;padding:0;margin:0}ul.vanilla li{padding:0}form{margin:0}[class*=col-]{margin-bottom:0}.circle{padding:0;border-width:8px;height:30px;width:30px;position:relative;top:3px}.text-body,body,input[type=text],p,textarea{font-size:14px;line-height:24px;font-family:-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;color:#000}.btn,.h1,.h2,.h3,.h4,.h5,.text-heading,button,h1,h2,h3,h4,h5{font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif}.command-item,.text-host-breadcrumb,.text-mono,.text-mono-bold,.text-mono-light,.text-timestamp,label{font-family:Source Code Pro,Roboto mono,Courier New,monospace}.h1,h1{font-size:6rem;line-height:8rem}.h2,h2{font-size:5rem;line-height:6rem}.h3,h3{font-size:4rem!important;line-height:5rem!important}h4{font-size:14px;line-height:20px}.text-small,.text-small *{font-size:12px;line-height:20px}.text-squat,.text-squat *{font-size:16px;line-height:20px}.text-gray,.text-gray *{color:#9b9b9b}.text-black,.text-black *{color:#000!important}.text-red,.text-red *{color:#ee3124}.text-timestamp{font-size:9px;font-weight:300;line-height:16px}.text-host-breadcrumb{font-weight:300;font-size:12px;line-height:20px;text-decoration:none}.flex{display:flex}.inline-block{display:inline-block}.space-between{justify-content:space-between}.align-start{align-items:flex-start}.align-center{align-items:center}.justify-start{justify-content:flex-start!important}.justify-end{justify-content:flex-end}.justify-between{justify-content:between}.flex-column{flex-direction:column}.pointer{cursor:pointer}.hide{display:none}.relative{position:relative}.inline{display:inline}.block{display:block}input[type=text],label,textarea{font-size:14px;line-height:24px;border:none;outline:none;padding:0}.select-dropdown[disabled],button[disabled],input[disabled],label[disabled],select[disabled],textarea[disabled]{opacity:.4;border-color:#aaa}input.input-sm{font-size:3rem;padding:6px;border-width:1px}label{margin-bottom:2rem}.input-group{padding:10px}.input-group label{font-size:14px;font-weight:600}.btn{width:156px;padding:8px 0;margin-bottom:0;display:inline-block;position:relative;font-size:16px;font-weight:500;text-align:center;color:#fff}.btn,.btn-sm{line-height:20px}.btn-sm{font-size:14px;padding:2px 0;height:24px}.btn-icon{width:40px}.btn:focus{text-decoration:underline}.btn[disabled]{background-color:#c4c4c4;color:#fff;opacity:1}.btn-default{background-color:#e6e6e6;color:#000}.btn-primary{background-color:#4330fc}.btn-secondary{background-color:#6fdc74;color:#000}.btn-tertiary{background-color:#ee3124}.btn-spinner{position:absolute;display:inline-block;width:10px;height:10px;top:12px}.btn-spinner:after{position:absolute;width:8px;height:8px;bottom:0;content:"◠";animation:a linear 1s infinite;font-size:10px;line-height:10px}.btn-spinner-lg{font-size:32px;font-weight:700;color:#4330fc}.btn-text{padding:0;background-color:inherit}@keyframes a{to{transform:rotate(1turn)}}#root{height:100%;padding-bottom:20px}.header-container{padding-top:3rem;padding-bottom:3rem;position:relative}.header-mainrow{margin-top:2rem;margin-bottom:1rem}.header-breadcrumbs,.header-carpet{height:20px}.header-title,.header-title *{text-decoration:none;font-weight:600;margin:0}.header-link{font-size:14px;line-height:20px;font-weight:600;font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif;text-decoration:none;text-transform:capitalize}.header-pending-panel{position:absolute;left:0;top:0;padding:8px 16px;background:#000;color:#fff}.header-notifications{width:14px;height:14px;padding-top:2px;margin-right:4px;border-radius:100%;background-color:#c4c4c4;color:#fff;font-size:9px;line-height:9px;text-align:center;transition:background-color 1s}.header-notifications-flash{background-color:#6fdc74;transition:background-color 1s}.page-status{position:absolute;right:10px;top:10px;border-radius:100%;height:18px;width:18px;background-color:#999}.header-pending-panel .page-status{position:relative;right:7px;top:1px}.page-status:after{content:"";background-color:#ccc;width:18px;height:18px;position:absolute;border-radius:100%;clip:rect(0,18px,18px,9px);animation:a 2s linear infinite}.page-status-primary{background-color:#4330fc}.page-status-primary:after{background-color:#d8d5fe}.page-status-secondary{background-color:#6fdc74}.page-status-secondary:after{background-color:#e2f8e3}.page-status-tertiary{background-color:#ee3124;cursor:pointer}.page-status-quaternary{background-color:#fd7a31}.page-status-quaternary:after{background-color:#febc98}.row{margin-left:-.5rem;margin-right:-.5rem}.flex-col-1{flex-basis:80px}.flex-col-1,.flex-col-2{padding-right:.5rem;padding-left:.5rem}.flex-col-2{flex-basis:160px}.flex-col-3{flex-basis:240px}.flex-col-3,.flex-col-4{padding-right:.5rem;padding-left:.5rem}.flex-col-4{flex-basis:320px}.flex-col-5{flex-basis:400px}.flex-col-5,.flex-col-6{padding-right:.5rem;padding-left:.5rem}.flex-col-6{flex-basis:480px}.flex-offset-1{margin-left:80px}.flex-offset-2{margin-left:160px}.flex-col-x{flex-basis:0;flex-grow:1;padding-right:.5rem;padding-left:.5rem}.chat-container{height:calc(100% - 106px)}.chat-container-inner,.chat-container-inner .container{height:100%}.flex-chat-scrollpane{flex-grow:1;flex-basis:0}.flex-chat-input{flex-basis:56px}.flex-chat-input .chat-sigil{margin-top:12px}.chat-container img{width:100%}textarea.chat-input-field{height:56px;padding:8px 10px;border:1px solid #e6e6e6;border-radius:1px;resize:none}.chat-input-field:placeholder{color:#b0b0b0}.chat-sep{text-align:center;font-weight:600;margin:4rem}.chat-msg-pending,.chat-msg-pending *{color:#aaa}.chat-msg-app,.chat-msg-app *{color:#9b9b9b}.chat-sigil{margin-right:2px}.cir-status{width:2rem;height:2rem;border-radius:100%;display:inline-block;position:relative;bottom:1px}.cir-green{background-color:#8eee9c}.cir-black,.cir-grey{background-color:#b0b0b0}.cir-red{background-color:#f44}.chat-scrollpane-view{display:flex;flex-direction:column;overflow-x:hidden!important;padding-bottom:15px}.chat-scrollpane-view>*{flex-shrink:0}.chat-scrollpane-view>:first-child{margin-top:auto!important}.scrollpane{height:600px;overflow-y:scroll;overflow-x:hidden;display:flex;flex-direction:column}.scrollpane>*{flex-shrink:0}.scrollpane>:first-child{margin-top:auto!important}input.collection-title,textarea.collection-post-edit{border:1px solid #b1b2b3}.collection-value-filled,input.collection-title:focus,textarea.collection-post-edit:focus{border-color:#000!important}input.collection-title{padding:10px 16px}textarea.collection-post-edit{height:352px;background:#fff;resize:none;padding:4rem}textarea.comment-edit{border:none;resize:none;padding:2rem;height:24rem;width:calc(100% - 26px);border:1px solid #aaa}.create-comment .usership{color:#000}.create-comment button{margin-left:calc(2rem + 18px)}div.coll-title,div.mod{font-size:6rem}.collection-index li.forum .meta-cont>div{float:left}.collection-index li.notes .da{position:absolute;margin-left:-12rem;margin-top:1rem}.collection-index .note-uuid{font-weight:inherit}.collection-index img{width:100%}.collection-index ul{list-style-type:none}.post img{width:100%}.post #edit{display:none}.collection-date{font-family:Source Code Pro,Roboto mono,Courier New,monospace;font-weight:300;font-size:3rem;line-height:5rem}.collection-title{position:relative}.collection-post:before,.collection-title:before{content:"";background-color:#6fdc74;border-radius:100%;width:4px;height:4px;position:absolute}.collection-post:before{margin-top:30px;margin-left:-18px}.collection-title:before{margin-top:22px;margin-left:-10rem}.collection-comment-avatar{position:absolute;left:-12rem;top:7px;width:32px;height:32px}.collection-post-actions{display:flex;align-items:center}.collection-comment-content{margin-left:26px}.form-mve .input-group-focused,.form-mve .input-group-focused input,.form-mve .input-group-focused textarea{background-color:#f6f6f6}.form-mve .input-group-error-message{display:none}.form-mve .input-group-error *{color:#ee3124}.form-mve .input-group-error input::placeholder{color:#ee3124;opacity:.3}.form-mve .input-group-error .input-group-error-message{display:block}.form-mve .btn-text{padding-left:3rem;padding-right:3rem}.form-mve .btn-text:focus span:first-child{text-decoration:underline}.command-page{padding-top:33px;position:relative}.command-row{height:48px;display:flex;align-items:center;position:relative;margin-bottom:27px}.command-input-placeholder-wrapper,.command-options{margin-left:-9px;width:calc(100% + 9px)}.command-input-placeholder-wrapper,input.command-menu-input{position:relative;border:none;outline:none;height:48px;font-size:20px;line-height:48px;font-family:Source Code Pro,Roboto mono,Courier New,monospace}input.command-menu-input{background-color:transparent;z-index:2;padding:0 9px;font-weight:500}input.command-menu-input[disabled]{opacity:1}.command-input-placeholder-wrapper{background-color:#f6f6f6}.command-input-placeholder-wrapper[disabled]{background-color:transparent}.command-input-placeholder-wrapper:after{content:attr(data-placeholder);position:absolute;top:0;left:0;right:0;z-index:1;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden;padding:0 9px;color:#9b9b9b;font-weight:400}.command-item{padding-top:3rem;padding-bottom:3rem;padding-left:9px;cursor:pointer;width:100%}.command-item-selected{background-color:#f6f6f6;font-weight:600}.command-help a{display:block}.profile-shipname{display:flex;align-items:center;font-size:28px;font-weight:600;height:64px;font-family:Source Code Pro,Roboto mono,Courier New,monospace}.profile-message-btn{background:#fff;display:inline-block}.profile-qr-desc{max-width:256px}.inbox-page img{width:100%}.inbox-page .invite .btn{float:right}.inbox-page .collection-preview h1:first-child{display:none}.inbox-link{font-weight:500;color:#777}.inbox-link-active{color:#000} \ No newline at end of file +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}[class*=col-]{width:100%;margin-bottom:1rem}.container{margin:0 auto;padding:0 2rem;max-width:960px}.row{display:flex}.flex,.row{flex-wrap:wrap}.align-vertical{align-items:center}.justify-center{justify-content:center}@media only screen and (min-width:0){.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-offset-0,.col-sm-offset-1,.col-sm-offset-2,.col-sm-offset-3,.col-sm-offset-4,.col-sm-offset-5,.col-sm-offset-6,.col-sm-offset-7,.col-sm-offset-8,.col-sm-offset-9,.col-sm-offset-10,.col-sm-offset-11,.col-sm-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-sm{flex-grow:1;flex-basis:0;max-width:100%}.col-sm-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-sm-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-sm-3{flex-basis:25%;max-width:25%}.col-sm-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-sm-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-sm-6{flex-basis:50%;max-width:50%}.col-sm-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-sm-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-sm-9{flex-basis:75%;max-width:75%}.col-sm-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-sm-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-sm-12{flex-basis:100%;max-width:100%}.col-sm-offset-0{margin-left:0}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-11{margin-left:91.66666667%}}@media only screen and (min-width:480px){.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-offset-0,.col-md-offset-1,.col-md-offset-2,.col-md-offset-3,.col-md-offset-4,.col-md-offset-5,.col-md-offset-6,.col-md-offset-7,.col-md-offset-8,.col-md-offset-9,.col-md-offset-10,.col-md-offset-11,.col-md-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-md{flex-grow:1;flex-basis:0;max-width:100%}.col-md-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-md-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-md-3{flex-basis:25%;max-width:25%}.col-md-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-md-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-md-6{flex-basis:50%;max-width:50%}.col-md-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-md-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-md-9{flex-basis:75%;max-width:75%}.col-md-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-md-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-md-12{flex-basis:100%;max-width:100%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-11{margin-left:91.66666667%}}@media only screen and (min-width:960px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-offset-0,.col-lg-offset-1,.col-lg-offset-2,.col-lg-offset-3,.col-lg-offset-4,.col-lg-offset-5,.col-lg-offset-6,.col-lg-offset-7,.col-lg-offset-8,.col-lg-offset-9,.col-lg-offset-10,.col-lg-offset-11,.col-lg-offset-12{box-sizing:border-box;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.col-lg{flex-grow:1;flex-basis:0;max-width:100%}.col-lg-1{flex-basis:8.33333333%;max-width:8.33333333%}.col-lg-2{flex-basis:16.66666667%;max-width:16.66666667%}.col-lg-3{flex-basis:25%;max-width:25%}.col-lg-4{flex-basis:33.33333333%;max-width:33.33333333%}.col-lg-5{flex-basis:41.66666667%;max-width:41.66666667%}.col-lg-6{flex-basis:50%;max-width:50%}.col-lg-7{flex-basis:58.33333333%;max-width:58.33333333%}.col-lg-8{flex-basis:66.66666667%;max-width:66.66666667%}.col-lg-9{flex-basis:75%;max-width:75%}.col-lg-10{flex-basis:83.33333333%;max-width:83.33333333%}.col-lg-11{flex-basis:91.66666667%;max-width:91.66666667%}.col-lg-12{flex-basis:100%;max-width:100%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-11{margin-left:91.66666667%}}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Thin.ttf) format("truetype");font-weight:100}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-ExtraLight.ttf) format("truetype");font-weight:200}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Light.ttf) format("truetype");font-weight:300}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Regular.ttf) format("truetype");font-weight:400}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Medium.ttf) format("truetype");font-weight:500}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-SemiBold.ttf) format("truetype");font-weight:600}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Bold.ttf) format("truetype");font-weight:700}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-ExtraBold.ttf) format("truetype");font-weight:800}@font-face{font-family:Work Sans;src:url(https://storage.googleapis.com/media.urbit.org/fonts/WorkSans-Black.ttf) format("truetype");font-weight:900}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-extralight.woff);font-weight:200}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-light.woff);font-weight:300}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-regular.woff);font-weight:400}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-medium.woff);font-weight:500}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-semibold.woff);font-weight:600}@font-face{font-family:Source Code Pro;src:url(https://storage.googleapis.com/media.urbit.org/fonts/scp-bold.woff);font-weight:700}*{font-smoothing:antialiased;-webkit-font-smoothing:antialiased}body{font-family:-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;font-size:4rem;line-height:6rem;color:#373a3c}a{color:#000}p{margin:0 0 2rem}.text-heading,h1,h2,h3,h4,h5{margin:0;font-family:Work Sans;color:#373a3c}.h1,h1{font-size:12rem;line-height:16rem;margin:4rem 0}.h1,.h2,h1,h2{font-weight:600}.h2,h2{font-size:9rem;line-height:13rem;margin:3rem 0}.h3,h3{font-size:6rem;font-weight:600;line-height:8rem;margin:2rem 0}.h4,h4{font-weight:600}.h4,.h5,h4,h5{font-size:5rem;line-height:7rem;margin:1rem 0}.h5,h5{font-weight:500}.text-sm,caption{font-size:3rem;line-height:5rem}.text-md{font-size:4rem;line-height:6rem}.text-lg{font-size:5rem;line-height:7rem}code,pre{background-color:#f1f1f1;padding:1rem}.text-code,.text-mono,code,pre{font-family:Source Code Pro,Roboto mono,Courier New,monospace}.text-code{color:#000}.code-block,.text-code{background-color:#f1f1f1}.code-block{padding:5rem;white-space:pre-wrap}.code-block .text-code{font-weight:200}.underline,u{text-decoration:underline}.strikethrough,s{text-decoration:line-through}.italic,em{font-style:italic}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.text-300{font-weight:300}.text-400{font-weight:400}.text-500{font-weight:500}.text-600{font-weight:600}.text-700,b{font-weight:700}.text-800{font-weight:800}.h-font{font-family:Work Sans}.blue{color:#4330fc}.green{color:#6fdc74}.red{color:#ee3124}.gray-lighter{color:#f1f1f1}.gray-light{color:#d4d4d4}.gray{color:#5b5b5b}.gray-dark{color:#373a3c}.blue-hl{background-color:#4330fc;color:#fff}.green-hl{background-color:#6fdc74;color:#fff}.red-hl{background-color:#ee3124;color:#fff}.gray-lighter-hl{background-color:#f1f1f1;color:#fff}.gray-light-hl{background-color:#d4d4d4;color:#fff}.gray-hl{background-color:#5b5b5b;color:#fff}.gray-dark-hl{background-color:#373a3c;color:#fff}.black-hl{background-color:#000;color:#fff}.center{text-align:center}.right{text-align:right}.justify{text-align:justify}button{border:none;outline:none}.btn,button{font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;font-size:4rem;line-height:4rem;padding:3rem 6rem;color:#000;background-color:#d4d4d4;margin:0 0 6px}.btn-sm{font-size:3rem;line-height:3rem;padding:2rem 4rem}.btn-primary{color:#fff}.btn-tetiary{background-color:#5b5b5b;color:#fff}.btn-warning{background-color:#ee3124;color:#fff}.btn-group .btn{display:inline-block}.btn-group .btn:not(.active){background-color:#d4d4d4;color:#000}label{display:block;font-weight:700}input[type=text],textarea{border:2px solid #000;padding:12px;width:100%}.error-label{display:none;color:#f44;font-size:2.33rem;line-height:3rem;margin-top:1rem}.input-group{margin:0 0 2rem}.input-group.error input[type=text],.input-group.error textarea{border:.5rem solid #f44}.input-group.error .error-label{display:block}.checkbox-group input,.checkbox-group label,.radio-group input,.radio-group label{font-weight:400;display:inline-block}.select-dropdown{display:flex;border:2px solid #000;overflow:hidden;background-color:#fff}.select-dropdown select{padding:5px 8px;width:130%;border:none;box-shadow:none;background:transparent;background-image:none;-webkit-appearance:none}.select-dropdown select:focus{outline:none}.select-dropdown .triangle-down{border-width:2rem 1rem 0;position:relative;top:14px;right:8px}.icon-arrow-right:before{content:"→"}.icon-arrow-left:before{content:"←"}.icon-arrow-up:before{content:"↑"}.icon-arrow-down:before{content:"↓"}.icon-cross:before{content:"×"}.icon-ellipsis:before{content:"...";position:relative;bottom:6px}.selected:before{content:"∙"}.icon{margin-right:.6rem}.icon.prev{width:1px;height:1px;border:12.0006px solid transparent;border-right:18px solid #000;border-left:0 solid transparent}.icon.next{border:12.0006px solid transparent;border-left:18px solid #000;border-right:0 solid transparent;margin-right:0}.icon.next,.icon.up{width:1px;height:1px}.icon.up{border:12.0006px solid transparent;border-bottom:18px solid #000;border-top:0 solid transparent}.circle{display:inline-block;padding:2rem;border-radius:50%;border:2px solid #000;text-align:center}.circle-sm{padding:1rem}.circle-lg{padding:4rem}.circle-fill{background-color:#000}.circle-red{background-color:#ee3124;border-color:#ee3124}.circle-blue{background-color:#4330fc;border-color:#4330fc}.circle-blue-light{background-color:#a4d8e8;border-color:#a4d8e8}.circle-yellow{background-color:#ffc440;border-color:#ffc440}.circle-green{background-color:#6fdc74;border-color:#6fdc74}.circle-gray{background-color:#5b5b5b;border-color:#5b5b5b}.circle-gray-light{background-color:#d4d4d4;border-color:#d4d4d4}.circle-gray-lighter{background-color:#f1f1f1;border-color:#f1f1f1}.circle-gray-dark{background-color:#373a3c;border-color:#373a3c}.circle-pill{border-radius:9999px;width:10rem}.circle-pill.circle-lg{width:20rem}.square{display:inline-block;padding:2rem;border:2px solid #000;text-align:center}.square-sm{padding:1rem}.square-lg{padding:4rem}.square-fill{background-color:#000}.square-red{background-color:red;border-color:red}.square-rect{width:10rem}.square-rect.square-lg{width:20rem}.triangle-base{display:inline-block;width:0;height:0}.triangle-up{border-bottom:4rem solid #000}.triangle-down,.triangle-up{border-left:2rem solid transparent;border-right:2rem solid transparent}.triangle-down{border-top:4rem solid #000}.triangle-right{border-left:4rem solid #000}.triangle-left,.triangle-right{border-top:2rem solid transparent;border-bottom:2rem solid transparent}.triangle-left{border-right:4rem solid #000}.urbit-logo{width:72px;height:72px;border-radius:50%;border:5px solid #fff;background-color:transparent}.urbit-logo,.urbit-logo:before{display:inline-block;vertical-align:middle}.urbit-logo:before{content:"~";color:#fff;font-size:72px;line-height:54px;text-align:center;width:2rem;font-family:Work Sans;font-weight:600;margin-right:30px;margin-top:3px}.urbit-logo-solid{border-color:#000}.urbit-logo-solid:before{color:#000}section{margin:0 0 2rem;border:none}blockquote{border-left:6px solid #000;margin:24px 0;padding-left:18px}hr{margin:4rem 0;width:100%;height:1rem;border:0;background-color:#373a3c}ul{padding-left:4rem;list-style:disc outside}ul li{margin-bottom:2rem;padding-left:2rem}ol ul,ul ol,ul ul{margin:2rem}ol ul li,ul ol li,ul ul li{margin-bottom:1rem}ul.list-reset{list-style:none}ol,ul.list-reset,ul.list-reset li{padding-left:0}ol{list-style:none}ol>li{counter-increment:a;margin-left:0;margin-bottom:1rem}ol>li:before{content:counter(a);font-weight:700;vertical-align:center;display:inline-block;width:6rem;text-align:left}.w-0{width:0!important}.h-0{height:0!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mr-0{margin-right:0!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.pr-0{padding-right:0!important}.w-1{width:1rem!important}.h-1{height:1rem!important}.m-1{margin:1rem!important}.mt-1{margin-top:1rem!important}.mb-1{margin-bottom:1rem!important}.ml-1{margin-left:1rem!important}.mr-1{margin-right:1rem!important}.p-1{padding:1rem!important}.pt-1{padding-top:1rem!important}.pb-1{padding-bottom:1rem!important}.pl-1{padding-left:1rem!important}.pr-1{padding-right:1rem!important}.w-2{width:2rem!important}.h-2{height:2rem!important}.m-2{margin:2rem!important}.mt-2{margin-top:2rem!important}.mb-2{margin-bottom:2rem!important}.ml-2{margin-left:2rem!important}.mr-2{margin-right:2rem!important}.p-2{padding:2rem!important}.pt-2{padding-top:2rem!important}.pb-2{padding-bottom:2rem!important}.pl-2{padding-left:2rem!important}.pr-2{padding-right:2rem!important}.w-3{width:3rem!important}.h-3{height:3rem!important}.m-3{margin:3rem!important}.mt-3{margin-top:3rem!important}.mb-3{margin-bottom:3rem!important}.ml-3{margin-left:3rem!important}.mr-3{margin-right:3rem!important}.p-3{padding:3rem!important}.pt-3{padding-top:3rem!important}.pb-3{padding-bottom:3rem!important}.pl-3{padding-left:3rem!important}.pr-3{padding-right:3rem!important}.w-4{width:4rem!important}.h-4{height:4rem!important}.m-4{margin:4rem!important}.mt-4{margin-top:4rem!important}.mb-4{margin-bottom:4rem!important}.ml-4{margin-left:4rem!important}.mr-4{margin-right:4rem!important}.p-4{padding:4rem!important}.pt-4{padding-top:4rem!important}.pb-4{padding-bottom:4rem!important}.pl-4{padding-left:4rem!important}.pr-4{padding-right:4rem!important}.w-5{width:5rem!important}.h-5{height:5rem!important}.m-5{margin:5rem!important}.mt-5{margin-top:5rem!important}.mb-5{margin-bottom:5rem!important}.ml-5{margin-left:5rem!important}.mr-5{margin-right:5rem!important}.p-5{padding:5rem!important}.pt-5{padding-top:5rem!important}.pb-5{padding-bottom:5rem!important}.pl-5{padding-left:5rem!important}.pr-5{padding-right:5rem!important}.w-6{width:6rem!important}.h-6{height:6rem!important}.m-6{margin:6rem!important}.mt-6{margin-top:6rem!important}.mb-6{margin-bottom:6rem!important}.ml-6{margin-left:6rem!important}.mr-6{margin-right:6rem!important}.p-6{padding:6rem!important}.pt-6{padding-top:6rem!important}.pb-6{padding-bottom:6rem!important}.pl-6{padding-left:6rem!important}.pr-6{padding-right:6rem!important}.w-7{width:7rem!important}.h-7{height:7rem!important}.m-7{margin:7rem!important}.mt-7{margin-top:7rem!important}.mb-7{margin-bottom:7rem!important}.ml-7{margin-left:7rem!important}.mr-7{margin-right:7rem!important}.p-7{padding:7rem!important}.pt-7{padding-top:7rem!important}.pb-7{padding-bottom:7rem!important}.pl-7{padding-left:7rem!important}.pr-7{padding-right:7rem!important}.w-8{width:8rem!important}.h-8{height:8rem!important}.m-8{margin:8rem!important}.mt-8{margin-top:8rem!important}.mb-8{margin-bottom:8rem!important}.ml-8{margin-left:8rem!important}.mr-8{margin-right:8rem!important}.p-8{padding:8rem!important}.pt-8{padding-top:8rem!important}.pb-8{padding-bottom:8rem!important}.pl-8{padding-left:8rem!important}.pr-8{padding-right:8rem!important}.w-9{width:9rem!important}.h-9{height:9rem!important}.m-9{margin:9rem!important}.mt-9{margin-top:9rem!important}.mb-9{margin-bottom:9rem!important}.ml-9{margin-left:9rem!important}.mr-9{margin-right:9rem!important}.p-9{padding:9rem!important}.pt-9{padding-top:9rem!important}.pb-9{padding-bottom:9rem!important}.pl-9{padding-left:9rem!important}.pr-9{padding-right:9rem!important}.w-10{width:10rem!important}.h-10{height:10rem!important}.m-10{margin:10rem!important}.mt-10{margin-top:10rem!important}.mb-10{margin-bottom:10rem!important}.ml-10{margin-left:10rem!important}.mr-10{margin-right:10rem!important}.p-10{padding:10rem!important}.pt-10{padding-top:10rem!important}.pb-10{padding-bottom:10rem!important}.pl-10{padding-left:10rem!important}.pr-10{padding-right:10rem!important}.w-11{width:11rem!important}.h-11{height:11rem!important}.m-11{margin:11rem!important}.mt-11{margin-top:11rem!important}.mb-11{margin-bottom:11rem!important}.ml-11{margin-left:11rem!important}.mr-11{margin-right:11rem!important}.p-11{padding:11rem!important}.pt-11{padding-top:11rem!important}.pb-11{padding-bottom:11rem!important}.pl-11{padding-left:11rem!important}.pr-11{padding-right:11rem!important}.w-12{width:12rem!important}.h-12{height:12rem!important}.m-12{margin:12rem!important}.mt-12{margin-top:12rem!important}.mb-12{margin-bottom:12rem!important}.ml-12{margin-left:12rem!important}.mr-12{margin-right:12rem!important}.p-12{padding:12rem!important}.pt-12{padding-top:12rem!important}.pb-12{padding-bottom:12rem!important}.pl-12{padding-left:12rem!important}.pr-12{padding-right:12rem!important}.w-13{width:13rem!important}.h-13{height:13rem!important}.m-13{margin:13rem!important}.mt-13{margin-top:13rem!important}.mb-13{margin-bottom:13rem!important}.ml-13{margin-left:13rem!important}.mr-13{margin-right:13rem!important}.p-13{padding:13rem!important}.pt-13{padding-top:13rem!important}.pb-13{padding-bottom:13rem!important}.pl-13{padding-left:13rem!important}.pr-13{padding-right:13rem!important}.w-14{width:14rem!important}.h-14{height:14rem!important}.m-14{margin:14rem!important}.mt-14{margin-top:14rem!important}.mb-14{margin-bottom:14rem!important}.ml-14{margin-left:14rem!important}.mr-14{margin-right:14rem!important}.p-14{padding:14rem!important}.pt-14{padding-top:14rem!important}.pb-14{padding-bottom:14rem!important}.pl-14{padding-left:14rem!important}.pr-14{padding-right:14rem!important}.w-15{width:15rem!important}.h-15{height:15rem!important}.m-15{margin:15rem!important}.mt-15{margin-top:15rem!important}.mb-15{margin-bottom:15rem!important}.ml-15{margin-left:15rem!important}.mr-15{margin-right:15rem!important}.p-15{padding:15rem!important}.pt-15{padding-top:15rem!important}.pb-15{padding-bottom:15rem!important}.pl-15{padding-left:15rem!important}.pr-15{padding-right:15rem!important}.w-16{width:16rem!important}.h-16{height:16rem!important}.m-16{margin:16rem!important}.mt-16{margin-top:16rem!important}.mb-16{margin-bottom:16rem!important}.ml-16{margin-left:16rem!important}.mr-16{margin-right:16rem!important}.p-16{padding:16rem!important}.pt-16{padding-top:16rem!important}.pb-16{padding-bottom:16rem!important}.pl-16{padding-left:16rem!important}.pr-16{padding-right:16rem!important}.w-17{width:17rem!important}.h-17{height:17rem!important}.m-17{margin:17rem!important}.mt-17{margin-top:17rem!important}.mb-17{margin-bottom:17rem!important}.ml-17{margin-left:17rem!important}.mr-17{margin-right:17rem!important}.p-17{padding:17rem!important}.pt-17{padding-top:17rem!important}.pb-17{padding-bottom:17rem!important}.pl-17{padding-left:17rem!important}.pr-17{padding-right:17rem!important}.w-18{width:18rem!important}.h-18{height:18rem!important}.m-18{margin:18rem!important}.mt-18{margin-top:18rem!important}.mb-18{margin-bottom:18rem!important}.ml-18{margin-left:18rem!important}.mr-18{margin-right:18rem!important}.p-18{padding:18rem!important}.pt-18{padding-top:18rem!important}.pb-18{padding-bottom:18rem!important}.pl-18{padding-left:18rem!important}.pr-18{padding-right:18rem!important}.w-19{width:19rem!important}.h-19{height:19rem!important}.m-19{margin:19rem!important}.mt-19{margin-top:19rem!important}.mb-19{margin-bottom:19rem!important}.ml-19{margin-left:19rem!important}.mr-19{margin-right:19rem!important}.p-19{padding:19rem!important}.pt-19{padding-top:19rem!important}.pb-19{padding-bottom:19rem!important}.pl-19{padding-left:19rem!important}.pr-19{padding-right:19rem!important}.w-20{width:20rem!important}.h-20{height:20rem!important}.m-20{margin:20rem!important}.mt-20{margin-top:20rem!important}.mb-20{margin-bottom:20rem!important}.ml-20{margin-left:20rem!important}.mr-20{margin-right:20rem!important}.p-20{padding:20rem!important}.pt-20{padding-top:20rem!important}.pb-20{padding-bottom:20rem!important}.pl-20{padding-left:20rem!important}.pr-20{padding-right:20rem!important}.w-21{width:21rem!important}.h-21{height:21rem!important}.m-21{margin:21rem!important}.mt-21{margin-top:21rem!important}.mb-21{margin-bottom:21rem!important}.ml-21{margin-left:21rem!important}.mr-21{margin-right:21rem!important}.p-21{padding:21rem!important}.pt-21{padding-top:21rem!important}.pb-21{padding-bottom:21rem!important}.pl-21{padding-left:21rem!important}.pr-21{padding-right:21rem!important}.w-22{width:22rem!important}.h-22{height:22rem!important}.m-22{margin:22rem!important}.mt-22{margin-top:22rem!important}.mb-22{margin-bottom:22rem!important}.ml-22{margin-left:22rem!important}.mr-22{margin-right:22rem!important}.p-22{padding:22rem!important}.pt-22{padding-top:22rem!important}.pb-22{padding-bottom:22rem!important}.pl-22{padding-left:22rem!important}.pr-22{padding-right:22rem!important}.w-23{width:23rem!important}.h-23{height:23rem!important}.m-23{margin:23rem!important}.mt-23{margin-top:23rem!important}.mb-23{margin-bottom:23rem!important}.ml-23{margin-left:23rem!important}.mr-23{margin-right:23rem!important}.p-23{padding:23rem!important}.pt-23{padding-top:23rem!important}.pb-23{padding-bottom:23rem!important}.pl-23{padding-left:23rem!important}.pr-23{padding-right:23rem!important}.w-24{width:24rem!important}.h-24{height:24rem!important}.m-24{margin:24rem!important}.mt-24{margin-top:24rem!important}.mb-24{margin-bottom:24rem!important}.ml-24{margin-left:24rem!important}.mr-24{margin-right:24rem!important}.p-24{padding:24rem!important}.pt-24{padding-top:24rem!important}.pb-24{padding-bottom:24rem!important}.pl-24{padding-left:24rem!important}.pr-24{padding-right:24rem!important}.w-25{width:25rem!important}.h-25{height:25rem!important}.m-25{margin:25rem!important}.mt-25{margin-top:25rem!important}.mb-25{margin-bottom:25rem!important}.ml-25{margin-left:25rem!important}.mr-25{margin-right:25rem!important}.p-25{padding:25rem!important}.pt-25{padding-top:25rem!important}.pb-25{padding-bottom:25rem!important}.pl-25{padding-left:25rem!important}.pr-25{padding-right:25rem!important}.w-26{width:26rem!important}.h-26{height:26rem!important}.m-26{margin:26rem!important}.mt-26{margin-top:26rem!important}.mb-26{margin-bottom:26rem!important}.ml-26{margin-left:26rem!important}.mr-26{margin-right:26rem!important}.p-26{padding:26rem!important}.pt-26{padding-top:26rem!important}.pb-26{padding-bottom:26rem!important}.pl-26{padding-left:26rem!important}.pr-26{padding-right:26rem!important}.w-27{width:27rem!important}.h-27{height:27rem!important}.m-27{margin:27rem!important}.mt-27{margin-top:27rem!important}.mb-27{margin-bottom:27rem!important}.ml-27{margin-left:27rem!important}.mr-27{margin-right:27rem!important}.p-27{padding:27rem!important}.pt-27{padding-top:27rem!important}.pb-27{padding-bottom:27rem!important}.pl-27{padding-left:27rem!important}.pr-27{padding-right:27rem!important}.w-28{width:28rem!important}.h-28{height:28rem!important}.m-28{margin:28rem!important}.mt-28{margin-top:28rem!important}.mb-28{margin-bottom:28rem!important}.ml-28{margin-left:28rem!important}.mr-28{margin-right:28rem!important}.p-28{padding:28rem!important}.pt-28{padding-top:28rem!important}.pb-28{padding-bottom:28rem!important}.pl-28{padding-left:28rem!important}.pr-28{padding-right:28rem!important}.w-29{width:29rem!important}.h-29{height:29rem!important}.m-29{margin:29rem!important}.mt-29{margin-top:29rem!important}.mb-29{margin-bottom:29rem!important}.ml-29{margin-left:29rem!important}.mr-29{margin-right:29rem!important}.p-29{padding:29rem!important}.pt-29{padding-top:29rem!important}.pb-29{padding-bottom:29rem!important}.pl-29{padding-left:29rem!important}.pr-29{padding-right:29rem!important}.w-30{width:30rem!important}.h-30{height:30rem!important}.m-30{margin:30rem!important}.mt-30{margin-top:30rem!important}.mb-30{margin-bottom:30rem!important}.ml-30{margin-left:30rem!important}.mr-30{margin-right:30rem!important}.p-30{padding:30rem!important}.pt-30{padding-top:30rem!important}.pb-30{padding-bottom:30rem!important}.pl-30{padding-left:30rem!important}.pr-30{padding-right:30rem!important}.w-31{width:31rem!important}.h-31{height:31rem!important}.m-31{margin:31rem!important}.mt-31{margin-top:31rem!important}.mb-31{margin-bottom:31rem!important}.ml-31{margin-left:31rem!important}.mr-31{margin-right:31rem!important}.p-31{padding:31rem!important}.pt-31{padding-top:31rem!important}.pb-31{padding-bottom:31rem!important}.pl-31{padding-left:31rem!important}.pr-31{padding-right:31rem!important}.w-32{width:32rem!important}.h-32{height:32rem!important}.m-32{margin:32rem!important}.mt-32{margin-top:32rem!important}.mb-32{margin-bottom:32rem!important}.ml-32{margin-left:32rem!important}.mr-32{margin-right:32rem!important}.p-32{padding:32rem!important}.pt-32{padding-top:32rem!important}.pb-32{padding-bottom:32rem!important}.pl-32{padding-left:32rem!important}.pr-32{padding-right:32rem!important}.w-33{width:33rem!important}.h-33{height:33rem!important}.m-33{margin:33rem!important}.mt-33{margin-top:33rem!important}.mb-33{margin-bottom:33rem!important}.ml-33{margin-left:33rem!important}.mr-33{margin-right:33rem!important}.p-33{padding:33rem!important}.pt-33{padding-top:33rem!important}.pb-33{padding-bottom:33rem!important}.pl-33{padding-left:33rem!important}.pr-33{padding-right:33rem!important}.w-34{width:34rem!important}.h-34{height:34rem!important}.m-34{margin:34rem!important}.mt-34{margin-top:34rem!important}.mb-34{margin-bottom:34rem!important}.ml-34{margin-left:34rem!important}.mr-34{margin-right:34rem!important}.p-34{padding:34rem!important}.pt-34{padding-top:34rem!important}.pb-34{padding-bottom:34rem!important}.pl-34{padding-left:34rem!important}.pr-34{padding-right:34rem!important}.w-35{width:35rem!important}.h-35{height:35rem!important}.m-35{margin:35rem!important}.mt-35{margin-top:35rem!important}.mb-35{margin-bottom:35rem!important}.ml-35{margin-left:35rem!important}.mr-35{margin-right:35rem!important}.p-35{padding:35rem!important}.pt-35{padding-top:35rem!important}.pb-35{padding-bottom:35rem!important}.pl-35{padding-left:35rem!important}.pr-35{padding-right:35rem!important}.w-36{width:36rem!important}.h-36{height:36rem!important}.m-36{margin:36rem!important}.mt-36{margin-top:36rem!important}.mb-36{margin-bottom:36rem!important}.ml-36{margin-left:36rem!important}.mr-36{margin-right:36rem!important}.p-36{padding:36rem!important}.pt-36{padding-top:36rem!important}.pb-36{padding-bottom:36rem!important}.pl-36{padding-left:36rem!important}.pr-36{padding-right:36rem!important}.w-37{width:37rem!important}.h-37{height:37rem!important}.m-37{margin:37rem!important}.mt-37{margin-top:37rem!important}.mb-37{margin-bottom:37rem!important}.ml-37{margin-left:37rem!important}.mr-37{margin-right:37rem!important}.p-37{padding:37rem!important}.pt-37{padding-top:37rem!important}.pb-37{padding-bottom:37rem!important}.pl-37{padding-left:37rem!important}.pr-37{padding-right:37rem!important}.w-38{width:38rem!important}.h-38{height:38rem!important}.m-38{margin:38rem!important}.mt-38{margin-top:38rem!important}.mb-38{margin-bottom:38rem!important}.ml-38{margin-left:38rem!important}.mr-38{margin-right:38rem!important}.p-38{padding:38rem!important}.pt-38{padding-top:38rem!important}.pb-38{padding-bottom:38rem!important}.pl-38{padding-left:38rem!important}.pr-38{padding-right:38rem!important}.w-39{width:39rem!important}.h-39{height:39rem!important}.m-39{margin:39rem!important}.mt-39{margin-top:39rem!important}.mb-39{margin-bottom:39rem!important}.ml-39{margin-left:39rem!important}.mr-39{margin-right:39rem!important}.p-39{padding:39rem!important}.pt-39{padding-top:39rem!important}.pb-39{padding-bottom:39rem!important}.pl-39{padding-left:39rem!important}.pr-39{padding-right:39rem!important}.w-40{width:40rem!important}.h-40{height:40rem!important}.m-40{margin:40rem!important}.mt-40{margin-top:40rem!important}.mb-40{margin-bottom:40rem!important}.ml-40{margin-left:40rem!important}.mr-40{margin-right:40rem!important}.p-40{padding:40rem!important}.pt-40{padding-top:40rem!important}.pb-40{padding-bottom:40rem!important}.pl-40{padding-left:40rem!important}.pr-40{padding-right:40rem!important}.w-41{width:41rem!important}.h-41{height:41rem!important}.m-41{margin:41rem!important}.mt-41{margin-top:41rem!important}.mb-41{margin-bottom:41rem!important}.ml-41{margin-left:41rem!important}.mr-41{margin-right:41rem!important}.p-41{padding:41rem!important}.pt-41{padding-top:41rem!important}.pb-41{padding-bottom:41rem!important}.pl-41{padding-left:41rem!important}.pr-41{padding-right:41rem!important}.w-42{width:42rem!important}.h-42{height:42rem!important}.m-42{margin:42rem!important}.mt-42{margin-top:42rem!important}.mb-42{margin-bottom:42rem!important}.ml-42{margin-left:42rem!important}.mr-42{margin-right:42rem!important}.p-42{padding:42rem!important}.pt-42{padding-top:42rem!important}.pb-42{padding-bottom:42rem!important}.pl-42{padding-left:42rem!important}.pr-42{padding-right:42rem!important}.w-43{width:43rem!important}.h-43{height:43rem!important}.m-43{margin:43rem!important}.mt-43{margin-top:43rem!important}.mb-43{margin-bottom:43rem!important}.ml-43{margin-left:43rem!important}.mr-43{margin-right:43rem!important}.p-43{padding:43rem!important}.pt-43{padding-top:43rem!important}.pb-43{padding-bottom:43rem!important}.pl-43{padding-left:43rem!important}.pr-43{padding-right:43rem!important}.w-44{width:44rem!important}.h-44{height:44rem!important}.m-44{margin:44rem!important}.mt-44{margin-top:44rem!important}.mb-44{margin-bottom:44rem!important}.ml-44{margin-left:44rem!important}.mr-44{margin-right:44rem!important}.p-44{padding:44rem!important}.pt-44{padding-top:44rem!important}.pb-44{padding-bottom:44rem!important}.pl-44{padding-left:44rem!important}.pr-44{padding-right:44rem!important}.w-45{width:45rem!important}.h-45{height:45rem!important}.m-45{margin:45rem!important}.mt-45{margin-top:45rem!important}.mb-45{margin-bottom:45rem!important}.ml-45{margin-left:45rem!important}.mr-45{margin-right:45rem!important}.p-45{padding:45rem!important}.pt-45{padding-top:45rem!important}.pb-45{padding-bottom:45rem!important}.pl-45{padding-left:45rem!important}.pr-45{padding-right:45rem!important}.w-46{width:46rem!important}.h-46{height:46rem!important}.m-46{margin:46rem!important}.mt-46{margin-top:46rem!important}.mb-46{margin-bottom:46rem!important}.ml-46{margin-left:46rem!important}.mr-46{margin-right:46rem!important}.p-46{padding:46rem!important}.pt-46{padding-top:46rem!important}.pb-46{padding-bottom:46rem!important}.pl-46{padding-left:46rem!important}.pr-46{padding-right:46rem!important}.w-47{width:47rem!important}.h-47{height:47rem!important}.m-47{margin:47rem!important}.mt-47{margin-top:47rem!important}.mb-47{margin-bottom:47rem!important}.ml-47{margin-left:47rem!important}.mr-47{margin-right:47rem!important}.p-47{padding:47rem!important}.pt-47{padding-top:47rem!important}.pb-47{padding-bottom:47rem!important}.pl-47{padding-left:47rem!important}.pr-47{padding-right:47rem!important}.w-48{width:48rem!important}.h-48{height:48rem!important}.m-48{margin:48rem!important}.mt-48{margin-top:48rem!important}.mb-48{margin-bottom:48rem!important}.ml-48{margin-left:48rem!important}.mr-48{margin-right:48rem!important}.p-48{padding:48rem!important}.pt-48{padding-top:48rem!important}.pb-48{padding-bottom:48rem!important}.pl-48{padding-left:48rem!important}.pr-48{padding-right:48rem!important}.w-49{width:49rem!important}.h-49{height:49rem!important}.m-49{margin:49rem!important}.mt-49{margin-top:49rem!important}.mb-49{margin-bottom:49rem!important}.ml-49{margin-left:49rem!important}.mr-49{margin-right:49rem!important}.p-49{padding:49rem!important}.pt-49{padding-top:49rem!important}.pb-49{padding-bottom:49rem!important}.pl-49{padding-left:49rem!important}.pr-49{padding-right:49rem!important}.w-50{width:50rem!important}.h-50{height:50rem!important}.m-50{margin:50rem!important}.mt-50{margin-top:50rem!important}.mb-50{margin-bottom:50rem!important}.ml-50{margin-left:50rem!important}.mr-50{margin-right:50rem!important}.p-50{padding:50rem!important}.pt-50{padding-top:50rem!important}.pb-50{padding-bottom:50rem!important}.pl-50{padding-left:50rem!important}.pr-50{padding-right:50rem!important}.w-51{width:51rem!important}.h-51{height:51rem!important}.m-51{margin:51rem!important}.mt-51{margin-top:51rem!important}.mb-51{margin-bottom:51rem!important}.ml-51{margin-left:51rem!important}.mr-51{margin-right:51rem!important}.p-51{padding:51rem!important}.pt-51{padding-top:51rem!important}.pb-51{padding-bottom:51rem!important}.pl-51{padding-left:51rem!important}.pr-51{padding-right:51rem!important}.w-52{width:52rem!important}.h-52{height:52rem!important}.m-52{margin:52rem!important}.mt-52{margin-top:52rem!important}.mb-52{margin-bottom:52rem!important}.ml-52{margin-left:52rem!important}.mr-52{margin-right:52rem!important}.p-52{padding:52rem!important}.pt-52{padding-top:52rem!important}.pb-52{padding-bottom:52rem!important}.pl-52{padding-left:52rem!important}.pr-52{padding-right:52rem!important}.w-53{width:53rem!important}.h-53{height:53rem!important}.m-53{margin:53rem!important}.mt-53{margin-top:53rem!important}.mb-53{margin-bottom:53rem!important}.ml-53{margin-left:53rem!important}.mr-53{margin-right:53rem!important}.p-53{padding:53rem!important}.pt-53{padding-top:53rem!important}.pb-53{padding-bottom:53rem!important}.pl-53{padding-left:53rem!important}.pr-53{padding-right:53rem!important}.w-54{width:54rem!important}.h-54{height:54rem!important}.m-54{margin:54rem!important}.mt-54{margin-top:54rem!important}.mb-54{margin-bottom:54rem!important}.ml-54{margin-left:54rem!important}.mr-54{margin-right:54rem!important}.p-54{padding:54rem!important}.pt-54{padding-top:54rem!important}.pb-54{padding-bottom:54rem!important}.pl-54{padding-left:54rem!important}.pr-54{padding-right:54rem!important}.w-55{width:55rem!important}.h-55{height:55rem!important}.m-55{margin:55rem!important}.mt-55{margin-top:55rem!important}.mb-55{margin-bottom:55rem!important}.ml-55{margin-left:55rem!important}.mr-55{margin-right:55rem!important}.p-55{padding:55rem!important}.pt-55{padding-top:55rem!important}.pb-55{padding-bottom:55rem!important}.pl-55{padding-left:55rem!important}.pr-55{padding-right:55rem!important}.w-56{width:56rem!important}.h-56{height:56rem!important}.m-56{margin:56rem!important}.mt-56{margin-top:56rem!important}.mb-56{margin-bottom:56rem!important}.ml-56{margin-left:56rem!important}.mr-56{margin-right:56rem!important}.p-56{padding:56rem!important}.pt-56{padding-top:56rem!important}.pb-56{padding-bottom:56rem!important}.pl-56{padding-left:56rem!important}.pr-56{padding-right:56rem!important}.w-57{width:57rem!important}.h-57{height:57rem!important}.m-57{margin:57rem!important}.mt-57{margin-top:57rem!important}.mb-57{margin-bottom:57rem!important}.ml-57{margin-left:57rem!important}.mr-57{margin-right:57rem!important}.p-57{padding:57rem!important}.pt-57{padding-top:57rem!important}.pb-57{padding-bottom:57rem!important}.pl-57{padding-left:57rem!important}.pr-57{padding-right:57rem!important}.w-58{width:58rem!important}.h-58{height:58rem!important}.m-58{margin:58rem!important}.mt-58{margin-top:58rem!important}.mb-58{margin-bottom:58rem!important}.ml-58{margin-left:58rem!important}.mr-58{margin-right:58rem!important}.p-58{padding:58rem!important}.pt-58{padding-top:58rem!important}.pb-58{padding-bottom:58rem!important}.pl-58{padding-left:58rem!important}.pr-58{padding-right:58rem!important}.w-59{width:59rem!important}.h-59{height:59rem!important}.m-59{margin:59rem!important}.mt-59{margin-top:59rem!important}.mb-59{margin-bottom:59rem!important}.ml-59{margin-left:59rem!important}.mr-59{margin-right:59rem!important}.p-59{padding:59rem!important}.pt-59{padding-top:59rem!important}.pb-59{padding-bottom:59rem!important}.pl-59{padding-left:59rem!important}.pr-59{padding-right:59rem!important}.w-60{width:60rem!important}.h-60{height:60rem!important}.m-60{margin:60rem!important}.mt-60{margin-top:60rem!important}.mb-60{margin-bottom:60rem!important}.ml-60{margin-left:60rem!important}.mr-60{margin-right:60rem!important}.p-60{padding:60rem!important}.pt-60{padding-top:60rem!important}.pb-60{padding-bottom:60rem!important}.pl-60{padding-left:60rem!important}.pr-60{padding-right:60rem!important}.w-61{width:61rem!important}.h-61{height:61rem!important}.m-61{margin:61rem!important}.mt-61{margin-top:61rem!important}.mb-61{margin-bottom:61rem!important}.ml-61{margin-left:61rem!important}.mr-61{margin-right:61rem!important}.p-61{padding:61rem!important}.pt-61{padding-top:61rem!important}.pb-61{padding-bottom:61rem!important}.pl-61{padding-left:61rem!important}.pr-61{padding-right:61rem!important}.w-62{width:62rem!important}.h-62{height:62rem!important}.m-62{margin:62rem!important}.mt-62{margin-top:62rem!important}.mb-62{margin-bottom:62rem!important}.ml-62{margin-left:62rem!important}.mr-62{margin-right:62rem!important}.p-62{padding:62rem!important}.pt-62{padding-top:62rem!important}.pb-62{padding-bottom:62rem!important}.pl-62{padding-left:62rem!important}.pr-62{padding-right:62rem!important}.w-63{width:63rem!important}.h-63{height:63rem!important}.m-63{margin:63rem!important}.mt-63{margin-top:63rem!important}.mb-63{margin-bottom:63rem!important}.ml-63{margin-left:63rem!important}.mr-63{margin-right:63rem!important}.p-63{padding:63rem!important}.pt-63{padding-top:63rem!important}.pb-63{padding-bottom:63rem!important}.pl-63{padding-left:63rem!important}.pr-63{padding-right:63rem!important}.w-64{width:64rem!important}.h-64{height:64rem!important}.m-64{margin:64rem!important}.mt-64{margin-top:64rem!important}.mb-64{margin-bottom:64rem!important}.ml-64{margin-left:64rem!important}.mr-64{margin-right:64rem!important}.p-64{padding:64rem!important}.pt-64{padding-top:64rem!important}.pb-64{padding-bottom:64rem!important}.pl-64{padding-left:64rem!important}.pr-64{padding-right:64rem!important}.w-65{width:65rem!important}.h-65{height:65rem!important}.m-65{margin:65rem!important}.mt-65{margin-top:65rem!important}.mb-65{margin-bottom:65rem!important}.ml-65{margin-left:65rem!important}.mr-65{margin-right:65rem!important}.p-65{padding:65rem!important}.pt-65{padding-top:65rem!important}.pb-65{padding-bottom:65rem!important}.pl-65{padding-left:65rem!important}.pr-65{padding-right:65rem!important}.w-66{width:66rem!important}.h-66{height:66rem!important}.m-66{margin:66rem!important}.mt-66{margin-top:66rem!important}.mb-66{margin-bottom:66rem!important}.ml-66{margin-left:66rem!important}.mr-66{margin-right:66rem!important}.p-66{padding:66rem!important}.pt-66{padding-top:66rem!important}.pb-66{padding-bottom:66rem!important}.pl-66{padding-left:66rem!important}.pr-66{padding-right:66rem!important}.w-67{width:67rem!important}.h-67{height:67rem!important}.m-67{margin:67rem!important}.mt-67{margin-top:67rem!important}.mb-67{margin-bottom:67rem!important}.ml-67{margin-left:67rem!important}.mr-67{margin-right:67rem!important}.p-67{padding:67rem!important}.pt-67{padding-top:67rem!important}.pb-67{padding-bottom:67rem!important}.pl-67{padding-left:67rem!important}.pr-67{padding-right:67rem!important}.w-68{width:68rem!important}.h-68{height:68rem!important}.m-68{margin:68rem!important}.mt-68{margin-top:68rem!important}.mb-68{margin-bottom:68rem!important}.ml-68{margin-left:68rem!important}.mr-68{margin-right:68rem!important}.p-68{padding:68rem!important}.pt-68{padding-top:68rem!important}.pb-68{padding-bottom:68rem!important}.pl-68{padding-left:68rem!important}.pr-68{padding-right:68rem!important}.w-69{width:69rem!important}.h-69{height:69rem!important}.m-69{margin:69rem!important}.mt-69{margin-top:69rem!important}.mb-69{margin-bottom:69rem!important}.ml-69{margin-left:69rem!important}.mr-69{margin-right:69rem!important}.p-69{padding:69rem!important}.pt-69{padding-top:69rem!important}.pb-69{padding-bottom:69rem!important}.pl-69{padding-left:69rem!important}.pr-69{padding-right:69rem!important}.w-70{width:70rem!important}.h-70{height:70rem!important}.m-70{margin:70rem!important}.mt-70{margin-top:70rem!important}.mb-70{margin-bottom:70rem!important}.ml-70{margin-left:70rem!important}.mr-70{margin-right:70rem!important}.p-70{padding:70rem!important}.pt-70{padding-top:70rem!important}.pb-70{padding-bottom:70rem!important}.pl-70{padding-left:70rem!important}.pr-70{padding-right:70rem!important}.w-71{width:71rem!important}.h-71{height:71rem!important}.m-71{margin:71rem!important}.mt-71{margin-top:71rem!important}.mb-71{margin-bottom:71rem!important}.ml-71{margin-left:71rem!important}.mr-71{margin-right:71rem!important}.p-71{padding:71rem!important}.pt-71{padding-top:71rem!important}.pb-71{padding-bottom:71rem!important}.pl-71{padding-left:71rem!important}.pr-71{padding-right:71rem!important}.w-72{width:72rem!important}.h-72{height:72rem!important}.m-72{margin:72rem!important}.mt-72{margin-top:72rem!important}.mb-72{margin-bottom:72rem!important}.ml-72{margin-left:72rem!important}.mr-72{margin-right:72rem!important}.p-72{padding:72rem!important}.pt-72{padding-top:72rem!important}.pb-72{padding-bottom:72rem!important}.pl-72{padding-left:72rem!important}.pr-72{padding-right:72rem!important}.w-73{width:73rem!important}.h-73{height:73rem!important}.m-73{margin:73rem!important}.mt-73{margin-top:73rem!important}.mb-73{margin-bottom:73rem!important}.ml-73{margin-left:73rem!important}.mr-73{margin-right:73rem!important}.p-73{padding:73rem!important}.pt-73{padding-top:73rem!important}.pb-73{padding-bottom:73rem!important}.pl-73{padding-left:73rem!important}.pr-73{padding-right:73rem!important}.w-74{width:74rem!important}.h-74{height:74rem!important}.m-74{margin:74rem!important}.mt-74{margin-top:74rem!important}.mb-74{margin-bottom:74rem!important}.ml-74{margin-left:74rem!important}.mr-74{margin-right:74rem!important}.p-74{padding:74rem!important}.pt-74{padding-top:74rem!important}.pb-74{padding-bottom:74rem!important}.pl-74{padding-left:74rem!important}.pr-74{padding-right:74rem!important}.w-75{width:75rem!important}.h-75{height:75rem!important}.m-75{margin:75rem!important}.mt-75{margin-top:75rem!important}.mb-75{margin-bottom:75rem!important}.ml-75{margin-left:75rem!important}.mr-75{margin-right:75rem!important}.p-75{padding:75rem!important}.pt-75{padding-top:75rem!important}.pb-75{padding-bottom:75rem!important}.pl-75{padding-left:75rem!important}.pr-75{padding-right:75rem!important}.w-76{width:76rem!important}.h-76{height:76rem!important}.m-76{margin:76rem!important}.mt-76{margin-top:76rem!important}.mb-76{margin-bottom:76rem!important}.ml-76{margin-left:76rem!important}.mr-76{margin-right:76rem!important}.p-76{padding:76rem!important}.pt-76{padding-top:76rem!important}.pb-76{padding-bottom:76rem!important}.pl-76{padding-left:76rem!important}.pr-76{padding-right:76rem!important}.w-77{width:77rem!important}.h-77{height:77rem!important}.m-77{margin:77rem!important}.mt-77{margin-top:77rem!important}.mb-77{margin-bottom:77rem!important}.ml-77{margin-left:77rem!important}.mr-77{margin-right:77rem!important}.p-77{padding:77rem!important}.pt-77{padding-top:77rem!important}.pb-77{padding-bottom:77rem!important}.pl-77{padding-left:77rem!important}.pr-77{padding-right:77rem!important}.w-78{width:78rem!important}.h-78{height:78rem!important}.m-78{margin:78rem!important}.mt-78{margin-top:78rem!important}.mb-78{margin-bottom:78rem!important}.ml-78{margin-left:78rem!important}.mr-78{margin-right:78rem!important}.p-78{padding:78rem!important}.pt-78{padding-top:78rem!important}.pb-78{padding-bottom:78rem!important}.pl-78{padding-left:78rem!important}.pr-78{padding-right:78rem!important}.w-79{width:79rem!important}.h-79{height:79rem!important}.m-79{margin:79rem!important}.mt-79{margin-top:79rem!important}.mb-79{margin-bottom:79rem!important}.ml-79{margin-left:79rem!important}.mr-79{margin-right:79rem!important}.p-79{padding:79rem!important}.pt-79{padding-top:79rem!important}.pb-79{padding-bottom:79rem!important}.pl-79{padding-left:79rem!important}.pr-79{padding-right:79rem!important}.w-80{width:80rem!important}.h-80{height:80rem!important}.m-80{margin:80rem!important}.mt-80{margin-top:80rem!important}.mb-80{margin-bottom:80rem!important}.ml-80{margin-left:80rem!important}.mr-80{margin-right:80rem!important}.p-80{padding:80rem!important}.pt-80{padding-top:80rem!important}.pb-80{padding-bottom:80rem!important}.pl-80{padding-left:80rem!important}.pr-80{padding-right:80rem!important}.w-81{width:81rem!important}.h-81{height:81rem!important}.m-81{margin:81rem!important}.mt-81{margin-top:81rem!important}.mb-81{margin-bottom:81rem!important}.ml-81{margin-left:81rem!important}.mr-81{margin-right:81rem!important}.p-81{padding:81rem!important}.pt-81{padding-top:81rem!important}.pb-81{padding-bottom:81rem!important}.pl-81{padding-left:81rem!important}.pr-81{padding-right:81rem!important}.w-82{width:82rem!important}.h-82{height:82rem!important}.m-82{margin:82rem!important}.mt-82{margin-top:82rem!important}.mb-82{margin-bottom:82rem!important}.ml-82{margin-left:82rem!important}.mr-82{margin-right:82rem!important}.p-82{padding:82rem!important}.pt-82{padding-top:82rem!important}.pb-82{padding-bottom:82rem!important}.pl-82{padding-left:82rem!important}.pr-82{padding-right:82rem!important}.w-83{width:83rem!important}.h-83{height:83rem!important}.m-83{margin:83rem!important}.mt-83{margin-top:83rem!important}.mb-83{margin-bottom:83rem!important}.ml-83{margin-left:83rem!important}.mr-83{margin-right:83rem!important}.p-83{padding:83rem!important}.pt-83{padding-top:83rem!important}.pb-83{padding-bottom:83rem!important}.pl-83{padding-left:83rem!important}.pr-83{padding-right:83rem!important}.w-84{width:84rem!important}.h-84{height:84rem!important}.m-84{margin:84rem!important}.mt-84{margin-top:84rem!important}.mb-84{margin-bottom:84rem!important}.ml-84{margin-left:84rem!important}.mr-84{margin-right:84rem!important}.p-84{padding:84rem!important}.pt-84{padding-top:84rem!important}.pb-84{padding-bottom:84rem!important}.pl-84{padding-left:84rem!important}.pr-84{padding-right:84rem!important}.w-85{width:85rem!important}.h-85{height:85rem!important}.m-85{margin:85rem!important}.mt-85{margin-top:85rem!important}.mb-85{margin-bottom:85rem!important}.ml-85{margin-left:85rem!important}.mr-85{margin-right:85rem!important}.p-85{padding:85rem!important}.pt-85{padding-top:85rem!important}.pb-85{padding-bottom:85rem!important}.pl-85{padding-left:85rem!important}.pr-85{padding-right:85rem!important}.w-86{width:86rem!important}.h-86{height:86rem!important}.m-86{margin:86rem!important}.mt-86{margin-top:86rem!important}.mb-86{margin-bottom:86rem!important}.ml-86{margin-left:86rem!important}.mr-86{margin-right:86rem!important}.p-86{padding:86rem!important}.pt-86{padding-top:86rem!important}.pb-86{padding-bottom:86rem!important}.pl-86{padding-left:86rem!important}.pr-86{padding-right:86rem!important}.w-87{width:87rem!important}.h-87{height:87rem!important}.m-87{margin:87rem!important}.mt-87{margin-top:87rem!important}.mb-87{margin-bottom:87rem!important}.ml-87{margin-left:87rem!important}.mr-87{margin-right:87rem!important}.p-87{padding:87rem!important}.pt-87{padding-top:87rem!important}.pb-87{padding-bottom:87rem!important}.pl-87{padding-left:87rem!important}.pr-87{padding-right:87rem!important}.w-88{width:88rem!important}.h-88{height:88rem!important}.m-88{margin:88rem!important}.mt-88{margin-top:88rem!important}.mb-88{margin-bottom:88rem!important}.ml-88{margin-left:88rem!important}.mr-88{margin-right:88rem!important}.p-88{padding:88rem!important}.pt-88{padding-top:88rem!important}.pb-88{padding-bottom:88rem!important}.pl-88{padding-left:88rem!important}.pr-88{padding-right:88rem!important}.w-89{width:89rem!important}.h-89{height:89rem!important}.m-89{margin:89rem!important}.mt-89{margin-top:89rem!important}.mb-89{margin-bottom:89rem!important}.ml-89{margin-left:89rem!important}.mr-89{margin-right:89rem!important}.p-89{padding:89rem!important}.pt-89{padding-top:89rem!important}.pb-89{padding-bottom:89rem!important}.pl-89{padding-left:89rem!important}.pr-89{padding-right:89rem!important}.w-90{width:90rem!important}.h-90{height:90rem!important}.m-90{margin:90rem!important}.mt-90{margin-top:90rem!important}.mb-90{margin-bottom:90rem!important}.ml-90{margin-left:90rem!important}.mr-90{margin-right:90rem!important}.p-90{padding:90rem!important}.pt-90{padding-top:90rem!important}.pb-90{padding-bottom:90rem!important}.pl-90{padding-left:90rem!important}.pr-90{padding-right:90rem!important}.w-91{width:91rem!important}.h-91{height:91rem!important}.m-91{margin:91rem!important}.mt-91{margin-top:91rem!important}.mb-91{margin-bottom:91rem!important}.ml-91{margin-left:91rem!important}.mr-91{margin-right:91rem!important}.p-91{padding:91rem!important}.pt-91{padding-top:91rem!important}.pb-91{padding-bottom:91rem!important}.pl-91{padding-left:91rem!important}.pr-91{padding-right:91rem!important}.w-92{width:92rem!important}.h-92{height:92rem!important}.m-92{margin:92rem!important}.mt-92{margin-top:92rem!important}.mb-92{margin-bottom:92rem!important}.ml-92{margin-left:92rem!important}.mr-92{margin-right:92rem!important}.p-92{padding:92rem!important}.pt-92{padding-top:92rem!important}.pb-92{padding-bottom:92rem!important}.pl-92{padding-left:92rem!important}.pr-92{padding-right:92rem!important}.w-93{width:93rem!important}.h-93{height:93rem!important}.m-93{margin:93rem!important}.mt-93{margin-top:93rem!important}.mb-93{margin-bottom:93rem!important}.ml-93{margin-left:93rem!important}.mr-93{margin-right:93rem!important}.p-93{padding:93rem!important}.pt-93{padding-top:93rem!important}.pb-93{padding-bottom:93rem!important}.pl-93{padding-left:93rem!important}.pr-93{padding-right:93rem!important}.w-94{width:94rem!important}.h-94{height:94rem!important}.m-94{margin:94rem!important}.mt-94{margin-top:94rem!important}.mb-94{margin-bottom:94rem!important}.ml-94{margin-left:94rem!important}.mr-94{margin-right:94rem!important}.p-94{padding:94rem!important}.pt-94{padding-top:94rem!important}.pb-94{padding-bottom:94rem!important}.pl-94{padding-left:94rem!important}.pr-94{padding-right:94rem!important}.w-95{width:95rem!important}.h-95{height:95rem!important}.m-95{margin:95rem!important}.mt-95{margin-top:95rem!important}.mb-95{margin-bottom:95rem!important}.ml-95{margin-left:95rem!important}.mr-95{margin-right:95rem!important}.p-95{padding:95rem!important}.pt-95{padding-top:95rem!important}.pb-95{padding-bottom:95rem!important}.pl-95{padding-left:95rem!important}.pr-95{padding-right:95rem!important}.w-96{width:96rem!important}.h-96{height:96rem!important}.m-96{margin:96rem!important}.mt-96{margin-top:96rem!important}.mb-96{margin-bottom:96rem!important}.ml-96{margin-left:96rem!important}.mr-96{margin-right:96rem!important}.p-96{padding:96rem!important}.pt-96{padding-top:96rem!important}.pb-96{padding-bottom:96rem!important}.pl-96{padding-left:96rem!important}.pr-96{padding-right:96rem!important}.w-97{width:97rem!important}.h-97{height:97rem!important}.m-97{margin:97rem!important}.mt-97{margin-top:97rem!important}.mb-97{margin-bottom:97rem!important}.ml-97{margin-left:97rem!important}.mr-97{margin-right:97rem!important}.p-97{padding:97rem!important}.pt-97{padding-top:97rem!important}.pb-97{padding-bottom:97rem!important}.pl-97{padding-left:97rem!important}.pr-97{padding-right:97rem!important}.w-98{width:98rem!important}.h-98{height:98rem!important}.m-98{margin:98rem!important}.mt-98{margin-top:98rem!important}.mb-98{margin-bottom:98rem!important}.ml-98{margin-left:98rem!important}.mr-98{margin-right:98rem!important}.p-98{padding:98rem!important}.pt-98{padding-top:98rem!important}.pb-98{padding-bottom:98rem!important}.pl-98{padding-left:98rem!important}.pr-98{padding-right:98rem!important}.w-99{width:99rem!important}.h-99{height:99rem!important}.m-99{margin:99rem!important}.mt-99{margin-top:99rem!important}.mb-99{margin-bottom:99rem!important}.ml-99{margin-left:99rem!important}.mr-99{margin-right:99rem!important}.p-99{padding:99rem!important}.pt-99{padding-top:99rem!important}.pb-99{padding-bottom:99rem!important}.pl-99{padding-left:99rem!important}.pr-99{padding-right:99rem!important}*{box-sizing:border-box}html{font-size:4px}.icon-label{display:flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:4px}.icon-stream-chat{width:14px;height:14px;border:4px solid #4330fc;border-radius:100%}.icon-stream-dm{height:14px;width:14px;border:6px solid #4330fc;border-radius:100%}.icon-collection{height:12px;width:12px;position:relative;background-color:#6fdc74;border-radius:1px}.icon-collection:after{height:6px;width:6px;position:absolute;top:3px;left:3px;z-index:1;content:"";background-color:#fff;border-radius:100%}.icon-collection-comment:before{position:absolute;top:4px;left:4px;z-index:2;content:"";border-radius:100%}.icon-collection-comment:before,.icon-collection-post{height:4px;width:4px;background-color:#6fdc74}.icon-panini{width:32px;height:32px;position:relative}.icon-panini:after{position:absolute;content:"";left:4px;top:8px;border-top:4px solid #000;border-bottom:4px solid #000;height:8px;width:24px}.icon-x{position:relative;display:inline-block;width:32px;height:32px}.icon-x:after,.icon-x:before{position:absolute;top:10px;width:24px;height:24px;border-top:5px solid #000;border-color:inherit;content:""}.icon-x:before{left:-4px;transform:rotate(45deg)}.icon-x:after{left:13px;transform:rotate(-45deg)}.icon-lus{position:relative;display:inline-block;width:12px;height:12px}.icon-lus:after,.icon-lus:before{position:absolute;width:12px;height:12px;content:""}.icon-lus:before{border-top:2px solid #000;border-color:inherit;top:5px}.icon-lus:after{border-left:2px solid #000;border-color:inherit;left:5px}.icon-ellipsis-wrapper{display:flex;justify-content:space-between;align-items:center;padding:0 1px}.icon-ellipsis-dot{width:2px;height:2px;background-color:#000}body{overflow:overlay}a{cursor:pointer}a.vanilla{text-decoration:none}ul.vanilla{list-style-type:none;padding:0;margin:0}ul.vanilla li{padding:0}form{margin:0}[class*=col-]{margin-bottom:0}.circle{padding:0;border-width:8px;height:30px;width:30px;position:relative;top:3px}.text-body,body,input[type=text],p,textarea{font-size:14px;line-height:24px;font-family:-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;color:#000}.btn,.h1,.h2,.h3,.h4,.h5,.text-heading,button,h1,h2,h3,h4,h5{font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif}.command-item,.text-host-breadcrumb,.text-mono,.text-mono-bold,.text-mono-light,.text-timestamp,label{font-family:Source Code Pro,Roboto mono,Courier New,monospace}.h1,h1{font-size:6rem;line-height:8rem}.h2,h2{font-size:5rem;line-height:6rem}.h3,h3{font-size:4rem!important;line-height:5rem!important}h4{font-size:14px;line-height:20px}.text-small,.text-small *{font-size:12px;line-height:20px}.text-squat,.text-squat *{font-size:16px;line-height:20px}.text-gray,.text-gray *{color:#9b9b9b}.text-black,.text-black *{color:#000!important}.text-red,.text-red *{color:#ee3124}.text-timestamp{font-size:9px;font-weight:300;line-height:16px}.text-host-breadcrumb{font-weight:300;font-size:12px;line-height:20px;text-decoration:none}.flex{display:flex}.inline-block{display:inline-block}.space-between{justify-content:space-between}.align-start{align-items:flex-start}.align-center{align-items:center}.justify-start{justify-content:flex-start!important}.justify-end{justify-content:flex-end}.justify-between{justify-content:between}.flex-column{flex-direction:column}.pointer{cursor:pointer}.hide{display:none}.relative{position:relative}.inline{display:inline}.block{display:block}input[type=text],label,textarea{font-size:14px;line-height:24px;border:none;outline:none;padding:0}.select-dropdown[disabled],button[disabled],input[disabled],label[disabled],select[disabled],textarea[disabled]{opacity:.4;border-color:#aaa}input.input-sm{font-size:3rem;padding:6px;border-width:1px}label{margin-bottom:2rem}.input-group{padding:10px}.input-group label{font-size:14px;font-weight:600}.btn{width:156px;padding:8px 0;margin-bottom:0;display:inline-block;position:relative;font-size:16px;font-weight:500;text-align:center;color:#fff}.btn,.btn-sm{line-height:20px}.btn-sm{font-size:14px;padding:2px 0;height:24px}.btn-icon{width:40px}.btn:focus{text-decoration:underline}.btn[disabled]{background-color:#c4c4c4;color:#fff;opacity:1}.btn-default{background-color:#e6e6e6;color:#000}.btn-primary{background-color:#4330fc}.btn-secondary{background-color:#6fdc74;color:#000}.btn-tertiary{background-color:#ee3124}.btn-spinner{position:absolute;display:inline-block;width:10px;height:10px;top:12px}.btn-spinner:after{position:absolute;width:8px;height:8px;bottom:0;content:"◠";animation:a linear 1s infinite;font-size:10px;line-height:10px}.btn-spinner-lg{font-size:32px;font-weight:700;color:#4330fc}.btn-text{padding:0;background-color:inherit}@keyframes a{to{transform:rotate(1turn)}}#root{height:100%;padding-bottom:20px}.header-container{padding-top:3rem;padding-bottom:3rem;position:relative}.header-mainrow{margin-top:2rem;margin-bottom:1rem}.header-breadcrumbs,.header-carpet{height:20px}.header-title,.header-title *{text-decoration:none;font-weight:600;margin:0}.header-link{font-size:14px;line-height:20px;font-weight:600;font-family:Work Sans,Helvetica Neue,Helvetica,Arial,sans-serif;text-decoration:none;text-transform:capitalize}.header-pending-panel{position:absolute;left:0;top:0;padding:8px 16px;background:#000;color:#fff}.header-notifications{width:14px;height:14px;padding-top:2px;margin-right:4px;border-radius:100%;background-color:#c4c4c4;color:#fff;font-size:9px;line-height:9px;text-align:center;transition:background-color 1s}.header-notifications-flash{background-color:#6fdc74;transition:background-color 1s}.page-status{position:absolute;right:10px;top:10px;border-radius:100%;height:18px;width:18px;background-color:#999}.header-pending-panel .page-status{position:relative;right:7px;top:1px}.page-status:after{content:"";background-color:#ccc;width:18px;height:18px;position:absolute;border-radius:100%;clip:rect(0,18px,18px,9px);animation:a 2s linear infinite}.page-status-primary{background-color:#4330fc}.page-status-primary:after{background-color:#d8d5fe}.page-status-secondary{background-color:#6fdc74}.page-status-secondary:after{background-color:#e2f8e3}.page-status-tertiary{background-color:#ee3124;cursor:pointer}.page-status-quaternary{background-color:#fd7a31}.page-status-quaternary:after{background-color:#febc98}.row{margin-left:-.5rem;margin-right:-.5rem}.flex-col-1{flex-basis:80px}.flex-col-1,.flex-col-2{padding-right:.5rem;padding-left:.5rem}.flex-col-2{flex-basis:160px}.flex-col-3{flex-basis:240px}.flex-col-3,.flex-col-4{padding-right:.5rem;padding-left:.5rem}.flex-col-4{flex-basis:320px}.flex-col-5{flex-basis:400px}.flex-col-5,.flex-col-6{padding-right:.5rem;padding-left:.5rem}.flex-col-6{flex-basis:480px}.flex-offset-1{margin-left:80px}.flex-offset-2{margin-left:160px}.flex-col-x{flex-basis:0;flex-grow:1;padding-right:.5rem;padding-left:.5rem}.chat-container{height:calc(100% - 106px)}.chat-container-inner,.chat-container-inner .container{height:100%}.flex-chat-scrollpane{flex-grow:1;flex-basis:0}.flex-chat-input{flex-basis:56px}.flex-chat-input .chat-sigil{margin-top:12px}.chat-container img{width:100%}textarea.chat-input-field{height:56px;padding:8px 10px;border:1px solid #e6e6e6;border-radius:1px;resize:none}.chat-input-field:placeholder{color:#b0b0b0}.chat-sep{text-align:center;font-weight:600;margin:4rem}.chat-msg-pending,.chat-msg-pending *{color:#aaa}.chat-msg-app,.chat-msg-app *{color:#9b9b9b}.chat-sigil{margin-right:2px}.cir-status{width:2rem;height:2rem;border-radius:100%;display:inline-block;position:relative;bottom:1px}.cir-green{background-color:#8eee9c}.cir-black,.cir-grey{background-color:#b0b0b0}.cir-red{background-color:#f44}.chat-scrollpane-view{display:flex;flex-direction:column;overflow-x:hidden!important;padding-bottom:15px}.chat-scrollpane-view>*{flex-shrink:0}.chat-scrollpane-view>:first-child{margin-top:auto!important}.scrollpane{height:600px;overflow-y:scroll;overflow-x:hidden;display:flex;flex-direction:column}.scrollpane>*{flex-shrink:0}.scrollpane>:first-child{margin-top:auto!important}input.collection-title,textarea.collection-post-edit{border:1px solid #b1b2b3}.collection-value-filled,input.collection-title:focus,textarea.collection-post-edit:focus{border-color:#000!important}input.collection-title{padding:10px 16px}textarea.collection-post-edit{height:352px;background:#fff;resize:none;padding:4rem}textarea.comment-edit{border:none;resize:none;padding:2rem;height:24rem;width:calc(100% - 26px);border:1px solid #aaa}.create-comment .usership{color:#000}.create-comment button{margin-left:calc(2rem + 18px)}div.coll-title,div.mod{font-size:6rem}.collection-index li.forum .meta-cont>div{float:left}.collection-index li.notes .da{position:absolute;margin-left:-12rem;margin-top:1rem}.collection-index .note-uuid{font-weight:inherit}.collection-index img{width:100%}.collection-index ul{list-style-type:none}.post img{width:100%}.post #edit{display:none}.collection-date{font-family:Source Code Pro,Roboto mono,Courier New,monospace;font-weight:300;font-size:3rem;line-height:5rem}.collection-title{position:relative}.collection-post:before,.collection-title:before{content:"";background-color:#6fdc74;border-radius:100%;width:4px;height:4px;position:absolute}.collection-post:before{margin-top:30px;margin-left:-18px}.collection-title:before{margin-top:22px;margin-left:-10rem}.collection-comment-avatar{position:absolute;left:-12rem;top:7px;width:32px;height:32px}.collection-post-actions{display:flex;align-items:center}.collection-comment-content{margin-left:26px}.form-mve .input-group-focused,.form-mve .input-group-focused input,.form-mve .input-group-focused textarea{background-color:#f6f6f6}.form-mve .input-group-error-message{display:none}.form-mve .input-group-error *{color:#ee3124}.form-mve .input-group-error input::placeholder{color:#ee3124;opacity:.3}.form-mve .input-group-error .input-group-error-message{display:block}.form-mve .btn-text{padding-left:3rem;padding-right:3rem}.form-mve .btn-text:focus span:first-child{text-decoration:underline}.command-page{padding-top:33px;position:relative}.command-row{height:48px;display:flex;align-items:center;position:relative;margin-bottom:27px}.command-input-placeholder-wrapper,input.command-menu-input{position:relative;border:none;outline:none;height:48px;font-size:20px;line-height:48px;font-family:Source Code Pro,Roboto mono,Courier New,monospace}input.command-menu-input{background-color:transparent;z-index:2;padding:0 9px;font-weight:500}input.command-menu-input[disabled]{opacity:1}.command-input-placeholder-wrapper{background-color:#f6f6f6}.command-input-placeholder-wrapper[disabled]{background-color:transparent}.command-input-placeholder-wrapper:after{content:attr(data-placeholder);position:absolute;top:0;left:0;right:0;z-index:1;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden;padding:0 9px;color:#9b9b9b;font-weight:400}.command-item{padding-top:3rem;padding-bottom:3rem;padding-left:9px;cursor:pointer;width:100%}.command-item-selected{background-color:#f6f6f6;font-weight:600}.command-help a{display:block}.profile-shipname{display:flex;align-items:center;font-size:28px;font-weight:600;height:64px;font-family:Source Code Pro,Roboto mono,Courier New,monospace}.profile-message-btn{background:#fff;display:inline-block}.profile-qr-desc{max-width:256px}@media (max-width:415px){.profile-avatar{display:flex;justify-content:center;flex-direction:column;align-items:center}}.inbox-page img{width:100%}.inbox-page .invite .btn{float:right}.inbox-page .collection-preview h1:first-child{display:none}.inbox-link{font-weight:500;color:#777}.inbox-link-active{color:#000} \ No newline at end of file diff --git a/web/landscape/js/index-min.js b/web/landscape/js/index-min.js index 378c14d2f..4354ef7b1 100644 --- a/web/landscape/js/index-min.js +++ b/web/landscape/js/index-min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define("index",t):t()}(0,function(){"use strict";var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function r(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}function a(e){return e&&e.default||e}var i=n(function(e){!function(t,r,n){if(t){for(var a,i={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},o={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},s={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},l={option:"alt",command:"meta",return:"enter",escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},u=1;u<20;++u)i[111+u]="f"+u;for(u=0;u<=9;++u)i[u+96]=u.toString();m.prototype.bind=function(e,t,r){return e=e instanceof Array?e:[e],this._bindMultiple.call(this,e,t,r),this},m.prototype.unbind=function(e,t){return this.bind.call(this,e,function(){},t)},m.prototype.trigger=function(e,t){return this._directMap[e+":"+t]&&this._directMap[e+":"+t]({},e),this},m.prototype.reset=function(){return this._callbacks={},this._directMap={},this},m.prototype.stopCallback=function(e,t){return!((" "+t.className+" ").indexOf(" mousetrap ")>-1)&&(!function e(t,n){return null!==t&&t!==r&&(t===n||e(t.parentNode,n))}(t,this.target)&&("INPUT"==t.tagName||"SELECT"==t.tagName||"TEXTAREA"==t.tagName||t.isContentEditable))},m.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)},m.addKeycodes=function(e){for(var t in e)e.hasOwnProperty(t)&&(i[t]=e[t]);a=null},m.init=function(){var e=m(r);for(var t in e)"_"!==t.charAt(0)&&(m[t]=function(t){return function(){return e[t].apply(e,arguments)}}(t))},m.init(),t.Mousetrap=m,e.exports&&(e.exports=m)}function c(e,t,r){e.addEventListener?e.addEventListener(t,r,!1):e.attachEvent("on"+t,r)}function f(e){if("keypress"==e.type){var t=String.fromCharCode(e.which);return e.shiftKey||(t=t.toLowerCase()),t}return i[e.which]?i[e.which]:o[e.which]?o[e.which]:String.fromCharCode(e.which).toLowerCase()}function d(e){return"shift"==e||"ctrl"==e||"alt"==e||"meta"==e}function h(e,t,r){return r||(r=function(){if(!a)for(var e in a={},i)e>95&&e<112||i.hasOwnProperty(e)&&(a[i[e]]=e);return a}()[e]?"keydown":"keypress"),"keypress"==r&&t.length&&(r="keydown"),r}function p(e,t){var r,n,a,i=[];for(r=function(e){return"+"===e?["+"]:(e=e.replace(/\+{2}/g,"+plus")).split("+")}(e),a=0;a1?g(e,s,r,n):(o=p(e,n),t._callbacks[o.key]=t._callbacks[o.key]||[],u(o.key,o.modifiers,{type:o.action},a,e,i),t._callbacks[o.key][a?"unshift":"push"]({callback:r,modifiers:o.modifiers,action:o.action,seq:a,level:i,combo:e}))}t._handleKey=function(e,t,r){var n,a=u(e,t,r),i={},c=0,f=!1;for(n=0;nvoid 0===typeof t.dataset.mousetrap&&("INPUT"==t.tagName||"SELECT"==t.tagName||"TEXTAREA"==t.tagName||t.contentEditable&&"true"==t.contentEditable)),Object.arrayify=(e=>{let t=[];return Object.keys(e).forEach(r=>{t.push({key:r,value:e[r]})}),t}),Object.cloneByProperty=((e,t)=>{let r=[];return e[t].forEach(n=>{let a={...e};a[t]=[n],r.push(a)}),r});var o=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;var u=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},r=0;r<10;r++)t["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var r,n,a=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),i=1;i2?r-2:0),a=2;a1?t-1:0),n=1;n2?r-2:0),a=2;a8)throw new Error("warningWithoutStack() currently supports at most 8 arguments.");if(!e){if("undefined"!=typeof console){var i=n.map(function(e){return""+e});i.unshift("Warning: "+t),Function.prototype.apply.call(console.error,console,i)}try{var o=0,s="Warning: "+t.replace(/%s/g,function(){return n[o++]});throw new Error(s)}catch(e){}}},T={};function C(e,t){var r=e.constructor,n=r&&(r.displayName||r.name)||"ReactClass",a=n+"."+t;T[a]||(E(!1,"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",t,n),T[a]=!0)}var D={isMounted:function(e){return!1},enqueueForceUpdate:function(e,t,r){C(e,"forceUpdate")},enqueueReplaceState:function(e,t,r,n){C(e,"replaceState")},enqueueSetState:function(e,t,r,n){C(e,"setState")}},N={};function S(e,t,r){this.props=e,this.context=t,this.refs=N,this.updater=r||D}Object.freeze(N),S.prototype.isReactComponent={},S.prototype.setState=function(e,t){"object"!=typeof e&&"function"!=typeof e&&null!=e&&w(!1,"setState(...): takes an object of state variables to update or a function which returns an object of state variables."),this.updater.enqueueSetState(this,e,t,"setState")},S.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};var M={isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]},I=function(e,t){Object.defineProperty(S.prototype,e,{get:function(){x(!1,"%s(...) is deprecated in plain JavaScript React classes. %s",t[0],t[1])}})};for(var R in M)M.hasOwnProperty(R)&&I(R,M[R]);function O(){}function L(e,t,r){this.props=e,this.context=t,this.refs=N,this.updater=r||D}O.prototype=S.prototype;var P=L.prototype=new O;P.constructor=L,t(P,S.prototype),P.isPureReactComponent=!0;var A={current:null,currentDispatcher:null},B=/^(.*)[\\\/]/,U=1;function j(e){if(null==e)return null;if("number"==typeof e.tag&&E(!1,"Received an unexpected object in getComponentName(). This is likely a bug in React. Please file an issue."),"function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case d:return"ConcurrentMode";case o:return"Fragment";case i:return"Portal";case l:return"Profiler";case s:return"StrictMode";case p:return"Suspense"}if("object"==typeof e)switch(e.$$typeof){case f:return"Context.Consumer";case c:return"Context.Provider";case h:return n=e,a=e.render,u="ForwardRef",g=a.displayName||a.name||"",n.displayName||(""!==g?u+"("+g+")":u);case m:return j(e.type);case b:var t=(r=e)._status===U?r._result:null;if(t)return j(t)}var r,n,a,u,g;return null}var z={},q=null;function F(e){q=e}z.getCurrentStack=null,z.getStackAddendum=function(){var e="";if(q){var t=j(q.type),r=q._owner;e+=function(e,t,r){var n="";if(t){var a=t.fileName,i=a.replace(B,"");if(/^index\./.test(i)){var o=a.match(B);if(o){var s=o[1];s&&(i=s.replace(B,"")+"/"+i)}}n=" (at "+i+":"+t.lineNumber+")"}else r&&(n=" (created by "+r+")");return"\n in "+(e||"Unknown")+n}(t,q._source,r&&j(r.type))}var n=z.getCurrentStack;return n&&(e+=n()||""),e};var H={ReactCurrentOwner:A,assign:t};t(H,{ReactDebugCurrentFrame:z,ReactComponentTreeHook:{}});var Z=function(e,t){if(!e){for(var r=H.ReactDebugCurrentFrame.getStackAddendum(),n=arguments.length,a=Array(n>2?n-2:0),i=2;i1){for(var c=Array(u),f=0;f.")}return t}(t);if(!ge[r]){ge[r]=!0;var n="";e&&e._owner&&e._owner!==A.current&&(n=" It was passed a child from "+j(e._owner.type)+"."),F(e),Z(!1,'Each child in an array or iterator should have a unique "key" prop.%s%s See https://fb.me/react-warning-keys for more information.',r,n),F(null)}}}function ye(e,t){if("object"==typeof e)if(Array.isArray(e))for(var r=0;r",i=" Did you accidentally export a JSX literal instead of a component?"):l=typeof e,Z(!1,"React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",l,i)}var u=J.apply(this,arguments);if(null==u)return u;if(n)for(var c=2;c is not supported and will be removed in a future major release. Did you mean to render instead?")),r.Provider},set:function(e){r.Provider=e}},_currentValue:{get:function(){return r._currentValue},set:function(e){r._currentValue=e}},_currentValue2:{get:function(){return r._currentValue2},set:function(e){r._currentValue2=e}},_threadCount:{get:function(){return r._threadCount},set:function(e){r._threadCount=e}},Consumer:{get:function(){return n||(n=!0,Z(!1,"Rendering is not supported and will be removed in a future major release. Did you mean to render instead?")),r.Consumer}}}),r.Consumer=i,r._currentRenderer=null,r._currentRenderer2=null,r},forwardRef:function(e){return null!=e&&e.$$typeof===m?E(!1,"forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):"function"!=typeof e?E(!1,"forwardRef requires a render function but was given %s.",null===e?"null":typeof e):0!==e.length&&2!==e.length&&E(!1,"forwardRef render functions accept exactly two parameters: props and ref. %s",1===e.length?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),null!=e&&(null!=e.defaultProps||null!=e.propTypes)&&E(!1,"forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?"),{$$typeof:h,render:e}},lazy:function(e){return{$$typeof:b,_ctor:e,_status:-1,_result:null}},memo:function(e,t){return pe(e)||E(!1,"memo: The first argument must be a component. Instead received: %s",null===e?"null":typeof e),{$$typeof:m,type:e,compare:void 0===t?null:t}},Fragment:o,StrictMode:s,Suspense:p,createElement:we,cloneElement:function(e,r,n){for(var a=function(e,r,n){null==e&&w(!1,"React.cloneElement(...): The argument must be a React element, but you passed %s.",e);var a=void 0,i=t({},e.props),o=e.key,s=e.ref,l=e._self,u=e._source,c=e._owner;if(null!=r){$(r)&&(s=r.ref,c=A.current),K(r)&&(o=""+r.key);var f=void 0;for(a in e.type&&e.type.defaultProps&&(f=e.type.defaultProps),r)G.call(r,a)&&!V.hasOwnProperty(a)&&(void 0===r[a]&&void 0!==f?i[a]=f[a]:i[a]=r[a])}var d=arguments.length-2;if(1===d)i.children=n;else if(d>1){for(var h=Array(d),p=0;p=t){n=e;break}e=e.next}while(e!==r);null===n?n=r:n===r&&(r=l,u()),(t=n.previous).next=n.previous=l,l.next=n,l.previous=t}}function f(){if(-1===i&&null!==r&&1===r.priorityLevel){s=!0;try{do{c()}while(null!==r&&1===r.priorityLevel)}finally{s=!1,null!==r?u():l=!1}}}function d(e){s=!0;var a=n;n=e;try{if(e)for(;null!==r;){var i=t.unstable_now();if(!(r.expirationTime<=i))break;do{c()}while(null!==r&&r.expirationTime<=i)}else if(null!==r)do{c()}while(null!==r&&!g())}finally{s=!1,n=a,null!==r?u():l=!1,f()}}var h,p,m,b,g,v=Date,y="function"==typeof setTimeout?setTimeout:void 0,_="function"==typeof clearTimeout?clearTimeout:void 0,w="function"==typeof requestAnimationFrame?requestAnimationFrame:void 0,k="function"==typeof cancelAnimationFrame?cancelAnimationFrame:void 0;function x(e){h=w(function(t){_(p),e(t)}),p=y(function(){k(h),e(t.unstable_now())},100)}if("object"==typeof performance&&"function"==typeof performance.now){var E=performance;t.unstable_now=function(){return E.now()}}else t.unstable_now=function(){return v.now()};if("undefined"!=typeof window&&window._schedMock){var T=window._schedMock;m=T[0],b=T[1],g=T[2]}else if("undefined"==typeof window||"function"!=typeof window.addEventListener){var C=null,D=-1,N=function(e,t){if(null!==C){var r=C;C=null;try{D=t,r(e)}finally{D=-1}}};m=function(e,t){-1!==D?setTimeout(m,0,e,t):(C=e,setTimeout(N,t,!0,t),setTimeout(N,1073741823,!1,1073741823))},b=function(){C=null},g=function(){return!1},t.unstable_now=function(){return-1===D?0:D}}else{"undefined"!=typeof console&&("function"!=typeof w&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof k&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));var S=null,M=!1,I=-1,R=!1,O=!1,L=0,P=33,A=33;g=function(){return L<=t.unstable_now()};var B="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(e){if(e.source===window&&e.data===B){M=!1,e=S;var r=I;S=null,I=-1;var n=t.unstable_now(),a=!1;if(0>=L-n){if(!(-1!==r&&r<=n))return R||(R=!0,x(U)),S=e,void(I=r);a=!0}if(null!==e){O=!0;try{e(a)}finally{O=!1}}}},!1);var U=function(e){if(null!==S){x(U);var t=e-L+A;tt&&(t=8),A=tt?window.postMessage(B,"*"):R||(R=!0,x(U))},b=function(){S=null,M=!1,I=-1}}t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,r){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=a,o=i;a=e,i=t.unstable_now();try{return r()}finally{a=n,i=o,f()}},t.unstable_scheduleCallback=function(e,n){var o=-1!==i?i:t.unstable_now();if("object"==typeof n&&null!==n&&"number"==typeof n.timeout)n=o+n.timeout;else switch(a){case 1:n=o+-1;break;case 2:n=o+250;break;case 5:n=o+1073741823;break;case 4:n=o+1e4;break;default:n=o+5e3}if(e={callback:e,priorityLevel:a,expirationTime:n,next:null,previous:null},null===r)r=e.next=e.previous=e,u();else{o=null;var s=r;do{if(s.expirationTime>n){o=s;break}s=s.next}while(s!==r);null===o?o=r:o===r&&(r=e,u()),(n=o.previous).next=o.previous=e,e.next=o,e.previous=n}return e},t.unstable_cancelCallback=function(e){var t=e.next;if(null!==t){if(t===e)r=null;else{e===r&&(r=t);var n=e.previous;n.next=t,t.previous=n}e.next=e.previous=null}},t.unstable_wrapCallback=function(e){var r=a;return function(){var n=a,o=i;a=r,i=t.unstable_now();try{return e.apply(this,arguments)}finally{a=n,i=o,f()}}},t.unstable_getCurrentPriorityLevel=function(){return a},t.unstable_shouldYield=function(){return!n&&(null!==r&&r.expirationTime=i){c=d;break}d=d.next}while(d!==f);null===c?c=f:c===f&&(f=u,y());var p=c.previous;p.next=c.previous=u,u.next=c,u.previous=p}}}function w(){if(-1===p&&null!==f&&f.priorityLevel===e){b=!0;try{do{_()}while(null!==f&&f.priorityLevel===e)}finally{b=!1,null!==f?y():g=!1}}}function k(e){b=!0;var r=d;d=e;try{if(e)for(;null!==f;){var n=t.unstable_now();if(!(f.expirationTime<=n))break;do{_()}while(null!==f&&f.expirationTime<=n)}else if(null!==f)do{_()}while(null!==f&&!D())}finally{b=!1,d=r,null!==f?y():g=!1,w()}}var x,E,T,C,D,N=Date,S="function"==typeof setTimeout?setTimeout:void 0,M="function"==typeof clearTimeout?clearTimeout:void 0,I="function"==typeof requestAnimationFrame?requestAnimationFrame:void 0,R="function"==typeof cancelAnimationFrame?cancelAnimationFrame:void 0,O=function(e){x=I(function(t){M(E),e(t)}),E=S(function(){R(x),e(t.unstable_now())},100)};if(v){var L=performance;t.unstable_now=function(){return L.now()}}else t.unstable_now=function(){return N.now()};if("undefined"!=typeof window&&window._schedMock){var P=window._schedMock;T=P[0],C=P[1],D=P[2]}else if("undefined"==typeof window||"function"!=typeof window.addEventListener){var A=null,B=-1,U=function(e,t){if(null!==A){var r=A;A=null;try{B=t,r(e)}finally{B=-1}}};T=function(e,t){-1!==B?setTimeout(T,0,e,t):(A=e,setTimeout(U,t,!0,t),setTimeout(U,1073741823,!1,1073741823))},C=function(){A=null},D=function(){return!1},t.unstable_now=function(){return-1===B?0:B}}else{"undefined"!=typeof console&&("function"!=typeof I&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof R&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));var j=null,z=!1,q=-1,F=!1,H=!1,Z=0,G=33,V=33;D=function(){return Z<=t.unstable_now()};var W="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(e){if(e.source===window&&e.data===W){z=!1;var r=j,n=q;j=null,q=-1;var a=t.unstable_now(),i=!1;if(Z-a<=0){if(!(-1!==n&&n<=a))return F||(F=!0,O(Y)),j=r,void(q=n);i=!0}if(null!==r){H=!0;try{r(i)}finally{H=!1}}}},!1);var Y=function(e){if(null!==j){O(Y);var t=e-Z+V;tb){_=w;break}w=w.next}while(w!==f);null===_?_=f:_===f&&(f=v,y());var k=_.previous;k.next=_.previous=v,v.next=_,v.previous=k}return v},t.unstable_cancelCallback=function(e){var t=e.next;if(null!==t){if(t===e)f=null;else{e===f&&(f=t);var r=e.previous;r.next=t,t.previous=r}e.next=e.previous=null}},t.unstable_wrapCallback=function(e){var r=h;return function(){var n=h,a=p;h=r,p=t.unstable_now();try{return e.apply(this,arguments)}finally{h=n,p=a,w()}}},t.unstable_getCurrentPriorityLevel=function(){return h},t.unstable_shouldYield=function(){return!d&&(null!==f&&f.expirationTimethis.eventPool.length&&this.eventPool.push(e)}function Oe(e){e.eventPool=[],e.getPooled=Ie,e.release=Re}u(Me.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=Ne)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=Ne)},persist:function(){this.isPersistent=Ne},isPersistent:Se,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=Se,this._dispatchInstances=this._dispatchListeners=null}}),Me.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},Me.extend=function(e){function t(){}function r(){return n.apply(this,arguments)}var n=this;t.prototype=n.prototype;var a=new t;return u(a,r.prototype),r.prototype=a,r.prototype.constructor=r,r.Interface=u({},n.Interface,e),r.extend=n.extend,Oe(r),r},Oe(Me);var Le=Me.extend({data:null}),Pe=Me.extend({data:null}),Ae=[9,13,27,32],Be=he&&"CompositionEvent"in window,Ue=null;he&&"documentMode"in document&&(Ue=document.documentMode);var je=he&&"TextEvent"in window&&!Ue,ze=he&&(!Be||Ue&&8=Ue),qe=String.fromCharCode(32),Fe={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},He=!1;function Ze(e,t){switch(e){case"keyup":return-1!==Ae.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function Ge(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Ve=!1;var We={eventTypes:Fe,extractEvents:function(e,t,r,n){var a=void 0,i=void 0;if(Be)e:{switch(e){case"compositionstart":a=Fe.compositionStart;break e;case"compositionend":a=Fe.compositionEnd;break e;case"compositionupdate":a=Fe.compositionUpdate;break e}a=void 0}else Ve?Ze(e,r)&&(a=Fe.compositionEnd):"keydown"===e&&229===r.keyCode&&(a=Fe.compositionStart);return a?(ze&&"ko"!==r.locale&&(Ve||a!==Fe.compositionStart?a===Fe.compositionEnd&&Ve&&(i=De()):(Te="value"in(Ee=n)?Ee.value:Ee.textContent,Ve=!0)),a=Le.getPooled(a,t,r,n),i?a.data=i:null!==(i=Ge(r))&&(a.data=i),de(a),i=a):i=null,(e=je?function(e,t){switch(e){case"compositionend":return Ge(t);case"keypress":return 32!==t.which?null:(He=!0,qe);case"textInput":return(e=t.data)===qe&&He?null:e;default:return null}}(e,r):function(e,t){if(Ve)return"compositionend"===e||!Be&&Ze(e,t)?(e=De(),Ce=Te=Ee=null,Ve=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1