This commit is contained in:
Henry Ault 2015-11-03 11:58:48 -08:00
commit c56f5cd577
42 changed files with 1034 additions and 719 deletions

View File

@ -8,42 +8,30 @@
/= talk-doc
/; |=(a=wain (turn a |=(b=cord [%txt "? {(trip b)}"])))
/: /===/pub/doc/talk/help /txt/
!:
::
::::
::
[. talk sole]
=> |% :: data structures
++ house ,[%3 house-3] :: full state
++ house ,[%4 house-4] :: full state
++ house-any :: app history
$% [%1 house-1] :: 1: talk
[%2 house-2] :: 2: talk
[%3 house-3] :: 3: talk
== ::
++ house-1 ::
$: stories=(map span story) :: conversations
general=(set bone) :: meta-subscribe
outbox=(pair ,@ud (map ,@ud thought)) :: urbit outbox
folks=(map ship human) :: human identities
shells=(map bone shell) :: interaction state
== ::
++ house-2 ::
$: stories=(map span story) :: conversations
general=(set bone) :: meta-subscribe
outbox=(pair ,@ud (map ,@ud thought)) :: urbit outbox
folks=(map ship human) :: human identities
shells=(map bone shell) :: interaction state
log=(map span ,@ud) :: logged to clay
$% [%3 house-3] :: 3: talk
[%4 house-4] :: 4: talk
== ::
++ house-3 ::
%+ cork house-4 |= house-4 :: modern house with
+<(stories (~(run by stories) story-3)) :: old stories
++ house-4 ::
$: stories=(map span story) :: conversations
general=(set bone) :: meta-subscribe
outbox=(pair ,@ud (map ,@ud thought)) :: urbit outbox
folks=(map ship human) :: human identities
shells=(map bone shell) :: interaction state
log=(map span ,@ud) :: logged to clay
nik=(map (set partner) char) ::
nak=(jug char (set partner)) ::
nik=(map (set partner) char) :: bound station glyphs
nak=(jug char (set partner)) :: station glyph lookup
== ::
++ story-3 (cork story |=(story +<(|10 &11.+<))) :: missing glyphers
++ story :: wire content
$: count=@ud :: (lent grams)
grams=(list telegram) :: all history
@ -53,9 +41,10 @@
sequence=(map partner ,@ud) :: partners heard
shape=config :: configuration
known=(map serial ,@ud) :: messages heard
guests=(map bone river) :: message followers
viewers=(set bone) :: presence followers
owners=(set bone) :: config followers
gramsers=(map bone river) :: message followers
groupers=(set bone) :: presence followers
cabalers=(set bone) :: config followers
glyphers=(set bone) :: glyph followers
== ::
++ shell :: console session
$: her=ship :: client identity
@ -64,7 +53,7 @@
say=sole-share :: console state
active=(unit (set partner)) :: active targets
passive=(set partner) :: passive targets
guests=register :: presence mirror
owners=register :: presence mirror
harbor=(map span (pair posture cord)) :: stations mirror
system=cabal :: config mirror
== ::
@ -307,6 +296,7 @@
[['[' ']'] u.active.she]
=+ cha=(~(get by nik) q.rew)
?^ cha ~[u.cha ' ']
:: ~& [rew nik nak]
=+ por=~(te-prom te man.she q.rew)
(weld `tape`[p.p.rew por] `tape`[q.p.rew ' ' ~])
::
@ -693,15 +683,15 @@
++ sh-repo-group-here :: update local
|= loc=atlas
^+ +>
=+ cul=(sh-repo-atlas-diff p.guests.she loc)
=. p.guests.she loc
=+ cul=(sh-repo-atlas-diff p.owners.she loc)
=. p.owners.she loc
(sh-repo-group-diff-here "" cul)
::
++ sh-repo-group-there :: update foreign
|= yid=(map partner atlas)
=+ day=(sh-repo-rogue-diff q.guests.she yid)
=+ dun=q.guests.she
=. q.guests.she yid
=+ day=(sh-repo-rogue-diff q.owners.she yid)
=+ dun=q.owners.she
=. q.owners.she yid
=. +>.$
|- ^+ +>.^$
?~ old.day +>.^$
@ -749,6 +739,18 @@
?~ gaz +>
$(gaz t.gaz, num +(num), +> (sh-repo-gram num i.gaz))
::
++ sh-repo-glyph :: apply binding
|= nac=(jug char (set partner))
^+ +>
%_ sh-prod
nak nac
nik %- ~(gas by *(map (set partner) char))
=- (zing `(list (list ,[(set partner) char]))`-)
%+ turn (~(tap by nac))
|= [a=char b=(set (set partner))]
(turn (~(tap by b)) |=(c=(set partner) [c a]))
==
::
++ sh-repo :: apply report
|= rad=report
^+ +>
@ -756,6 +758,7 @@
?- -.rad
%cabal (sh-repo-cabal +.rad)
%grams (sh-repo-grams +.rad)
%glyph (sh-repo-glyph +.rad) :: XX ever happens?
%group (sh-repo-group +.rad)
%house (sh-repo-house +.rad)
==
@ -885,6 +888,17 @@
ole
[new num]
::
++ set-glyph
|= [cha=char lix=(set partner)]
=: nik (~(put by nik) lix cha)
nak (~(put ju nak) cha lix)
==
%_ ..sh-work
..pa
%- (ra-know man.she)
|=(_pa pa-abet:(pa-report glyphers %glyph nak))
==
::
++ join :: %join
|= lix=(set partner)
^+ ..sh-work
@ -892,10 +906,7 @@
=+ (~(get by nik) lix)
?^ - (sh-note "has glyph {<u>}")
=+ cha=(glyph (mug lix))
=: nik (~(put by nik) lix cha)
nak (~(put ju nak) cha lix)
==
(sh-note "new glyph {<cha>}")
(sh-note:(set-glyph cha lix) "new glyph {<cha>}")
=+ loc=loc.system.she
%^ sh-tell %design man.she
:- ~
@ -923,7 +934,7 @@
|= lix=?((set partner) char) ^+ ..sh-work
=< ?~(lix (. lix) ?^(lix (. lix) (fetch-nik lix .)))
|= pan=(set partner)
=< (sh-fact %mor (murn (sort (~(tap by q.guests.she)) aor) .))
=< (sh-fact %mor (murn (sort (~(tap by q.owners.she)) aor) .))
|= [pon=partner alt=atlas] ^- (unit sole-effect)
?. |(=(~ pan) (~(has in pan) pon)) ~
=- `[%tan rose/[", " `~]^- leaf/~(ta-full ta man.she pon) ~]
@ -941,11 +952,7 @@
?~ pan $(pan [~ ?~(active.she passive.she u.active.she)])
=+ ole=(~(get by nik) u.pan)
?: =(ole [~ cha]) ..sh-work
=. nak ?~(ole nak (~(del ju nak) u.ole u.pan))
=: nak (~(put ju nak) cha u.pan)
nik (~(put by nik) u.pan cha)
==
..sh-work
(sh-note:(set-glyph cha u.pan) "bound {<cha>} {<u.pan>}")
::
++ invite :: %invite
|= [nom=span tal=(list partner)]
@ -1167,7 +1174,8 @@
^+ +>
=+ shu=(~(get by shells) ost.hid)
?~ shu
~& [%ra-console-broken ost.hid ?:((~(has by sup.hid) ost.hid) %lost %unknown)]
~& :+ %ra-console-broken ost.hid
?:((~(has by sup.hid) ost.hid) %lost %unknown)
+>.$
sh-abet:(~(sh-sole sh ~ u.shu) act)
::
@ -1310,21 +1318,18 @@
(ra-house(general (~(put in general) ost.hid)) ost.hid)
?. ?=([@ @ *] pax)
(ra-evil %talk-bad-path)
=+ ^= vab ^- (set ,@tas)
=| vab=(set ,@tas)
|- ^+ vab
?: =(0 i.pax) vab
$(i.pax (rsh 3 1 i.pax), vab (~(put in vab) (end 3 1 i.pax)))
=+ vab=(~(gas in *(set ,@tas)) (rip 3 i.pax))
=+ pur=(~(get by stories) i.t.pax)
?~ pur
~& [%bad-subscribe-story-c i.t.pax]
(ra-evil %talk-no-story)
=+ soy=~(. pa i.t.pax u.pur)
=^ who +>.$ (ra-human her)
=. soy ?.((~(has in vab) %a) soy (pa-watch:soy her))
=. soy ?.((~(has in vab) %x) soy (pa-master:soy her))
=. soy ?.((~(has in vab) %a) soy (pa-watch-group:soy her))
=. soy ?.((~(has in vab) %v) soy (pa-watch-glyph:soy her))
=. soy ?.((~(has in vab) %x) soy (pa-watch-cabal:soy her))
=. soy ?.((~(has in vab) %f) soy (pa-watch-grams:soy her t.t.pax))
=. soy (pa-notify:soy her %hear who)
=. soy ?.((~(has in vab) %f) soy (pa-listen:soy her t.t.pax))
pa-abet:soy
::
++ ra-think :: publish/review
@ -1409,44 +1414,50 @@
::==
&
::
++ pa-watch :: watch presence
++ pa-report :: update
|= [wac=(set bone) caw=report]
:: ~& [%pa-report man -.caw]
^+ +>
?~ wac +>
=. +> $(wac l.wac)
=. +> $(wac r.wac)
:: ~& [%pa-report-cabal man shape]
(pa-sauce n.wac [%diff %talk-report caw]~)
::
++ pa-watch-group :: subscribe presence
|= her=ship
?. (pa-admire her)
(pa-sauce ost.hid [%quit ~]~)
=. viewers (~(put in viewers) ost.hid)
(pa-display ost.hid ~ ~)
=. groupers (~(put in groupers) ost.hid)
(pa-report-group ost.hid ~ ~)
::
++ pa-master :: hear config
++ pa-watch-cabal :: subscribe config
|= her=ship
?. (pa-admire her)
~& [%pa-admire-not her]
(pa-sauce ost.hid [%quit ~]~)
=. owners (~(put in owners) ost.hid)
:: ~& [%pa-master her man shape]
=. cabalers (~(put in cabalers) ost.hid)
:: ~& [%pa-watch-cabal her man shape]
(pa-sauce ost.hid [[%diff %talk-report %cabal shape mirrors] ~])
::
++ pa-display :: update presence
|= vew=(set bone)
=+ ^= reg
:_ remotes
|- ^- atlas
?~ locals ~
[[p.n.locals q.q.n.locals] $(locals l.locals) $(locals r.locals)]
:: ~& [%pa-display man reg]
|- ^+ +>.^$
?~ vew +>.^$
=. +>.^$ $(vew l.vew)
=. +>.^$ $(vew r.vew)
(pa-sauce n.vew [[%diff %talk-report %group reg] ~])
++ pa-watch-glyph :: subscribe config
|= her=ship
?. (pa-admire her)
~& [%pa-admire-not her]
(pa-sauce ost.hid [%quit ~]~)
=. glyphers (~(put in glyphers) ost.hid)
(pa-report [ost.hid ~ ~] %glyph nak)
::
++ pa-monitor :: update config
=+ owe=owners
|- ^+ +>
?~ owe +>
=. +> $(owe l.owe)
=. +> $(owe r.owe)
:: ~& [%pa-monitor man shape]
(pa-sauce n.owe [[%diff %talk-report %cabal shape mirrors] ~])
++ pa-report-group :: update presence
|= vew=(set bone)
%^ pa-report vew %group
:_ remotes
|- ^- atlas
?~ locals ~
[[p.n.locals q.q.n.locals] $(locals l.locals) $(locals r.locals)]
::
++ pa-report-cabal :: update config
(pa-report cabalers %cabal shape mirrors)
::
++ pa-cabal
|= [cuz=station con=config ham=(map station config)]
@ -1455,7 +1466,7 @@
=. mirrors (~(put by mirrors) cuz con)
?: =(mirrors old)
+>.$
pa-monitor
pa-report-cabal
::
++ pa-diff-talk-report :: subscribed update
|= [cuz=station rad=report]
@ -1475,7 +1486,7 @@
::
++ pa-quit :: stop subscription
|= tay=partner
pa-monitor(sources.shape (~(del in sources.shape) tay))
pa-report-cabal(sources.shape (~(del in sources.shape) tay))
::
++ pa-sauce :: send backward
|= [ost=bone cub=(list card)]
@ -1533,14 +1544,15 @@
=. +>.$ (pa-acquire p.dif)
=. +>.$ (pa-abjure q.dif)
=. shape cof
pa-monitor
pa-report-cabal
::
++ pa-cancel :: unsubscribe from
~& [%pa-cancel ost.hid]
%_ .
guests (~(del by guests) ost.hid)
viewers (~(del in viewers) ost.hid)
owners (~(del in owners) ost.hid)
gramsers (~(del by gramsers) ost.hid)
groupers (~(del in groupers) ost.hid)
glyphers (~(del in glyphers) ost.hid)
cabalers (~(del in cabalers) ost.hid)
==
::
++ pa-notify :: local presence
@ -1551,7 +1563,7 @@
(~(del by locals) her)
(~(put by locals) her now.hid saz)
?: =(nol locals) +>.$
(pa-display(locals nol) viewers)
(pa-report-group(locals nol) groupers)
::
++ pa-remind :: remote presence
|= [tay=partner loc=atlas rem=(map partner atlas)]
@ -1578,16 +1590,17 @@
?. |(?=(~ gub) !=(buk u.gub))
+>.$
=. remotes (~(put by remotes) tay buk)
(pa-display viewers)
(pa-report-group groupers)
::
++ pa-start :: start stream
|= riv=river
^+ +>
=- :: ~& [%pa-start riv lab]
=. +>.$ (pa-sauce ost.hid [[%diff %talk-report %grams q.lab r.lab] ~])
=. +>.$
(pa-sauce ost.hid [[%diff %talk-report %grams q.lab r.lab] ~])
?: p.lab
(pa-sauce ost.hid [[%quit ~] ~])
+>.$(guests (~(put by guests) ost.hid riv))
+>.$(gramsers (~(put by gramsers) ost.hid riv))
^= lab
=+ [end=count gaz=grams dun=| zeg=*(list telegram)]
|- ^- (trel ,? ,@ud (list telegram))
@ -1604,56 +1617,55 @@
[dun end zeg]
$(end (dec end), gaz t.gaz, zeg [i.gaz zeg])
::
++ pa-listen :: subscribe
++ pa-watch-grams :: subscribe messages
|= [her=ship pax=path]
^+ +>
?. (pa-admire her)
~& [%pa-listen-admire ~]
~& [%pa-watch-grams-admire ~]
(pa-sauce ost.hid [%quit ~]~)
=+ ^= ruv ^- (unit river)
?: ?=(~ pax)
`[[%ud ?:((lth count 64) 0 (sub count 64))] [%da (dec (bex 128))]]
?: ?=([@ ~] pax)
=+ say=(slay i.pax)
?. ?=([~ %$ ?(%ud %da) @] say) ~
`[(point +>.say) [%da (dec (bex 128))]]
?. ?=([@ @ ~] pax) ~
=+ [say=(slay i.pax) den=(slay i.t.pax)]
?. ?=([~ %$ ?(%ud %da) @] say) ~
?. ?=([~ %$ ?(%ud %da) @] den) ~
`[(point +>.say) (point +>.den)]
:: ~& [%pa-listen her pax ruv]
%+ biff
(zl:jo (turn pax ;~(biff slay |=(a=coin `(unit dime)`?~(-.a a ~)))))
|= paf=(list dime)
?~ paf
$(paf [%ud (sub (max 64 count) 64)]~)
?~ t.paf
$(t.paf [%da (dec (bex 128))]~)
?. ?=([[?(%ud %da) @] [?(%ud %da) @] ~] paf)
~
`[[?+(- . %ud .)]:i.paf [?+(- . %ud .)]:i.t.paf] :: XX types
:: ~& [%pa-watch-grams her pax ruv]
?~ ruv
~& [%pa-listen-malformed pax]
~& [%pa-watch-grams-malformed pax]
(pa-sauce ost.hid [%quit ~]~)
(pa-start u.ruv)
::
++ pa-refresh :: update to guests
++ pa-refresh :: update to listeners
|= [num=@ud gam=telegram]
^+ +>
=+ ^= moy
|- ^- (pair (list bone) (list move))
?~ guests [~ ~]
:: ~& [%pa-refresh num n.guests]
=+ lef=$(guests l.guests)
=+ rit=$(guests r.guests)
?~ gramsers [~ ~]
:: ~& [%pa-refresh num n.gramsers]
=+ lef=$(gramsers l.gramsers)
=+ rit=$(gramsers r.gramsers)
=+ old=[p=(welp p.lef p.rit) q=(welp q.lef q.rit)]
?: ?- -.q.q.n.guests :: after the end
%ud (lte p.q.q.n.guests num)
%da (lte p.q.q.n.guests p.r.q.gam)
?: ?- -.q.q.n.gramsers :: after the end
%ud (lte p.q.q.n.gramsers num)
%da (lte p.q.q.n.gramsers p.r.q.gam)
==
[[p.n.guests p.old] [[p.n.guests %quit ~] q.old]]
?: ?- -.p.q.n.guests :: before the start
%ud (gth p.p.q.n.guests num)
%da (gth p.p.q.n.guests p.r.q.gam)
[[p.n.gramsers p.old] [[p.n.gramsers %quit ~] q.old]]
?: ?- -.p.q.n.gramsers :: before the start
%ud (gth p.p.q.n.gramsers num)
%da (gth p.p.q.n.gramsers p.r.q.gam)
==
old
:- p.old
[[p.n.guests %diff %talk-report %grams num gam ~] q.old]
[[p.n.gramsers %diff %talk-report %grams num gam ~] q.old]
=. moves (welp q.moy moves)
|- ^+ +>.^$
?~ p.moy +>.^$
$(p.moy t.p.moy, guests (~(del by guests) i.p.moy))
$(p.moy t.p.moy, gramsers (~(del by gramsers) i.p.moy))
::
++ pa-lesson :: learn multiple
|= gaz=(list telegram)
@ -1872,12 +1884,12 @@
|- ^- tang
=< ?+(. . [@ *] [.]~) ^- ?(tank tang) :: wrap single tanks
?+ -.sep [>sep<]~
%exp leaf/"# {(trip p.sep)}"
%exp palm/[~ "#" " " ~]^~[leaf/(trip p.sep)]
%lin leaf/"{?:(p.sep "" "@ ")}{(trip q.sep)}"
%non ~
%app rose/[": " ~ ~]^~[leaf/"[{(trip p.sep)}]" leaf/(trip q.sep)]
%tax leaf/(rend-work-duty p.sep)
%url leaf/"/ {(earf p.sep)}"
%url palm/[~ "/" " " ~]^~[leaf/(earf p.sep)]
%mor ?~(p.sep ~ (weld $(p.sep t.p.sep) $(sep i.p.sep)))
%fat (welp (tr-rend-tors p.sep) $(sep q.sep))
==
@ -1924,6 +1936,8 @@
:+ '/' '_'
=+ hok=r.p.p.p.sep
~! hok
=- (swag [(sub (max 64 (lent -)) 64) 64] -)
^- tape
=< ?~(-.hok (reel p.hok .) +:(scow %if p.hok))
|=([a=span b=tape] ?~(b (trip a) (welp b '.' (trip a))))
::
@ -2027,6 +2041,7 @@
::
++ log-all-to-file
^- (quip move .)
?: & [~ .] :: XXX!!!!
:_ %_ .
log %- ~(urn by log)
|=([man=span len=@ud] count:(~(got by stories) man))
@ -2067,6 +2082,8 @@
::
++ poke-log
|= man=span
~& %poke-log
^- (quip move +>)
:- [(log-to-file man) ~]
+>.$(log (~(put by log) man count:(~(got by stories) man)))
@ -2078,14 +2095,14 @@
+>.$(log (~(del by log) man))
::
++ prep
|= [old=(unit house-any)]
^- (quip move +>)
|= old=(unit house-any)
^- (quip move ..prep)
?~ old
ra-abet:ra-init:ra
|-
?- -.u.old
%1 $(u.old [%2 stories general outbox folks shells ~]:u.old)
%2 $(u.old [%3 stories general outbox folks shells log ~ ~]:u.old)
%3 [~ +>.^$(+<+ u.old)]
%4 [~ ..prep(+<+ u.old)]
%3 =< ^$(-.u.old %4, stories.u.old (~(run by stories.u.old) .))
|=(story-3 `story`+<(cabalers [cabalers glyphers=*(set bone)]))
==
--

View File

@ -26,6 +26,8 @@
::
++ made
|= [pax=wire @ res=gage]
?. =(our src)
~|(foreign-write/[our=our src=src] !!)
?+ -.res ~|(gage/-.res !!)
%| (mean p.res)
%& =- [[ost %info / our -]~ +>.$]

View File

@ -1204,6 +1204,7 @@
::
++ show-login-page
|= ses=(unit hole) ^- (each pest ,_done)
%- (slog leaf/"Login code for {(scow %p our)} is: {(trip load-secret)}" ~)
?. ?=($|(~ [~ %html]) p.pok)
[%& %red ~]
?~ ses

View File

@ -29,14 +29,14 @@
-- ::
|% :::::::::::::::::::::::::::::::::::::::::::::::::::::: %gall state
::::::::::::::::::::::::::::::::::::::::::::::::::::::
++ axle-n ?(axle axle-0) :: upgrade path
++ axle-0 ,[%0 pol=(map ship mast-0)] ::
++ mast-0 ::
(cork mast |=(mast +<(bum (~(run by bum) seat-0)))) ::
++ seat-0 ::
(cork seat |=(seat +<(|7 zam=(scar |7.+<)))) ::
++ axle-n ?(axle axle-1) :: upgrade path
++ axle-1 ,[%1 pol=(map ship mast-1)] ::
++ mast-1 ::
(cork mast |=(mast +<(bum (~(run by bum) seat-1)))) ::
++ seat-1 ::
(cork seat |=(seat +<+)) ::
++ axle :: all state
$: %1 :: state version
$: %2 :: state version
pol=(map ship mast) :: apps by ship
== ::
++ gest :: subscriber data
@ -66,7 +66,8 @@
r=(map bone duct) :: by bone
== ::
++ seat :: agent state
$: mom=duct :: control duct
$: vel=worm :: cache
mom=duct :: control duct
liv=? :: unstopped
toc=torc :: privilege
tyc=stic :: statistics
@ -93,9 +94,11 @@
eny=@uvI :: entropy
ska=sled :: activate
== :: opaque core
~% %gall-top ..is ~
|% :::::::::::::::::::::::::::::::::::::::::::::::::::::: state machine
::::::::::::::::::::::::::::::::::::::::::::::::::::::
++ mo
~% %gall-mo +> ~
|_ $: $: our=@p
hen=duct
moz=(list move)
@ -528,6 +531,7 @@
==
::
++ ap :: agent engine
~% %gall-ap +> ~
|_ $: $: dap=dude
pry=prey
ost=bone
@ -617,12 +621,13 @@
|=([a=(each suss tang)] [hen %give %onto a])
::
++ ap-call :: call into server
~/ %ap-call
|= [cog=term arg=vase]
^- [(unit tang) _+>]
=. +> ap-bowl
=+ arm=(ap-farm cog)
=^ arm +>.$ (ap-farm cog)
?: ?=(%| -.arm) [`p.arm +>.$]
=+ zem=(ap-slam cog p.arm arg)
=^ zem +>.$ (ap-slam cog p.arm arg)
?: ?=(%| -.zem) [`p.zem +>.$]
(ap-sake p.zem)
::
@ -677,13 +682,16 @@
+(qel.ged (~(put by qel.ged) ost u.soy))
::
++ ap-farm :: produce arm
~/ %ap-farm
|= cog=term
^- (each vase tang)
=+ puz=(mule |.((~(mint ut p.hav) [%noun [%cnzy cog]])))
?: ?=(%| -.puz) [%| p.puz]
=+ ton=(mock [q.hav q.p.puz] ap-sled)
^- [(each vase tang) _+>]
=+ pyz=(mule |.((~(mint wa vel) p.hav [%cnzy cog])))
?: ?=(%| -.pyz)
:_(+>.$ [%| +.pyz])
:_ +>.$(vel `worm`+>.pyz)
=+ ton=(mock [q.hav q.+<.pyz] ap-sled)
?- -.ton
%0 [%& p.p.puz p.ton]
%0 [%& p.+<.pyz p.ton]
%1 [%| (turn p.ton |=(a=* (smyt (path a))))]
%2 [%| p.ton]
==
@ -740,15 +748,17 @@
|=([a=term b=term] `term`(cat 3 a (cat 3 '-' b)))
::
++ ap-move :: process each move
~/ %ap-move
|= vax=vase
^- (each cove tang)
?@ q.vax [%| (ap-suck "move: invalid move (atom)")]
?^ -.q.vax [%| (ap-suck "move: invalid move (bone)")]
?@ +.q.vax [%| (ap-suck "move: invalid move (card)")]
^- [(each cove tang) _+>]
?@ q.vax :_(+>.$ [%| (ap-suck "move: invalid move (atom)")])
?^ -.q.vax :_(+>.$ [%| (ap-suck "move: invalid move (bone)")])
?@ +.q.vax :_(+>.$ [%| (ap-suck "move: invalid move (card)")])
=+ hun=(~(get by r.zam) -.q.vax)
?. (~(has by r.zam) -.q.vax)
[%| (ap-suck "move: invalid card (bone {<-.q.vax>})")]
=+ cav=(slot 3 (spec (slot 3 vax)))
:_(+>.$ [%| (ap-suck "move: invalid card (bone {<-.q.vax>})")])
=^ pec vel (~(spot wa vel) 3 vax)
=^ cav vel (~(slot wa vel) 3 pec)
?+ +<.q.vax
(ap-move-pass -.q.vax +<.q.vax cav)
%diff (ap-move-diff -.q.vax cav)
@ -762,36 +772,41 @@
::
++ ap-move-quit :: give quit move
|= [sto=bone vax=vase]
^- (each cove tang)
^- [(each cove tang) _+>]
:_ +>
?^ q.vax [%| (ap-suck "quit: improper give")]
[%& `cove`[sto %give `cuft`[%quit ~]]]
::
++ ap-move-diff :: give diff move
|= [sto=bone vax=vase]
=. vax (spec vax)
^- (each cove tang)
?. &(?=(^ q.vax) ?=(@ -.q.vax) ((sane %tas) -.q.vax))
[%| (ap-suck "diff: improper give")]
[%& sto %give %diff `cage`[-.q.vax (slot 3 (spec vax))]]
^- [(each cove tang) _+>]
=^ pec vel (~(spec wa vel) vax)
?. &(?=(^ q.pec) ?=(@ -.q.pec) ((sane %tas) -.q.pec))
:_(+>.$ [%| (ap-suck "diff: improper give")])
=^ tel vel (~(slot wa vel) 3 pec)
:_(+>.$ [%& sto %give %diff `cage`[-.q.pec tel]])
::
++ ap-move-hiss :: pass %hiss
|= [sto=bone vax=vase]
^- (each cove tang)
^- [(each cove tang) _+>]
?. &(?=([p=* q=@ q=^] q.vax) ((sane %tas) q.q.vax))
[%| (ap-suck "hiss: malformed hiss ask.[%hiss wire mark cage]")]
=+ gaw=(slot 7 vax)
:_(+>.$ [%| (ap-suck "hiss: bad hiss ask.[%hiss wire mark cage]")])
=^ gaw vel (~(slot wa vel) 7 vax)
?. &(?=([p=@ q=^] q.gaw) ((sane %tas) p.q.gaw))
[%| (ap-suck "hiss: malformed cage")]
:_(+>.$ [%| (ap-suck "hiss: malformed cage")])
=+ pux=((soft path) p.q.vax)
?. &(?=(^ pux) (levy u.pux (sane %ta)))
[%| (ap-suck "hiss: malformed path")]
:_(+>.$ [%| (ap-suck "hiss: malformed path")])
=^ paw vel (~(stop wa vel) 3 gaw)
:_ +>.$
:^ %& sto %pass
:- [(scot %p q.q.pry) %cay u.pux]
[%hiss q.q.vax [p.q.gaw (slot 3 (spec gaw))]]
[%hiss q.q.vax [p.q.gaw paw]]
::
++ ap-move-mess :: extract path, target
|= vax=vase
^- (each (trel path ship term) tang)
^- [(each (trel path ship term) tang) _+>]
:_ +>.$
?. ?& ?=([p=* [q=@ r=@] s=*] q.vax)
(gte 1 (met 7 q.q.vax))
==
@ -803,34 +818,39 @@
::
++ ap-move-pass :: pass general move
|= [sto=bone wut=* vax=vase]
^- (each cove tang)
^- [(each cove tang) _+>]
?. &(?=(@ wut) ((sane %tas) wut))
[%| (ap-suck "pass: malformed card")]
:_(+>.$ [%| (ap-suck "pass: malformed card")])
=+ pux=((soft path) -.q.vax)
?. &(?=(^ pux) (levy u.pux (sane %ta)))
[%| (ap-suck "pass: malformed path")]
:_(+>.$ [%| (ap-suck "pass: malformed path")])
=+ huj=(ap-vain wut)
?~ huj [%| (ap-suck "move: unknown note {(trip wut)}")]
?~ huj :_(+>.$ [%| (ap-suck "move: unknown note {(trip wut)}")])
=^ tel vel (~(slot wa vel) 3 vax)
:_ +>.$
:^ %& sto %pass
:- [(scot %p q.q.pry) %inn u.pux]
[%meta u.huj (slop (ap-term %tas wut) (slot 3 vax))]
[%meta u.huj (slop (ap-term %tas wut) tel)]
::
++ ap-move-poke :: pass %poke
|= [sto=bone vax=vase]
^- (each cove tang)
=+ yep=(ap-move-mess vax)
?: ?=(%| -.yep) yep
=+ gaw=(slot 7 vax)
^- [(each cove tang) _+>]
=^ yep +>.$ (ap-move-mess vax)
?: ?=(%| -.yep) :_(+>.$ yep)
=^ gaw vel (~(slot wa vel) 7 vax)
?. &(?=([p=@ q=*] q.gaw) ((sane %tas) p.q.gaw))
[%| (ap-suck "poke: malformed cage")]
:_(+>.$ [%| (ap-suck "poke: malformed cage")])
=^ paw vel (~(stop wa vel) 3 gaw)
:_ +>.$
:^ %& sto %pass
:- p.p.yep
[%send q.p.yep r.p.yep %poke p.q.gaw (slot 3 (spec gaw))]
[%send q.p.yep r.p.yep %poke p.q.gaw paw]
::
++ ap-move-peer :: pass %peer
|= [sto=bone vax=vase]
^- (each cove tang)
=+ yep=(ap-move-mess vax)
^- [(each cove tang) _+>]
=^ yep +>.$ (ap-move-mess vax)
:_ +>.$
?: ?=(%| -.yep) yep
=+ pux=((soft path) +>.q.vax)
?. &(?=(^ pux) (levy u.pux (sane %ta)))
@ -841,8 +861,9 @@
::
++ ap-move-pull :: pass %pull
|= [sto=bone vax=vase]
^- (each cove tang)
=+ yep=(ap-move-mess vax)
^- [(each cove tang) _+>]
=^ yep +>.$ (ap-move-mess vax)
:_ +>.$
?: ?=(%| -.yep) yep
?. =(~ +>.q.vax)
[%| (ap-suck "pull: malformed card")]
@ -852,27 +873,31 @@
::
++ ap-move-send :: pass gall action
|= [sto=bone vax=vase]
^- (each cove tang)
^- [(each cove tang) _+>]
?. ?& ?=([p=* [q=@ r=@] [s=@ t=*]] q.vax)
(gte 1 (met 7 q.q.vax))
((sane %tas) r.q.vax)
==
[%| (ap-suck "send: improper ask.[%send wire gill club]")]
:_(+>.$ [%| (ap-suck "send: improper ask.[%send wire gill club]")])
=+ pux=((soft path) p.q.vax)
?. &(?=(^ pux) (levy u.pux (sane %ta)))
[%| (ap-suck "send: malformed path")]
:_(+>.$ [%| (ap-suck "send: malformed path")])
?: ?=(%poke s.q.vax)
=+ gav=(spec (slot 7 vax))
=^ gav vel (~(spot wa vel) 7 vax)
?> =(%poke -.q.gav)
?. ?& ?=([p=@ q=*] t.q.vax)
((sane %tas) p.t.q.vax)
==
[%| (ap-suck "send: malformed poke")]
:_(+>.$ [%| (ap-suck "send: malformed poke")])
=^ vig vel (~(spot wa vel) 3 gav)
=^ geb vel (~(slot wa vel) 3 vig)
:_ +>.$
:^ %& sto %pass
:- [(scot %p q.q.vax) %out r.q.vax u.pux]
^- cote
:: ~& [%ap-move-send `path`[(scot %p q.q.vax) %out r.q.vax u.pux]]
[%send q.q.vax r.q.vax %poke p.t.q.vax (slot 3 (spec (slot 3 gav)))]
[%send q.q.vax r.q.vax %poke p.t.q.vax geb]
:_ +>.$
=+ cob=((soft club) [s t]:q.vax)
?~ cob
[%| (ap-suck "send: malformed club")]
@ -954,11 +979,12 @@
=+ cug=(ap-find [-.q.vax pax])
?~ cug
(ap-lame -.q.vax (ap-suck "pour: no {(trip -.q.vax)}: {<pax>}"))
=^ tel vel (~(slot wa vel) 3 vax)
=^ cam +>.$
%+ ap-call q.u.cug
%+ slop
!>(`path`(slag p.u.cug pax))
(slot 3 vax)
tel
?^ cam (ap-lame -.q.vax u.cam)
+>.$
::
@ -1055,12 +1081,15 @@
::
++ ap-safe :: process move list
|= vax=vase
^- (each (list cove) tang)
?~ q.vax [%& ~]
?@ q.vax [%| (ap-suck "move: malformed list")]
=+ sud=(ap-move (slot 2 vax))
?: ?=(%| -.sud) sud
=+ res=$(vax (slot 3 vax))
^- [(each (list cove) tang) _+>]
?~ q.vax :_(+>.$ [%& ~])
?@ q.vax :_(+>.$ [%| (ap-suck "move: malformed list")])
=^ hed vel (~(slot wa vel) 2 vax)
=^ sud +>.$ (ap-move hed)
?: ?=(%| -.sud) :_(+>.$ sud)
=^ tel vel (~(slot wa vel) 3 vax)
=^ res +>.$ $(vax tel)
:_ +>.$
?: ?=(%| -.res) res
[%& p.sud p.res]
::
@ -1069,9 +1098,11 @@
^- [(unit tang) _+>]
?: ?=(@ q.vax)
[`(ap-suck "sake: invalid product (atom)") +>.$]
=+ muz=(ap-safe (slot 2 vax))
=^ hed vel (~(slot wa vel) 2 vax)
=^ muz +>.$ (ap-safe hed)
?: ?=(%| -.muz) [`p.muz +>.$]
=+ sav=(ap-save (slot 3 vax))
=^ tel vel (~(slot wa vel) 3 vax)
=^ sav +>.$ (ap-save tel)
?: ?=(%| -.sav) [`p.sav +>.$]
:- ~
%_ +>.$
@ -1081,22 +1112,32 @@
::
++ ap-save :: verify core
|= vax=vase
^- (each vase tang)
?. (~(nest ut p.hav) %| p.vax)
^- [(each vase tang) _+>]
=^ gud vel (~(nest wa vel) p.hav p.vax)
:_ +>.$
?. gud
[%| (ap-suck "invalid core")]
[%& vax]
::
++ ap-mong
~/ %ap-mong
|= [[gat=* sam=*] sky=$+(* (unit))]
^- toon
(mong [gat sam] sky)
::
++ ap-slam :: virtual slam
~/ %ap-slam
|= [cog=term gat=vase arg=vase]
^- (each vase tang)
=+ wiz=(mule |.((slit p.gat p.arg)))
?: ?=(%| -.wiz)
^- [(each vase tang) _+>]
=+ wyz=(mule |.((~(play wa vel) [%cell p.gat p.arg] [%cncl `2 `3])))
?: ?=(%| -.wyz)
%- =+ sam=(~(peek ut p.gat) %free 6)
(slog >%ap-slam-mismatch< ~(duck ut p.arg) ~(duck ut sam) ~)
[%| (ap-suck "call: {<cog>}: type mismatch")]
=+ ton=(mong [q.gat q.arg] ap-sled)
:_(+>.$ [%| (ap-suck "call: {<cog>}: type mismatch")])
:_ +>.$(vel +>.wyz)
=+ ton=(ap-mong [q.gat q.arg] ap-sled)
?- -.ton
%0 [%& p.wiz p.ton]
%0 [%& +<.wyz p.ton]
%1 [%| (turn p.ton |=(a=* (smyt (path a))))]
%2 [%| p.ton]
==
@ -1136,6 +1177,7 @@
--
--
++ call :: request
~% %gall-call +> ~
|= [hen=duct hic=(hypo (hobo kiss-gall))]
^- [p=(list move) q=_..^$]
=> .(q.hic ?.(?=(%soft -.q.hic) q.hic ((hard kiss-gall) p.q.hic)))
@ -1203,11 +1245,11 @@
++ load :: recreate vane
|= old=axle-n
^+ ..^$
?: ?=(%1 -.old) ..^$(all old)
?: ?=(%2 -.old) ..^$(all old)
%= $
old => |=(seat-0 `seat`+<(zam [~ zam]))
=> |=(mast-0 +<(bum (~(run by bum) +>)))
old(- %1, pol (~(run by pol.old) .))
old => |=(seat-1 `seat`[*worm +<])
=> |=(mast-1 +<(bum (~(run by bum) +>)))
old(- %2, pol (~(run by pol.old) .))
==
::
++ scry

View File

@ -1254,7 +1254,6 @@
--
::
++ stat :: positive counter
!:
|* a=$+(* *)
|= (trel ,? a (map a ,@ud))
^+ r
@ -6600,8 +6599,7 @@
|= [[tab=@ edg=@] tac=tank] ^- wall
(~(win re tac) tab edg)
::
++ wa :: cached compile
!:
++ wa !: :: cached compile
|_ worm
++ nell |=(ref=type (nest [%cell %noun %noun] ref)) :: nest in cell
++ nest :: nest:ut
@ -6668,13 +6666,19 @@
=^ typ +>+<.$ (play p.vax [%wtgr gen [%$ 1]])
[[typ q.vax] +>+<.$]
::
++ spot :: slot and spec
++ spot :: slot then spec
|= [axe=@ vax=vase]
^- [vase worm]
=^ xav +>+< (slot axe vax)
(spec xav)
::
++ stop :: spec then slot
|= [axe=@ vax=vase]
^- [vase worm]
=^ xav +>+< (spec vax)
(slot axe xav)
--
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2fB, macro expansion ::
::
++ ah :: tiki engine
@ -10345,14 +10349,14 @@
==
?.(-.hig ~ `[(slym gat +>.hil) +.hig])
::
++ slur-a ~/(%slur-a |=([gat=vase hil=mill] (slur gat hil)))
++ slur-b ~/(%slur-b |=([gat=vase hil=mill] (slur gat hil)))
++ slur-c ~/(%slur-c |=([gat=vase hil=mill] (slur gat hil)))
++ slur-d ~/(%slur-d |=([gat=vase hil=mill] (slur gat hil)))
++ slur-e ~/(%slur-e |=([gat=vase hil=mill] (slur gat hil)))
++ slur-f ~/(%slur-f |=([gat=vase hil=mill] (slur gat hil)))
++ slur-g ~/(%slur-g |=([gat=vase hil=mill] (slur gat hil)))
++ slur-z ~/(%slur-z |=([gat=vase hil=mill] (slur gat hil)))
++ slur-a ~/(%slur-a |=([gat=vase hil=mill] =+(%a (slur gat hil))))
++ slur-b ~/(%slur-b |=([gat=vase hil=mill] =+(%b (slur gat hil))))
++ slur-c ~/(%slur-c |=([gat=vase hil=mill] =+(%c (slur gat hil))))
++ slur-d ~/(%slur-d |=([gat=vase hil=mill] =+(%d (slur gat hil))))
++ slur-e ~/(%slur-e |=([gat=vase hil=mill] =+(%e (slur gat hil))))
++ slur-f ~/(%slur-f |=([gat=vase hil=mill] =+(%f (slur gat hil))))
++ slur-g ~/(%slur-g |=([gat=vase hil=mill] =+(%g (slur gat hil))))
++ slur-z ~/(%slur-z |=([gat=vase hil=mill] =+(%z (slur gat hil))))
::
++ slur-pro :: profiling slur
~/ %slur-pro

View File

@ -588,44 +588,41 @@
--
::
++ pojo :: print json
=| rez=tape
|= val=json
^- tape
?~ val "null"
?~ val (weld "null" rez)
?- -.val
%a
;: weld
"["
=| rez=tape
|- ^+ rez
?~ p.val rez
$(p.val t.p.val, rez :(weld rez ^$(val i.p.val) ?~(t.p.val ~ ",")))
"]"
==
:- '['
=. rez [']' rez]
!.
?~ p.val rez
|-
?~ t.p.val ^$(val i.p.val)
^$(val i.p.val, rez [',' $(p.val t.p.val)])
::
%b ?:(p.val "true" "false")
%n (trip p.val)
%b (weld ?:(p.val "true" "false") rez)
%n (weld (trip p.val) rez)
%s
;: welp
"\""
%+ reel
(turn (trip p.val) jesc)
|=([p=tape q=tape] (welp +<))
"\""
==
:- '"'
=. rez ['"' rez]
=+ viz=(trip p.val)
!.
|-
?~ viz rez
(weld (jesc i.viz) $(viz t.viz))
::
%o
;: welp
"\{"
=+ viz=(~(tap by p.val) ~)
=| rez=tape
|- ^+ rez
?~ viz rez
%= $
viz t.viz
rez
:(welp rez "\"" (trip p.i.viz) "\":" ^$(val q.i.viz) ?~(t.viz ~ ","))
==
"}"
==
:- '{'
=. rez ['}' rez]
=+ viz=(~(tap by p.val))
?~ viz rez
!.
|- ^+ rez
?~ t.viz ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)])
=. rez [',' $(viz t.viz)]
^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)])
==
::
::

View File

@ -1 +1 @@
;list(data-source "default");
;list(data-source "default", is404 "true");

View File

@ -13,8 +13,8 @@
=- |= tub=nail ^- (like ,@t) %. tub :: export context
=+(poxa enty(ent mapping))
^- mapping=(map span ,@tF)
=+ pax=/==1%%/'html5-entities.json'/txt :: XX %%/
=+ maf=%.(pax ;~(biff file (soft ,@t) poja (om so):jo))
=+ pax=/==5%%/html5-entities/json :: XX %%/
=+ maf=%.(pax ;~(biff file (soft json) (om so):jo))
?^ maf u.maf
~& no-enty/pax
(mo amp/'&' quot/'"' apos/'\'' lt/'<' gt/'>' ~) :: fallback

View File

@ -27,6 +27,13 @@
^- (unit (list ,_[(wonk *fel) (need *wit)]))
(zl (turn (~(tap by a)) (head-rush fel)))
::
++ ke :: callbacks
|* [gar=* sef=_|.(fist)]
|= jon=json
^- (unit ,_gar)
=- ~! gar ~! (need -) -
((sef) jon)
::
++ as :: array as set
:: |*(a=fist (cu sa (ar a))) :: XX types
|* a=fist
@ -69,20 +76,31 @@
%+ sear (soft passport)
;~((glue fas) sym urs:ab) :: XX [a-z0-9_]{1,15}
::
++ speeech ?(speech [%eval p=@t] [%mor p=(list speeech)])
++ eval
|= a=(trel ,@da bouquet ?(speech [%eval p=@t])) ^- statement
?. ?=(%eval -.r.a) a
=+ pax=[&1:% &2:% (scot %da p.a) |3:%]
=- a(r [%fat tank/- %exp p.r.a])
p:(mule |.([(sell (slap !>(..zuse) (rain pax p.r.a)))]~))
|= a=(trel ,@da bouquet speeech) ^- statement
%= a r ^- speech
|-
?: ?=(%mor -.r.a)
[%mor (turn p.r.a |=(b=speeech ^$(r.a b)))]
?. ?=(%eval -.r.a) r.a
=- [%fat tank/- %exp p.r.a]
=+ pax=[&1:% &2:% (scot %da p.a) |3:%]
p:(mule |.([(sell (slap !>(..zuse) (rain pax p.r.a)))]~))
==
::
++ stam
^- $+(json (unit statement))
%+ cu eval
=- (ot date/di bouquet/(as (ar so)) speech/(of -) ~)
(ot date/di bouquet/(as (ar so)) speech/spec ~)
::
++ spec
%+ ke *speeech |.
%- of
:~ lin/(ot say/bo txt/so ~)
url/(su aurf:urlp)
eval/so
mor/(ar spec)
:: exp/(cu |=(a=cord [a ~]) so)
:: inv/(ot ship/(su fed:ag) party/(su urs:ab) ~)
==

View File

@ -21,6 +21,7 @@
?- -.rep
%cabal (cabl +.rep)
%house a/(turn (~(tap by +.rep)) jose)
%glyph ((jome |=(a=char a) nack) +.rep)
%grams (jobe num/(jone p.rep) tele/[%a (turn q.rep gram)] ~)
%group (jobe local/(grop p.rep) global/%.(q.rep (jome parn grop)) ~)
==
@ -54,6 +55,7 @@
|=(c=_[+<.a +<.b] [(a -.c) (b +.c)])
::
::
++ nack |=(a=(set (set partner)) [%a (turn (~(tap in a)) sorc)])
++ grop (jome phon stas) :: (map ship status)
++ phon |=(a=ship (scot %p a))
++ stas |=(status (jobe presence/(joce p) human/(huma q) ~))
@ -95,6 +97,7 @@
%tax (joba txt/(jape (rend-work-duty p.a)))
%app (jobe txt/[%s q.a] src/[%s p.a] ~)
%fat (jobe tor/(tors p.a) taf/$(a q.a) ~)
%mor a/(turn p.a spec)
:: %inv (jobe ship/(jope p.a) party/[%s q.a] ~)
==
::
@ -124,10 +127,14 @@
ham/((jome stat conf) ham)
==
::
++ sorc
|= a=(set partner) ^- json
[%a (turn (~(tap in a)) |=(b=partner s/(parn b)))]
::
++ conf
|= config
%- jobe :~
sources/[%a (turn (~(tap in sources)) |=(a=partner [%s (parn a)]))]
sources/(sorc sources)
caption/[%s caption]
=- cordon/(jobe posture/[%s -.cordon] list/[%a -] ~)
(turn (~(tap in q.cordon)) jope) :: XX jase

View File

@ -1,10 +1,9 @@
---
title: Network Goals, Part I
title: Network architecture: goals
sort: 4
hide: true
---
# Constitution of a digital republic: part 1, goals
# Design of a digital republic: part 1, goals
Some of us remember when the Internet was a social network.
Today, the Internet is a modem.
@ -13,7 +12,7 @@ It's a wonderful modem. It connects you to all kinds of great
online services. Some of which are social "networks," but only
networks in the MBA sense. Really they're social *servers*:
giant virtual mainframes running one hardcoded program. 1976
called -- it wants its acoustic coupler back.
called it wants its acoustic coupler back.
So, you prefer 1996. So, you wish you had your decentralized
Internet back. So, you don't seem alone in this. So, we know
@ -34,8 +33,8 @@ against "Governments of the Industrial World, you weary giants of
flesh and steel."
Well... hindsight is 20/20. But in hindsight, even in 1996
things were starting to head south. Usenet -- the brain of the
Internet, when the Internet had a brain -- was already
things were starting to head south. Usenet the brain of the
Internet, when the Internet had a brain was already
disintegrating under the barbarian invasions. And where is the
WELL these days? (John Perry Barlow is probably still on it.)
@ -79,7 +78,7 @@ Dealing is way better than worrying. 1996 worried about the
problem; 2016 ought to deal with it.
A constitution is not a declaration. It's not a list of ideals.
It's more like a bridge -- an actual structure, that fails unless
It's more like a bridge an actual structure, that fails unless
it stands up to genuine load. A bridge isn't a bridge unless it
works. If you want a bridge, you have to build a bridge. It
doesn't typically happen that you set out to build something
@ -94,7 +93,7 @@ network. They weren't trying to, and they didn't.
If we want a decentralized social network, we can't do it without
rigorous engineering work. And we can't limit our work to the
world of code. A decentralized network has to work not just
technically -- but politically, economically, and socially.
technically but politically, economically, and socially.
Where do we go from here? How do we get back to 1996? Admit
we've failed, and try again. How else?
@ -289,7 +288,7 @@ republic, but it certainly works and it's better than nothing.
Thus what seems like an optimal political design: the ugly,
centralized, young larva that's designed to molt into a
beautiful, mature, decentralized butterfly. And once mature, the
larva must molt or die -- not keep growing into a gigantic,
larva must molt or die not keep growing into a gigantic,
man-eating caterpillar of death.
## Economic engineering
@ -374,8 +373,8 @@ space by giving blocks away. You may even increase the value of
your own position.
A monopolized network is not politically healthy. So its
economic value is lower. So -- if the network is properly
designed and structured -- it can be stably demonopolized. The
economic value is lower. So if the network is properly
designed and structured it can be stably demonopolized. The
monopoly power achieved by combining large positions is smaller
than the reputation cost of remonopolization, so centrifugal
force dominates and the system stays decentralized.
@ -562,4 +561,5 @@ Goals are more interesting than ideals, don't you think?
Goals and features are also different things. What are the
features of a network that attempts to achieve these design
goals? In the next installment, we'll look at how our own
network -- Urbit -- measures up to these yardsticks.
network — [Urbit](http://urbit.org) — measures up to these
yardsticks.

View File

@ -3,6 +3,7 @@ logo: black
title: User doc
sort: 1
---
<div class="short">
# User documentation

View File

@ -83,11 +83,11 @@ possible; it's not well-optimized.
There's a web interface to `:talk` at
http://localhost:8080/~~/pub/talk/fab
http://localhost:8080/~~/home/pub/talk/fab
and a dojo interface at
http://localhost:8080/~~/pub/dojo/fab
http://localhost:8080/~~/home/pub/dojo/fab
The `:talk` client is beautiful and works quite well. Use it.
The `:dojo` client is a bit more of a work in progress. (For

View File

@ -89,6 +89,3 @@ Run `make`:
make
(On FreeBSD, use `gmake` instead.)
The executable is `bin/urbit`. Install it somewhere, or just use
it where it is.

View File

@ -131,6 +131,7 @@ respect our code of conduct, which is: "don't be rude."
## Pronunciation and etymology
Urbit is always pronounced "herb it," never "your bit." Not that
it's not your bit! But "herb it" just sounds better.
it's not your bit! But "herb it" just sounds better. (Yes, we
speak American and the 'h' is silent.)
The origin of the name is just the Latin *urbi*, meaning city.

View File

@ -59,7 +59,7 @@ be anyone, so you have zero reputation. You have no official
access to any Urbit services. Any connectivity you may enjoy
could be shut off at any time, and it probably will be. If the
Internet has proven one thing, it's that positive default
reputation and effectively infinite identity don't mix.
reputation and effectively infinite number of identities don't mix.
## Substrate interactions

View File

@ -3,7 +3,7 @@
;link(rel "stylesheet", href "/home/lib/base.css");
;link(rel "stylesheet", href "/home/pub/paste/main.css");
;script@"//code.jquery.com/jquery-2.1.4.min.js";
;script@"/~/at/home/lib/urb.js";
;script@"/~/as/own/~/at/home/lib/urb.js";
;script:'''
document.title = 'pastebin - urbit'
urb.appl = 'write'

View File

@ -29,7 +29,12 @@
;title: Talk
==
;body
;div#c;
;div#c
;div#station-container;
;div#messages-container;
;div#writing-container;
;div#scrolling: BOTTOM
==
;script(type "text/javascript", src "/home/pub/talk/src/js/main.js");
==
==

View File

@ -441,12 +441,12 @@ a {
content: "~";
}
.type.private:before {
content: "•";
content: attr(data-glyph);
font-size: 1rem;
line-height: 1.1rem;
}
.type.public:before {
content: "▒";
content: attr(data-glyph);
font-size: 0.8rem;
line-height: 1.2rem;
}
@ -534,6 +534,8 @@ a {
#writing {
min-height: 1.6rem;
min-width: 1.3rem;
max-width: 32rem;
line-height: 2rem;
outline: none;
padding: 0.3rem 0.1rem;
margin-top: -0.3rem;

View File

@ -391,12 +391,12 @@ a
content "~"
.type.private:before
content ""
content attr(data-glyph)
font-size 1rem
line-height 1.1rem
.type.public:before
content ""
content attr(data-glyph)
font-size .8rem
line-height 1.2rem
@ -488,6 +488,8 @@ a
#writing
min-height 1.6rem
min-width 1.3rem
max-width 32rem
line-height 2rem
outline none
padding .3rem .1rem
margin-top -.3rem

View File

@ -56,17 +56,32 @@ module.exports =
else if window.urb.util.isURL(message)
speech = url: message
_message =
ship:window.urb.ship
thought:
serial:serial
audience:_audi
statement:
bouquet:[]
speech:speech
date: Date.now()
MessageDispatcher.handleViewAction
type:"message-send"
message:_message
window.talk.MessagePersistence.sendMessage _message.thought
speeches =
if not (speech.lin?.txt.length > 64)
[speech]
else
{say,txt} = speech.lin
txt.match(/(.{1,64}$|.{0,64} |.{64}|.+$)/g).map (s,i)->
say ||= i isnt 0
lin: {say, txt:
if s.slice -1 isnt " "
s
else s.slice 0,-1
}
for speech in speeches
_message =
ship:window.urb.ship
thought:
serial:window.util.uuid32()
audience:_audi
statement:
bouquet:[]
speech:speech
date: Date.now()
MessageDispatcher.handleViewAction
type:"message-send"
message:_message
window.talk.MessagePersistence.sendMessage _message.thought

View File

@ -7,6 +7,12 @@ module.exports =
station:station
config:config
loadGlyphs: (glyphs) ->
StationDispatcher.handleServerAction
type: "glyphs-load"
station:station
glyphs:glyphs
switchStation: (station) ->
StationDispatcher.handleViewAction
type:"station-switch"
@ -67,4 +73,4 @@ module.exports =
StationDispatcher.handleViewAction
type: "station-create"
station: station
window.talk.StationPersistence.createStation station
window.talk.StationPersistence.createStation station

View File

@ -7,5 +7,6 @@ module.exports = recl
k = "ship"
k+= " #{@props.presence}" if @props.presence
div {className:"iden"}, [
# div {}, @props.glyph || "*"
div {className:k}, @props.ship
]

View File

@ -1,7 +1,8 @@
moment = require 'moment-timezone'
clas = require 'classnames'
recl = React.createClass
{div,pre,br,input,textarea,a} = React.DOM
{div,pre,br,span,input,textarea,a} = React.DOM
MessageActions = require '../actions/MessageActions.coffee'
MessageStore = require '../stores/MessageStore.coffee'
@ -10,6 +11,7 @@ StationStore = require '../stores/StationStore.coffee'
Member = require './MemberComponent.coffee'
Message = recl
displayName: "Message"
lz: (n) -> if n<10 then "0#{n}" else "#{n}"
convTime: (time) ->
@ -29,54 +31,57 @@ Message = recl
return if user.toLowerCase() is 'system'
@props._handlePm user
renderSpeech: (speech)-> switch
when (con = speech.lin) or (con = speech.app) or
(con = speech.exp) or (con = speech.tax)
con.txt
when (con = speech.url)
(a {href:con.txt,target:"_blank"}, con.txt)
when (con = speech.mor) then con.map @renderSpeech
else "Unknown speech type:" + (" %"+x for x of speech).join ''
render: ->
# pendingClass = if @props.pending isnt "received" then "pending" else ""
# pendingClass = clas pending: @props.pending isnt "received"
delivery = _.uniq _.pluck @props.thought.audience, "delivery"
klass = if delivery.indexOf("received") isnt -1 then " received" else " pending"
speech = @props.thought.statement.speech
attachments = []
while speech.fat?
attachments.push pre {}, speech.fat.tor.tank.join("\n")
speech = speech.fat.taf # XX
if !speech? then return;
if speech.lin?.say is false then klass += " say"
if speech.url then klass += " url"
if @props.unseen is true then klass += " new"
if @props.sameAs is true then klass += " same" else klass += " first"
name = if @props.name then @props.name else ""
aude = _.keys @props.thought.audience
audi = window.util.clipAudi(aude).map (_audi) -> (div {}, _audi.slice(1))
type = ['private','public']
type = type[Number(aude.indexOf(window.util.mainStationPath(window.urb.user)) is -1)]
mainStation = window.util.mainStationPath(window.urb.user)
type = if mainStation in aude then 'private' else 'public'
mess = switch
when (con = speech.lin) or (con = speech.app) or
(con = speech.exp) or (con = speech.tax)
con.txt
when (con = speech.url)
(a {href:con.txt,target:"_blank"}, con.txt)
else "Unknown speech type:" + (" %"+x for x of speech).join ''
klass += switch
when speech.app? then " say"
when speech.exp? then " exp"
else ""
className = clas {message:true},
(if @props.sameAs then "same" else "first"),
(if delivery.indexOf("received") isnt -1 then "received" else "pending"),
{say: speech.lin?.say is false, url: speech.url, 'new': @props.unseen},
switch
when speech.app? then "say"
when speech.exp? then "exp"
div {className:"message#{klass}"}, [
div {className}, [
(div {className:"attr"}, [
div {className:"type #{type}"}, ""
(div {onClick:@_handlePm}, (React.createElement Member,{ship:@props.ship}))
div {className:"type #{type}", "data-glyph": @props.glyph || "*"}
(div {onClick:@_handlePm},
(React.createElement Member,{ship:@props.ship,glyph:@props.glyph}))
div {onClick:@_handleAudi,className:"audi"}, audi
div {className:"time"}, @convTime @props.thought.statement.date
])
div {className:"mess"}, mess,
div {className:"mess"},
(@renderSpeech speech)
if attachments.length
div {className:"fat"}, attachments
]
module.exports = recl
displayName: "Messages"
pageSize: 50
paddingTop: 100
@ -89,6 +94,7 @@ module.exports = recl
stations:StationStore.getStations()
configs:StationStore.getConfigs()
typing:MessageStore.getTyping()
glyph:StationStore.getGlyphMap()
}
getInitialState: -> @stateFromStore()
@ -122,7 +128,8 @@ module.exports = recl
sortedMessages: (messages) ->
_.sortBy messages, (_message) ->
_message.pending = _message.thought.audience[station]
_message.thought.statement.date
_message.key
#_message.thought.statement.date
componentDidMount: ->
MessageStore.addChangeListener @_onChangeStore
@ -189,14 +196,18 @@ module.exports = recl
lastIndex = if @lastSeen then _messages.indexOf(@lastSeen)+1 else null
lastSaid = null
messages = _messages.map (_message,k) =>
if lastIndex and lastIndex is k then _message.unseen = true
div {id: "messages"}, _messages.map (_message,k) =>
nowSaid = [_message.ship,_message.thought.audience]
{station} = @state
mess = {
station, @_handlePm, @_handleAudi,
glyph: @state.glyph[(_.keys _message.thought.audience).join " "]
unseen: lastIndex and lastIndex is k
sameAs: _.isEqual lastSaid, nowSaid
}
lastSaid = nowSaid
if _message.thought.statement.speech?.app
_message.ship = "system"
_message.sameAs = lastSaid is _message.ship
_message.station = @state.station
_message._handlePm = @_handlePm
_message._handleAudi = @_handleAudi
lastSaid = _message.ship
React.createElement Message,_message
div {id: "messages"}, messages
mess.ship = "system"
React.createElement Message, (_.extend {}, _message, mess)

View File

@ -7,7 +7,70 @@ StationActions = require '../actions/StationActions.coffee'
StationStore = require '../stores/StationStore.coffee'
Member = require './MemberComponent.coffee'
SHIPSHAPE = ///
^~?( #preamble
[a-z]{3} # galaxy
| [a-z]{6}(-[a-z]{6}){0,3} # star - moon
| [a-z]{6}(-[a-z]{6}){3} # comet
(--[a-z]{6}(-[a-z]{6}){3})+ #
)$ #postamble
///
PO = '''
dozmarbinwansamlitsighidfidlissogdirwacsabwissib
rigsoldopmodfoglidhopdardorlorhodfolrintogsilmir
holpaslacrovlivdalsatlibtabhanticpidtorbolfosdot
losdilforpilramtirwintadbicdifrocwidbisdasmidlop
rilnardapmolsanlocnovsitnidtipsicropwitnatpanmin
ritpodmottamtolsavposnapnopsomfinfonbanporworsip
ronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig
sivtagpadsaldivdactansidfabtarmonranniswolmispal
lasdismaprabtobrollatlonnodnavfignomnibpagsopral
bilhaddocridmocpacravripfaltodtiltinhapmicfanpat
taclabmogsimsonpinlomrictapfirhasbosbatpochactid
havsaplindibhosdabbitbarracparloddosbortochilmac
tomdigfilfasmithobharmighinradmashalraglagfadtop
mophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc
nimlarfitwalrapsarnalmoslandondanladdovrivbacpol
laptalpitnambonrostonfodponsovnocsorlavmatmipfap
zodnecbudwessevpersutletfulpensytdurwepserwylsun
rypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex
lunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb
pyldulhetmevruttylwydtepbesdexsefwycburderneppur
rysrebdennutsubpetrulsynregtydsupsemwynrecmegnet
secmulnymtevwebsummutnyxrextebfushepbenmuswyxsym
selrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel
syptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed
lytdusnebrumtynseglyxpunresredfunrevrefmectedrus
bexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer
tenlusnussyltecmexpubrymtucfyllepdebbermughuttun
bylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl
wedducfurfexnulluclennerlexrupnedlecrydlydfenwel
nydhusrelrudneshesfetdesretdunlernyrsebhulryllud
remlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun
lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes
'''
Audience = recl
displayName: "Audience"
onKeyDown: (e) ->
if e.keyCode is 13
e.preventDefault()
setTimeout () ->
$('#writing').focus()
,0
return false
render: ->
div {
id:"audi"
className:"audi valid-#{@props.valid}"
contentEditable:true
@onKeyDown
onBlur:@props.onBlur
}, @props.audi.join(" ")
module.exports = recl
displayName: "Writing"
set: ->
if window.localStorage and @$writing then window.localStorage.setItem 'writing', @$writing.text()
@ -26,20 +89,21 @@ module.exports = recl
s.ludi = _.without s.ludi, window.util.mainStationPath window.urb.user
s
getInitialState: -> @stateFromStore()
getInitialState: -> _.extend @stateFromStore(), length:0, lengthy: false
typing: (state) ->
if @state.typing[@state.station] isnt state
StationActions.setTyping @state.station,state
_blur: ->
onBlur: ->
@$writing.text @$writing.text()
MessageActions.setTyping false
@typing false
_focus: ->
onFocus: ->
MessageActions.setTyping true
@typing true
@cursorAtEnd
addCC: (audi) ->
listening = @state.config[window.util.mainStation(window.urb.user)].sources
@ -61,23 +125,16 @@ module.exports = recl
else
audi = @state.audi
audi = @addCC audi
MessageActions.sendMessage @$writing.text().trim(),audi
@$length.text "0/62"
txt = @$writing.text().trim().replace(/\xa0/g,' ')
MessageActions.sendMessage txt,audi
@$writing.text('')
@setState length:0
@set()
@typing false
_audiKeyDown: (e) ->
if e.keyCode is 13
e.preventDefault()
setTimeout () ->
$('#writing').focus()
,0
return false
_writingKeyUp: (e) ->
onKeyUp: (e) ->
if not window.urb.util.isURL @$writing.text()
@$length.toggleClass('valid-false',(@$writing.text().length > 62))
@setState lengthy: (@$writing.text().length > 62)
# r = window.getSelection().getRangeAt(0).cloneRange()
# @$writing.text @$writing.text()
# setTimeout =>
@ -86,19 +143,18 @@ module.exports = recl
# s.addRange r
# console.log r
# ,0
_writingKeyDown: (e) ->
onKeyDown: (e) ->
if e.keyCode is 13
txt = @$writing.text()
e.preventDefault()
if ( (txt.length > 0 and txt.length < 63) or
window.urb.util.isURL @$writing.text() )
if txt.length > 0
@sendMessage()
return false
@_input()
@onInput()
@set()
_input: (e) ->
onInput: (e) ->
text = @$writing.text()
length = text.length
# geturl = new RegExp [
@ -113,11 +169,10 @@ module.exports = recl
# for url in urls
# length -= url.length
# length += 10
@$length.text "#{length}/62"
_setFocus: -> @$writing.focus()
@setState {length}
_validateAudiPart: (a) ->
a = a.trim()
# if a[0] isnt "~"
# return false
if a.indexOf("/") isnt -1
@ -127,9 +182,9 @@ module.exports = recl
ship = _a[0]
else
ship = a
if ship.length < 3
return false
return true
return (SHIPSHAPE.test ship) and
_.all (ship.match /[a-z]{3}/g), (a)-> -1 isnt PO.indexOf a
_validateAudi: ->
v = $('#audi').text()
@ -138,23 +193,17 @@ module.exports = recl
return true
if v.length < 5 # zod/a is shortest
return false
v = v.split " "
for a in v
a = a.trim()
valid = @_validateAudiPart(a)
valid
_.all (v.split /\ +/), @_validateAudiPart
_setAudi: ->
valid = @_validateAudi()
StationActions.setValidAudience valid
if valid is true
v = $('#audi').text()
if v.length is 0 then v = window.util.mainStationPath window.urb.user
v = v.split " "
for k,_v of v
if _v[0] isnt "~" then v[k] = "~#{_v}"
StationActions.setAudience v
v
stan = $('#audi').text() || window.util.mainStationPath window.urb.user
stan = (stan.split /\ +/).map (v)->
if v[0] is "~" then v else "~"+v
StationActions.setAudience stan
stan
else
false
@ -178,12 +227,11 @@ module.exports = recl
StationStore.addChangeListener @_onChangeStore
MessageStore.addChangeListener @_onChangeStore
@$el = $ @getDOMNode()
@$length = $('#length')
@$writing = $('#writing')
@$writing.focus()
if @get()
@$writing.text @get()
@_input()
@onInput()
@interval = setInterval =>
@$el.find('.time').text @getTime()
, 1000
@ -210,25 +258,14 @@ module.exports = recl
div {className:k}, [
(div {className:"attr"}, [
(React.createElement Member, iden)
(div {
id:"audi"
className:"audi valid-#{@state.valid}"
contentEditable:true
onKeyDown: @_audiKeyDown
onBlur:@_setAudi
}, audi.join(" "))
(React.createElement Audience, {audi,valid:@state.valid, onBlur:@_setAudi})
(div {className:"time"}, @getTime())
])
(div {
id:"writing"
contentEditable:true
onFocus: @_focus
onBlur: @_blur
onInput: @_input
onPaste: @_input
onKeyDown: @_writingKeyDown
onKeyUp: @_writingKeyUp
onFocus: @cursorAtEnd
onPaste: @onInput
@onInput, @onFocus, @onBlur, @onKeyDown, @onKeyUp
}, "")
div {id:"length"}, "0/62"
(div {id:"length"}, "#{@state.length}/64 (#{Math.ceil @state.length / 64})")
]

View File

@ -25,16 +25,12 @@ $(() ->
$c = $('#c')
clean = ->
React.unmountComponentAtNode $('#station-container')[0]
React.unmountComponentAtNode $('#messages-container')[0]
React.unmountComponentAtNode $('#writing-container')[0]
# clean = -> # ??
# React.unmountComponentAtNode $('#station-container')[0]
# React.unmountComponentAtNode $('#messages-container')[0]
# React.unmountComponentAtNode $('#writing-container')[0]
$c.append "<div id='station-container'></div>"
$c.append "<div id='messages-container'></div>"
$c.append "<div id='writing-container'></div>"
$c.append "<div id='scrolling'>BOTTOM</div>"
rend (React.createElement(StationComponent, {})),$('#station-container')[0]
rend (React.createElement(MessagesComponent, {})),$('#messages-container')[0]
rend (React.createElement(WritingComponent, {})),$('#writing-container')[0]
)
)

View File

@ -37,7 +37,7 @@ module.exports = {
return window.talk.MessagePersistence.get(station, start, end);
},
sendMessage: function(message, audience) {
var _audi, _message, k, serial, speech, v;
var _audi, _message, j, k, len, ref, ref1, results, say, serial, speech, speeches, txt, v;
serial = window.util.uuid32();
audience = _.uniq(audience);
_audi = {};
@ -69,23 +69,37 @@ module.exports = {
url: message
};
}
_message = {
ship: window.urb.ship,
thought: {
serial: serial,
audience: _audi,
statement: {
bouquet: [],
speech: speech,
date: Date.now()
speeches = !(((ref = speech.lin) != null ? ref.txt.length : void 0) > 64) ? [speech] : ((ref1 = speech.lin, say = ref1.say, txt = ref1.txt, ref1), txt.match(/(.{1,64}$|.{0,64} |.{64}|.+$)/g).map(function(s, i) {
say || (say = i !== 0);
return {
lin: {
say: say,
txt: s.slice(-1 !== " ") ? s : s.slice(0, -1)
}
}
};
MessageDispatcher.handleViewAction({
type: "message-send",
message: _message
});
return window.talk.MessagePersistence.sendMessage(_message.thought);
};
}));
results = [];
for (j = 0, len = speeches.length; j < len; j++) {
speech = speeches[j];
_message = {
ship: window.urb.ship,
thought: {
serial: window.util.uuid32(),
audience: _audi,
statement: {
bouquet: [],
speech: speech,
date: Date.now()
}
}
};
MessageDispatcher.handleViewAction({
type: "message-send",
message: _message
});
results.push(window.talk.MessagePersistence.sendMessage(_message.thought));
}
return results;
}
};
@ -104,6 +118,13 @@ module.exports = {
config: config
});
},
loadGlyphs: function(glyphs) {
return StationDispatcher.handleServerAction({
type: "glyphs-load",
station: station,
glyphs: glyphs
});
},
switchStation: function(station) {
return StationDispatcher.handleViewAction({
type: "station-switch",
@ -209,13 +230,16 @@ module.exports = recl({
},{}],4:[function(require,module,exports){
var Member, Message, MessageActions, MessageStore, StationActions, StationStore, a, br, div, input, moment, pre, recl, ref, textarea;
var Member, Message, MessageActions, MessageStore, StationActions, StationStore, a, br, clas, div, input, moment, pre, recl, ref, span, textarea,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
moment = require('moment-timezone');
clas = require('classnames');
recl = React.createClass;
ref = React.DOM, div = ref.div, pre = ref.pre, br = ref.br, input = ref.input, textarea = ref.textarea, a = ref.a;
ref = React.DOM, div = ref.div, pre = ref.pre, br = ref.br, span = ref.span, input = ref.input, textarea = ref.textarea, a = ref.a;
MessageActions = require('../actions/MessageActions.coffee');
@ -228,6 +252,7 @@ StationStore = require('../stores/StationStore.coffee');
Member = require('./MemberComponent.coffee');
Message = recl({
displayName: "Message",
lz: function(n) {
if (n < 10) {
return "0" + n;
@ -261,10 +286,32 @@ Message = recl({
}
return this.props._handlePm(user);
},
renderSpeech: function(speech) {
var con, x;
switch (false) {
case !((con = speech.lin) || (con = speech.app) || (con = speech.exp) || (con = speech.tax)):
return con.txt;
case !(con = speech.url):
return a({
href: con.txt,
target: "_blank"
}, con.txt);
case !(con = speech.mor):
return con.map(this.renderSpeech);
default:
return "Unknown speech type:" + ((function() {
var results;
results = [];
for (x in speech) {
results.push(" %" + x);
}
return results;
})()).join('');
}
},
render: function() {
var attachments, aude, audi, con, delivery, klass, mess, name, ref1, speech, type, x;
var attachments, aude, audi, className, delivery, mainStation, name, ref1, speech, type;
delivery = _.uniq(_.pluck(this.props.thought.audience, "delivery"));
klass = delivery.indexOf("received") !== -1 ? " received" : " pending";
speech = this.props.thought.statement.speech;
attachments = [];
while (speech.fat != null) {
@ -274,69 +321,41 @@ Message = recl({
if (speech == null) {
return;
}
if (((ref1 = speech.lin) != null ? ref1.say : void 0) === false) {
klass += " say";
}
if (speech.url) {
klass += " url";
}
if (this.props.unseen === true) {
klass += " new";
}
if (this.props.sameAs === true) {
klass += " same";
} else {
klass += " first";
}
name = this.props.name ? this.props.name : "";
aude = _.keys(this.props.thought.audience);
audi = window.util.clipAudi(aude).map(function(_audi) {
return div({}, _audi.slice(1));
});
type = ['private', 'public'];
type = type[Number(aude.indexOf(window.util.mainStationPath(window.urb.user)) === -1)];
mess = (function() {
switch (false) {
case !((con = speech.lin) || (con = speech.app) || (con = speech.exp) || (con = speech.tax)):
return con.txt;
case !(con = speech.url):
return a({
href: con.txt,
target: "_blank"
}, con.txt);
default:
return "Unknown speech type:" + ((function() {
var results;
results = [];
for (x in speech) {
results.push(" %" + x);
}
return results;
})()).join('');
}
})();
klass += (function() {
mainStation = window.util.mainStationPath(window.urb.user);
type = indexOf.call(aude, mainStation) >= 0 ? 'private' : 'public';
className = clas({
message: true
}, (this.props.sameAs ? "same" : "first"), (delivery.indexOf("received") !== -1 ? "received" : "pending"), {
say: ((ref1 = speech.lin) != null ? ref1.say : void 0) === false,
url: speech.url,
'new': this.props.unseen
}, (function() {
switch (false) {
case speech.app == null:
return " say";
return "say";
case speech.exp == null:
return " exp";
default:
return "";
return "exp";
}
})();
})());
return div({
className: "message" + klass
className: className
}, [
div({
className: "attr"
}, [
div({
className: "type " + type
}, ""), div({
className: "type " + type,
"data-glyph": this.props.glyph || "*"
}), div({
onClick: this._handlePm
}, React.createElement(Member, {
ship: this.props.ship
ship: this.props.ship,
glyph: this.props.glyph
})), div({
onClick: this._handleAudi,
className: "audi"
@ -345,7 +364,7 @@ Message = recl({
}, this.convTime(this.props.thought.statement.date))
]), div({
className: "mess"
}, mess, attachments.length ? div({
}, this.renderSpeech(speech), attachments.length ? div({
className: "fat"
}, attachments) : void 0)
]);
@ -353,6 +372,7 @@ Message = recl({
});
module.exports = recl({
displayName: "Messages",
pageSize: 50,
paddingTop: 100,
stateFromStore: function() {
@ -364,7 +384,8 @@ module.exports = recl({
station: window.util.mainStation(),
stations: StationStore.getStations(),
configs: StationStore.getConfigs(),
typing: MessageStore.getTyping()
typing: MessageStore.getTyping(),
glyph: StationStore.getGlyphMap()
};
},
getInitialState: function() {
@ -402,7 +423,7 @@ module.exports = recl({
sortedMessages: function(messages) {
return _.sortBy(messages, function(_message) {
_message.pending = _message.thought.audience[station];
return _message.thought.statement.date;
return _message.key;
});
},
componentDidMount: function() {
@ -463,7 +484,7 @@ module.exports = recl({
return StationActions.setAudience(audi);
},
render: function() {
var _messages, _station, lastIndex, lastSaid, messages, ref1, ref2, ref3, sources, station;
var _messages, _station, lastIndex, lastSaid, ref1, ref2, ref3, sources, station;
station = this.state.station;
_station = "~" + window.urb.ship + "/" + station;
sources = _.clone((ref1 = (ref2 = this.state.configs[this.state.station]) != null ? ref2.sources : void 0) != null ? ref1 : []);
@ -483,32 +504,34 @@ module.exports = recl({
})(this), 1);
lastIndex = this.lastSeen ? _messages.indexOf(this.lastSeen) + 1 : null;
lastSaid = null;
messages = _messages.map((function(_this) {
return function(_message, k) {
var ref4;
if (lastIndex && lastIndex === k) {
_message.unseen = true;
}
if ((ref4 = _message.thought.statement.speech) != null ? ref4.app : void 0) {
_message.ship = "system";
}
_message.sameAs = lastSaid === _message.ship;
_message.station = _this.state.station;
_message._handlePm = _this._handlePm;
_message._handleAudi = _this._handleAudi;
lastSaid = _message.ship;
return React.createElement(Message, _message);
};
})(this));
return div({
id: "messages"
}, messages);
}, _messages.map((function(_this) {
return function(_message, k) {
var mess, nowSaid, ref4;
nowSaid = [_message.ship, _message.thought.audience];
station = _this.state.station;
mess = {
station: station,
_handlePm: _this._handlePm,
_handleAudi: _this._handleAudi,
glyph: _this.state.glyph[(_.keys(_message.thought.audience)).join(" ")],
unseen: lastIndex && lastIndex === k,
sameAs: _.isEqual(lastSaid, nowSaid)
};
lastSaid = nowSaid;
if ((ref4 = _message.thought.statement.speech) != null ? ref4.app : void 0) {
mess.ship = "system";
}
return React.createElement(Message, _.extend({}, _message, mess));
};
})(this)));
}
});
},{"../actions/MessageActions.coffee":1,"../actions/StationActions.coffee":2,"../stores/MessageStore.coffee":19,"../stores/StationStore.coffee":20,"./MemberComponent.coffee":3,"moment-timezone":14}],5:[function(require,module,exports){
},{"../actions/MessageActions.coffee":1,"../actions/StationActions.coffee":2,"../stores/MessageStore.coffee":20,"../stores/StationStore.coffee":21,"./MemberComponent.coffee":3,"classnames":10,"moment-timezone":15}],5:[function(require,module,exports){
var Member, StationActions, StationStore, a, div, h1, input, recl, ref, textarea;
recl = React.createClass;
@ -695,8 +718,8 @@ module.exports = recl({
},{"../actions/StationActions.coffee":2,"../stores/StationStore.coffee":20,"./MemberComponent.coffee":3}],6:[function(require,module,exports){
var Member, MessageActions, MessageStore, StationActions, StationStore, br, div, input, recl, ref, textarea;
},{"../actions/StationActions.coffee":2,"../stores/StationStore.coffee":21,"./MemberComponent.coffee":3}],6:[function(require,module,exports){
var Audience, Member, MessageActions, MessageStore, PO, SHIPSHAPE, StationActions, StationStore, br, div, input, recl, ref, textarea;
recl = React.createClass;
@ -712,7 +735,34 @@ StationStore = require('../stores/StationStore.coffee');
Member = require('./MemberComponent.coffee');
SHIPSHAPE = /^~?([a-z]{3}|[a-z]{6}(-[a-z]{6}){0,3}|[a-z]{6}(-[a-z]{6}){3}(--[a-z]{6}(-[a-z]{6}){3})+)$/;
PO = 'dozmarbinwansamlitsighidfidlissogdirwacsabwissib\nrigsoldopmodfoglidhopdardorlorhodfolrintogsilmir\nholpaslacrovlivdalsatlibtabhanticpidtorbolfosdot\nlosdilforpilramtirwintadbicdifrocwidbisdasmidlop\nrilnardapmolsanlocnovsitnidtipsicropwitnatpanmin\nritpodmottamtolsavposnapnopsomfinfonbanporworsip\nronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig\nsivtagpadsaldivdactansidfabtarmonranniswolmispal\nlasdismaprabtobrollatlonnodnavfignomnibpagsopral\nbilhaddocridmocpacravripfaltodtiltinhapmicfanpat\ntaclabmogsimsonpinlomrictapfirhasbosbatpochactid\nhavsaplindibhosdabbitbarracparloddosbortochilmac\ntomdigfilfasmithobharmighinradmashalraglagfadtop\nmophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc\nnimlarfitwalrapsarnalmoslandondanladdovrivbacpol\nlaptalpitnambonrostonfodponsovnocsorlavmatmipfap\n\nzodnecbudwessevpersutletfulpensytdurwepserwylsun\nrypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex\nlunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb\npyldulhetmevruttylwydtepbesdexsefwycburderneppur\nrysrebdennutsubpetrulsynregtydsupsemwynrecmegnet\nsecmulnymtevwebsummutnyxrextebfushepbenmuswyxsym\nselrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel\nsyptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed\nlytdusnebrumtynseglyxpunresredfunrevrefmectedrus\nbexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer\ntenlusnussyltecmexpubrymtucfyllepdebbermughuttun\nbylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl\nwedducfurfexnulluclennerlexrupnedlecrydlydfenwel\nnydhusrelrudneshesfetdesretdunlernyrsebhulryllud\nremlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun\nlyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes';
Audience = recl({
displayName: "Audience",
onKeyDown: function(e) {
if (e.keyCode === 13) {
e.preventDefault();
setTimeout(function() {
return $('#writing').focus();
}, 0);
return false;
}
},
render: function() {
return div({
id: "audi",
className: "audi valid-" + this.props.valid,
contentEditable: true,
onKeyDown: this.onKeyDown,
onBlur: this.props.onBlur
}, this.props.audi.join(" "));
}
});
module.exports = recl({
displayName: "Writing",
set: function() {
if (window.localStorage && this.$writing) {
return window.localStorage.setItem('writing', this.$writing.text());
@ -738,21 +788,25 @@ module.exports = recl({
return s;
},
getInitialState: function() {
return this.stateFromStore();
return _.extend(this.stateFromStore(), {
length: 0,
lengthy: false
});
},
typing: function(state) {
if (this.state.typing[this.state.station] !== state) {
return StationActions.setTyping(this.state.station, state);
}
},
_blur: function() {
onBlur: function() {
this.$writing.text(this.$writing.text());
MessageActions.setTyping(false);
return this.typing(false);
},
_focus: function() {
onFocus: function() {
MessageActions.setTyping(true);
return this.typing(true);
this.typing(true);
return this.cursorAtEnd;
},
addCC: function(audi) {
var cc, i, len, listening, s;
@ -773,7 +827,7 @@ module.exports = recl({
return audi;
},
sendMessage: function() {
var audi;
var audi, txt;
if (this._validateAudi() === false) {
$('#audi').focus();
return;
@ -784,50 +838,46 @@ module.exports = recl({
audi = this.state.audi;
}
audi = this.addCC(audi);
MessageActions.sendMessage(this.$writing.text().trim(), audi);
this.$length.text("0/62");
txt = this.$writing.text().trim().replace(/\xa0/g, ' ');
MessageActions.sendMessage(txt, audi);
this.$writing.text('');
this.setState({
length: 0
});
this.set();
return this.typing(false);
},
_audiKeyDown: function(e) {
if (e.keyCode === 13) {
e.preventDefault();
setTimeout(function() {
return $('#writing').focus();
}, 0);
return false;
}
},
_writingKeyUp: function(e) {
onKeyUp: function(e) {
if (!window.urb.util.isURL(this.$writing.text())) {
return this.$length.toggleClass('valid-false', this.$writing.text().length > 62);
return this.setState({
lengthy: this.$writing.text().length > 62
});
}
},
_writingKeyDown: function(e) {
onKeyDown: function(e) {
var txt;
if (e.keyCode === 13) {
txt = this.$writing.text();
e.preventDefault();
if ((txt.length > 0 && txt.length < 63) || window.urb.util.isURL(this.$writing.text())) {
if (txt.length > 0) {
this.sendMessage();
}
return false;
}
this._input();
this.onInput();
return this.set();
},
_input: function(e) {
onInput: function(e) {
var length, text;
text = this.$writing.text();
length = text.length;
return this.$length.text(length + "/62");
},
_setFocus: function() {
return this.$writing.focus();
return this.setState({
length: length
});
},
_validateAudiPart: function(a) {
var _a, ship;
a = a.trim();
if (a.indexOf("/") !== -1) {
_a = a.split("/");
if (_a[1].length === 0) {
@ -837,13 +887,12 @@ module.exports = recl({
} else {
ship = a;
}
if (ship.length < 3) {
return false;
}
return true;
return (SHIPSHAPE.test(ship)) && _.all(ship.match(/[a-z]{3}/g), function(a) {
return -1 !== PO.indexOf(a);
});
},
_validateAudi: function() {
var a, i, len, v, valid;
var v;
v = $('#audi').text();
v = v.trim();
if (v.length === 0) {
@ -852,32 +901,23 @@ module.exports = recl({
if (v.length < 5) {
return false;
}
v = v.split(" ");
for (i = 0, len = v.length; i < len; i++) {
a = v[i];
a = a.trim();
valid = this._validateAudiPart(a);
}
return valid;
return _.all(v.split(/\ +/), this._validateAudiPart);
},
_setAudi: function() {
var _v, k, v, valid;
var stan, valid;
valid = this._validateAudi();
StationActions.setValidAudience(valid);
if (valid === true) {
v = $('#audi').text();
if (v.length === 0) {
v = window.util.mainStationPath(window.urb.user);
}
v = v.split(" ");
for (k in v) {
_v = v[k];
if (_v[0] !== "~") {
v[k] = "~" + _v;
stan = $('#audi').text() || window.util.mainStationPath(window.urb.user);
stan = (stan.split(/\ +/)).map(function(v) {
if (v[0] === "~") {
return v;
} else {
return "~" + v;
}
}
StationActions.setAudience(v);
return v;
});
StationActions.setAudience(stan);
return stan;
} else {
return false;
}
@ -905,12 +945,11 @@ module.exports = recl({
StationStore.addChangeListener(this._onChangeStore);
MessageStore.addChangeListener(this._onChangeStore);
this.$el = $(this.getDOMNode());
this.$length = $('#length');
this.$writing = $('#writing');
this.$writing.focus();
if (this.get()) {
this.$writing.text(this.get());
this._input();
this.onInput();
}
return this.interval = setInterval((function(_this) {
return function() {
@ -944,35 +983,32 @@ module.exports = recl({
div({
className: "attr"
}, [
React.createElement(Member, iden), div({
id: "audi",
className: "audi valid-" + this.state.valid,
contentEditable: true,
onKeyDown: this._audiKeyDown,
React.createElement(Member, iden), React.createElement(Audience, {
audi: audi,
valid: this.state.valid,
onBlur: this._setAudi
}, audi.join(" ")), div({
}), div({
className: "time"
}, this.getTime())
]), div({
id: "writing",
contentEditable: true,
onFocus: this._focus,
onBlur: this._blur,
onInput: this._input,
onPaste: this._input,
onKeyDown: this._writingKeyDown,
onKeyUp: this._writingKeyUp,
onFocus: this.cursorAtEnd
onPaste: this.onInput,
onInput: this.onInput,
onFocus: this.onFocus,
onBlur: this.onBlur,
onKeyDown: this.onKeyDown,
onKeyUp: this.onKeyUp
}, ""), div({
id: "length"
}, "0/62")
}, this.state.length + "/64 (" + (Math.ceil(this.state.length / 64)) + ")")
]);
}
});
},{"../actions/MessageActions.coffee":1,"../actions/StationActions.coffee":2,"../stores/MessageStore.coffee":19,"../stores/StationStore.coffee":20,"./MemberComponent.coffee":3}],7:[function(require,module,exports){
},{"../actions/MessageActions.coffee":1,"../actions/StationActions.coffee":2,"../stores/MessageStore.coffee":20,"../stores/StationStore.coffee":21,"./MemberComponent.coffee":3}],7:[function(require,module,exports){
var Dispatcher;
Dispatcher = require('flux').Dispatcher;
@ -994,9 +1030,9 @@ module.exports = _.merge(new Dispatcher(), {
},{"flux":10}],8:[function(require,module,exports){
},{"flux":11}],8:[function(require,module,exports){
$(function() {
var $c, MessagesComponent, StationActions, StationComponent, WritingComponent, clean, rend;
var $c, MessagesComponent, StationActions, StationComponent, WritingComponent, rend;
StationActions = require('./actions/StationActions.coffee');
rend = React.render;
window.talk = {};
@ -1009,15 +1045,6 @@ $(function() {
MessagesComponent = require('./components/MessagesComponent.coffee');
WritingComponent = require('./components/WritingComponent.coffee');
$c = $('#c');
clean = function() {
React.unmountComponentAtNode($('#station-container')[0]);
React.unmountComponentAtNode($('#messages-container')[0]);
return React.unmountComponentAtNode($('#writing-container')[0]);
};
$c.append("<div id='station-container'></div>");
$c.append("<div id='messages-container'></div>");
$c.append("<div id='writing-container'></div>");
$c.append("<div id='scrolling'>BOTTOM</div>");
rend(React.createElement(StationComponent, {}), $('#station-container')[0]);
rend(React.createElement(MessagesComponent, {}), $('#messages-container')[0]);
return rend(React.createElement(WritingComponent, {}), $('#writing-container')[0]);
@ -1025,7 +1052,7 @@ $(function() {
},{"./actions/StationActions.coffee":2,"./components/MessagesComponent.coffee":4,"./components/StationComponent.coffee":5,"./components/WritingComponent.coffee":6,"./move.coffee":9,"./persistence/MessagePersistence.coffee":17,"./persistence/StationPersistence.coffee":18,"./util.coffee":21}],9:[function(require,module,exports){
},{"./actions/StationActions.coffee":2,"./components/MessagesComponent.coffee":4,"./components/StationComponent.coffee":5,"./components/WritingComponent.coffee":6,"./move.coffee":9,"./persistence/MessagePersistence.coffee":18,"./persistence/StationPersistence.coffee":19,"./util.coffee":22}],9:[function(require,module,exports){
var ldy, setSo, so;
so = {};
@ -1127,6 +1154,56 @@ $(window).on('scroll', window.util.checkScroll);
},{}],10:[function(require,module,exports){
/*!
Copyright (c) 2015 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
function classNames () {
var classes = '';
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes += ' ' + arg;
} else if (Array.isArray(arg)) {
classes += ' ' + classNames.apply(null, arg);
} else if (argType === 'object') {
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes += ' ' + key;
}
}
}
}
return classes.substr(1);
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// register as 'classnames', consistent with npm package name
define('classnames', function () {
return classNames;
});
} else {
window.classNames = classNames;
}
}());
},{}],11:[function(require,module,exports){
/**
* Copyright (c) 2014-2015, Facebook, Inc.
* All rights reserved.
@ -1138,7 +1215,7 @@ $(window).on('scroll', window.util.checkScroll);
module.exports.Dispatcher = require('./lib/Dispatcher')
},{"./lib/Dispatcher":11}],11:[function(require,module,exports){
},{"./lib/Dispatcher":12}],12:[function(require,module,exports){
/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
@ -1390,7 +1467,7 @@ var _prefix = 'ID_';
module.exports = Dispatcher;
},{"./invariant":12}],12:[function(require,module,exports){
},{"./invariant":13}],13:[function(require,module,exports){
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
@ -1445,7 +1522,7 @@ var invariant = function(condition, format, a, b, c, d, e, f) {
module.exports = invariant;
},{}],13:[function(require,module,exports){
},{}],14:[function(require,module,exports){
module.exports={
"version": "2014j",
"zones": [
@ -2035,11 +2112,11 @@ module.exports={
"Pacific/Pohnpei|Pacific/Ponape"
]
}
},{}],14:[function(require,module,exports){
},{}],15:[function(require,module,exports){
var moment = module.exports = require("./moment-timezone");
moment.tz.load(require('./data/packed/latest.json'));
},{"./data/packed/latest.json":13,"./moment-timezone":15}],15:[function(require,module,exports){
},{"./data/packed/latest.json":14,"./moment-timezone":16}],16:[function(require,module,exports){
//! moment-timezone.js
//! version : 0.2.5
//! author : Tim Wood
@ -2442,7 +2519,7 @@ moment.tz.load(require('./data/packed/latest.json'));
return moment;
}));
},{"moment":16}],16:[function(require,module,exports){
},{"moment":17}],17:[function(require,module,exports){
//! moment.js
//! version : 2.10.6
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
@ -5638,7 +5715,7 @@ moment.tz.load(require('./data/packed/latest.json'));
return _moment;
}));
},{}],17:[function(require,module,exports){
},{}],18:[function(require,module,exports){
var MessageActions, send;
MessageActions = require('../actions/MessageActions.coffee');
@ -5712,7 +5789,7 @@ module.exports = {
},{"../actions/MessageActions.coffee":1}],18:[function(require,module,exports){
},{"../actions/MessageActions.coffee":1}],19:[function(require,module,exports){
var StationActions, design, send;
StationActions = require('../actions/StationActions.coffee');
@ -5793,14 +5870,14 @@ module.exports = {
});
},
listenStation: function(station) {
return window.urb.bind("/ax/" + station, function(err, res) {
return window.urb.bind("/avx/" + station, function(err, res) {
var ref;
if (err || !res) {
console.log('/ax/ err');
console.log('/avx/ err');
console.log(err);
return;
}
console.log('/ax/');
console.log('/avx/');
console.log(res.data);
if (res.data.ok === true) {
StationActions.listeningStation(station);
@ -5810,7 +5887,10 @@ module.exports = {
StationActions.loadMembers(res.data.group.global);
}
if ((ref = res.data.cabal) != null ? ref.loc : void 0) {
return StationActions.loadConfig(station, res.data.cabal.loc);
StationActions.loadConfig(station, res.data.cabal.loc);
}
if (res.data.glyph) {
return StationActions.loadGlyphs(res.data.glyph);
}
});
}
@ -5818,7 +5898,7 @@ module.exports = {
},{"../actions/StationActions.coffee":2}],19:[function(require,module,exports){
},{"../actions/StationActions.coffee":2}],20:[function(require,module,exports){
var EventEmitter, MessageDispatcher, MessageStore, _fetching, _last, _listening, _messages, _station, _typing, moment;
moment = require('moment-timezone');
@ -5898,11 +5978,12 @@ MessageStore = _.merge(new EventEmitter, {
return _messages[message.thought.serial] = message;
},
loadMessages: function(messages, last, get) {
var k, serial, v;
for (k in messages) {
v = messages[k];
var i, key, len, serial, v;
key = last;
for (i = 0, len = messages.length; i < len; i++) {
v = messages[i];
serial = v.thought.serial;
v.key = serial;
v.key = key++;
_messages[serial] = v;
}
if (last < _last || _last === null || get === true) {
@ -5964,8 +6045,8 @@ module.exports = MessageStore;
},{"../dispatcher/Dispatcher.coffee":7,"events":22,"moment-timezone":14}],20:[function(require,module,exports){
var EventEmitter, StationDispatcher, StationStore, _audience, _config, _listening, _members, _station, _stations, _typing, _validAudience;
},{"../dispatcher/Dispatcher.coffee":7,"events":23,"moment-timezone":15}],21:[function(require,module,exports){
var EventEmitter, StationDispatcher, StationStore, _audience, _config, _glyphs, _listening, _members, _shpylg, _station, _stations, _typing, _validAudience;
EventEmitter = require('events').EventEmitter;
@ -5985,6 +6066,10 @@ _config = {};
_typing = {};
_glyphs = {};
_shpylg = {};
_validAudience = true;
StationStore = _.merge(new EventEmitter, {
@ -6025,6 +6110,19 @@ StationStore = _.merge(new EventEmitter, {
getConfig: function(station) {
return _config[station];
},
getGlyph: function(station) {
return _shpylg[station];
},
getGlyphMap: function() {
return _shpylg;
},
getGlyphAudience: function(glyph) {
var aud, ref;
aud = (ref = _glyphs[glyph]) != null ? ref : [];
if (aud.length === 1) {
return aud[0];
}
},
getMember: function(ship) {
return {
ship: ship
@ -6072,6 +6170,25 @@ StationStore = _.merge(new EventEmitter, {
loadStations: function(stations) {
return _stations = stations;
},
loadGlyphs: function(glyphs) {
var aud, auds, char, results;
_glyphs = glyphs;
_shpylg = {};
results = [];
for (char in glyphs) {
auds = glyphs[char];
results.push((function() {
var i, len, results1;
results1 = [];
for (i = 0, len = auds.length; i < len; i++) {
aud = auds[i];
results1.push(_shpylg[aud.join(" ")] = char);
}
return results1;
})());
}
return results;
},
getStations: function() {
return _stations;
},
@ -6136,6 +6253,10 @@ StationStore.dispatchToken = StationDispatcher.register(function(payload) {
StationStore.loadConfig(action.station, action.config);
StationStore.emitChange();
break;
case "glyphs-load":
StationStore.loadGlyphs(action.glyphs);
StationStore.emitChange();
break;
case "stations-load":
StationStore.loadStations(action.stations);
StationStore.emitChange();
@ -6164,7 +6285,7 @@ module.exports = StationStore;
},{"../dispatcher/Dispatcher.coffee":7,"events":22}],21:[function(require,module,exports){
},{"../dispatcher/Dispatcher.coffee":7,"events":23}],22:[function(require,module,exports){
if (!window.util) {
window.util = {};
}
@ -6276,7 +6397,7 @@ _.merge(window.util, {
},{}],22:[function(require,module,exports){
},{}],23:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a

View File

@ -2,12 +2,13 @@
"name": "urbit-talk",
"version": "0.0.0",
"repository": {
"type":"git",
"url":"https://github.com/urbit/urbit"
"type": "git",
"url": "https://github.com/urbit/urbit"
},
"description": "urbit talk frontend",
"main": "main.js",
"dependencies": {
"classnames": "^2.2.0",
"coffeeify": "~0.7.0",
"flux": "~2.0.1",
"lodash": "~2.4.1",

View File

@ -38,12 +38,12 @@ module.exports =
if res.data.house
StationActions.loadStations res.data.house
listenStation: (station) -> window.urb.bind "/ax/#{station}", (err,res) ->
listenStation: (station) -> window.urb.bind "/avx/#{station}", (err,res) ->
if err or not res
console.log '/ax/ err'
console.log '/avx/ err'
console.log err
return
console.log('/ax/')
console.log('/avx/')
console.log(res.data)
if res.data.ok is true
StationActions.listeningStation station
@ -53,3 +53,5 @@ module.exports =
StationActions.loadMembers res.data.group.global
if res.data.cabal?.loc
StationActions.loadConfig station,res.data.cabal.loc
if res.data.glyph
StationActions.loadGlyphs res.data.glyph

View File

@ -52,9 +52,10 @@ MessageStore = _.merge new EventEmitter,{
_messages[message.thought.serial] = message
loadMessages: (messages,last,get) ->
for k,v of messages
key = last
for v in messages
serial = v.thought.serial
v.key = serial
v.key = key++
# always overwrite with new
_messages[serial] = v
_last = last if last < _last or _last is null or get is true
@ -103,4 +104,4 @@ MessageStore.dispatchToken = MessageDispatcher.register (payload) ->
MessageStore.emitChange()
break
module.exports = MessageStore
module.exports = MessageStore

View File

@ -9,6 +9,8 @@ _listening = []
_station = null
_config = {}
_typing = {}
_glyphs = {}
_shpylg = {}
_validAudience = true
@ -38,6 +40,15 @@ StationStore = _.merge new EventEmitter,{
getConfigs: -> _config
getConfig: (station) -> _config[station]
getGlyph: (station) -> _shpylg[station]
getGlyphMap: -> _shpylg
getGlyphAudience: (glyph) ->
aud = _glyphs[glyph] ? []
if aud.length is 1
aud[0]
getMember: (ship) -> {ship:ship}
@ -62,6 +73,13 @@ StationStore = _.merge new EventEmitter,{
_stations.push(station) if _stations.indexOf(station) is -1
loadStations: (stations) -> _stations = stations
loadGlyphs: (glyphs) ->
_glyphs = glyphs
_shpylg = {}
for char,auds of glyphs
for aud in auds
_shpylg[aud.join " "] = char
getStations: -> _stations
@ -115,6 +133,10 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
StationStore.loadConfig action.station,action.config
StationStore.emitChange()
break
when "glyphs-load" #[name:'loadConfig', args:['station', 'config']]
StationStore.loadGlyphs action.glyphs
StationStore.emitChange()
break
when "stations-load"
StationStore.loadStations action.stations
StationStore.emitChange()
@ -140,4 +162,4 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
StationStore.emitChange()
break
module.exports = StationStore
module.exports = StationStore

View File

@ -1,46 +1,46 @@
.bar
margin-top 2rem
margin-bottom 2rem
& > div
display inline-block
a.logo
display inline-block
height 2rem
vertical-align middle
border none
img.logo
margin-right 18px
margin-top 0
ul
margin 0
line-height 2rem
display inline-block
li::before
content ''
padding-right none
li
display inline-block
margin-bottom 0
margin-right 1rem
vertical-align middle
li a
border-bottom none
text-decoration underline
li a h1
margin 0
line-height inherit
text-transform capitalize
font-size 1.2rem
h1
text-transform capitalize
font-size 1rem
font-weight 400
letter-spacing .03rem
.lead
#body
margin-top 3rem
margin-top 0
.bar
margin-top 2rem
margin-bottom 2rem
& > div
display inline-block
a.logo
display inline-block
height 2rem
vertical-align middle
border none
img.logo
margin-right 18px
margin-top 0
ul
margin 0
line-height 2rem
display inline-block
li::before
content ''
padding-right none
li
display inline-block
margin-bottom 0
margin-right 1rem
vertical-align middle
li a
border-bottom none
text-decoration underline
li a h1
margin 0
line-height inherit
text-transform capitalize
font-size 1.2rem
h1
text-transform capitalize
font-size 1rem
font-weight 400
letter-spacing .03rem
margin-top 0
h1
margin-top 1rem

View File

@ -155,7 +155,7 @@ pre {
background-color: #f5f5f5;
padding: 0.3rem;
margin-left: -0.3rem;
white-space: pre-line;
overflow-y: scroll;
}
code {
line-height: 1.2rem;
@ -251,12 +251,6 @@ li:before {
transition: opacity 1s ease-in-out;
z-index: 4;
}
img.logo.black {
content: url("https://storage.googleapis.com/urbit-extra/logo/logo-black-100x100.png");
}
img.logo.white {
content: url("https://storage.googleapis.com/urbit-extra/logo/logo-white-100x100.png");
}
img.logo {
height: 2rem;
width: 2rem;
@ -545,58 +539,58 @@ div.post p.ib {
font-weight: 200;
}
}
.lead #body {
margin-top: 3rem;
margin-top: 0;
}
.lead .bar {
.bar {
margin-top: 2rem;
margin-bottom: 2rem;
}
.lead .bar > div {
.bar > div {
display: inline-block;
}
.lead .bar a.logo {
.bar a.logo {
display: inline-block;
height: 2rem;
vertical-align: middle;
border: none;
}
.lead .bar img.logo {
.bar img.logo {
margin-right: 18px;
margin-top: 0;
}
.lead .bar ul {
.bar ul {
margin: 0;
line-height: 2rem;
display: inline-block;
}
.lead .bar ul li::before {
.bar ul li::before {
content: '';
padding-right: none;
}
.lead .bar ul li {
.bar ul li {
display: inline-block;
margin-bottom: 0;
margin-right: 1rem;
vertical-align: middle;
}
.lead .bar ul li a {
.bar ul li a {
border-bottom: none;
text-decoration: underline;
}
.lead .bar ul li a h1 {
.bar ul li a h1 {
margin: 0;
line-height: inherit;
text-transform: capitalize;
font-size: 1.2rem;
}
.lead .bar ul h1 {
.bar ul h1 {
text-transform: capitalize;
font-size: 1rem;
font-weight: 400;
letter-spacing: 0.03rem;
}
.lead #body {
margin-top: 3rem;
margin-top: 0;
}
.lead h1 {
margin-top: 1rem;
vertical-align: middle;

View File

@ -85,7 +85,7 @@ pre
background-color #f5f5f5
padding .3rem
margin-left -.3rem
white-space pre-line
overflow-y scroll
code
line-height 1.2rem

View File

@ -113,6 +113,7 @@ module.exports = query {
setTitle: ->
title = $('#cont h1').first().text() || @props.name
title = @props.meta.title if @props.meta?.title
document.title = "#{title} - #{@props.path}"
setPath: (href,hist) ->

View File

@ -1,17 +1,17 @@
clas = require 'classnames'
logo = require './Logo.coffee'
query = require './Async.coffee'
reactify = require './Reactify.coffee'
recl = React.createClass
{div,p,img,a} = React.DOM
Logo = React.createFactory recl render: ->
{color} = @props
if color is "white" or color is "black" # else?
src = "//storage.googleapis.com/urbit-extra/logo/logo-#{color}-100x100.png"
(img {src,className:"logo"})
Logo = React.createFactory recl
render: ->
{color} = @props
if color is "white" or color is "black" # else?
src = "//storage.googleapis.com/urbit-extra/logo/logo-#{color}-100x100.png"
(a {href:"http://urbit.org",style:{border:"none"}}, [(img {src,className:"logo"})])
Next = React.createFactory query {
path:'t'

View File

@ -4,7 +4,7 @@ reactify = require './Reactify.coffee'
query = require './Async.coffee'
recl = React.createClass
{div,a,ul,li,h1} = React.DOM
{div,pre,span,a,ul,li,h1} = React.DOM
module.exports = query {
path:'t'
@ -21,7 +21,15 @@ module.exports = query {
@props.dataType
posts: @props.dataType is 'post' # needs css update
default: @props['data-source'] is 'default'
(ul {className:k}, @renderList())
kids = @renderList()
unless kids.length is 0 and @props.is404?
return (ul {className:k}, kids)
div {className:k},
h1 {className:'error'}, 'Error: Empty path'
div {},
pre {}, @props.path
span {}, 'is either empty or does not exist.'
renderList: ->
# check if kids all have a sort meta tag

View File

@ -36,7 +36,7 @@ module.exports = {
},{"../dispatcher/Dispatcher.coffee":15,"../persistence/TreePersistence.coffee":21}],2:[function(require,module,exports){
},{"../dispatcher/Dispatcher.coffee":14,"../persistence/TreePersistence.coffee":20}],2:[function(require,module,exports){
var BodyComponent, CLICK, Links, TreeActions, TreeStore, a, clas, div, query, reactify, recl, ref;
clas = require('classnames');
@ -243,8 +243,11 @@ module.exports = query({
});
},
setTitle: function() {
var title;
var ref1, title;
title = $('#cont h1').first().text() || this.props.name;
if ((ref1 = this.props.meta) != null ? ref1.title : void 0) {
title = this.props.meta.title;
}
return document.title = title + " - " + this.props.path;
},
setPath: function(href, hist) {
@ -313,7 +316,7 @@ module.exports = query({
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":22,"./Async.coffee":3,"./BodyComponent.coffee":4,"./Reactify.coffee":12,"classnames":17}],3:[function(require,module,exports){
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":21,"./Async.coffee":3,"./BodyComponent.coffee":4,"./Reactify.coffee":11,"classnames":16}],3:[function(require,module,exports){
var TreeActions, TreeStore, _load, code, div, recl, ref, span;
_load = require('./LoadComponent.coffee');
@ -424,13 +427,11 @@ module.exports = function(queries, Child, load) {
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":22,"./LoadComponent.coffee":10}],4:[function(require,module,exports){
var Logo, Next, a, clas, div, img, logo, p, query, reactify, recl, ref;
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":21,"./LoadComponent.coffee":10}],4:[function(require,module,exports){
var Logo, Next, a, clas, div, img, p, query, reactify, recl, ref;
clas = require('classnames');
logo = require('./Logo.coffee');
query = require('./Async.coffee');
reactify = require('./Reactify.coffee');
@ -446,10 +447,17 @@ Logo = React.createFactory(recl({
if (color === "white" || color === "black") {
src = "//storage.googleapis.com/urbit-extra/logo/logo-" + color + "-100x100.png";
}
return img({
src: src,
className: "logo"
});
return a({
href: "http://urbit.org",
style: {
border: "none"
}
}, [
img({
src: src,
className: "logo"
})
]);
}
}));
@ -525,7 +533,7 @@ module.exports = query({
},{"./Async.coffee":3,"./Logo.coffee":11,"./Reactify.coffee":12,"classnames":17}],5:[function(require,module,exports){
},{"./Async.coffee":3,"./Reactify.coffee":11,"classnames":16}],5:[function(require,module,exports){
var div, recl, ref, textarea;
recl = React.createClass;
@ -572,7 +580,7 @@ module.exports = {
},{"./CodeMirror.coffee":5,"./EmailComponent.coffee":7,"./KidsComponent.coffee":8,"./ListComponent.coffee":9,"./SearchComponent.coffee":13,"./TocComponent.coffee":14}],7:[function(require,module,exports){
},{"./CodeMirror.coffee":5,"./EmailComponent.coffee":7,"./KidsComponent.coffee":8,"./ListComponent.coffee":9,"./SearchComponent.coffee":12,"./TocComponent.coffee":13}],7:[function(require,module,exports){
var button, div, input, p, reactify, recl, ref;
reactify = require('./Reactify.coffee');
@ -653,7 +661,7 @@ module.exports = recl({
},{"./Reactify.coffee":12}],8:[function(require,module,exports){
},{"./Reactify.coffee":11}],8:[function(require,module,exports){
var a, div, hr, li, query, reactify, recl, ref, ul;
reactify = require('./Reactify.coffee');
@ -725,8 +733,8 @@ module.exports = query({
},{"./Async.coffee":3,"./Reactify.coffee":12}],9:[function(require,module,exports){
var a, clas, div, h1, li, query, reactify, recl, ref, ul;
},{"./Async.coffee":3,"./Reactify.coffee":11}],9:[function(require,module,exports){
var a, clas, div, h1, li, pre, query, reactify, recl, ref, span, ul;
clas = require('classnames');
@ -736,7 +744,7 @@ query = require('./Async.coffee');
recl = React.createClass;
ref = React.DOM, div = ref.div, a = ref.a, ul = ref.ul, li = ref.li, h1 = ref.h1;
ref = React.DOM, div = ref.div, pre = ref.pre, span = ref.span, a = ref.a, ul = ref.ul, li = ref.li, h1 = ref.h1;
module.exports = query({
path: 't',
@ -748,16 +756,24 @@ module.exports = query({
}, recl({
displayName: "List",
render: function() {
var k;
var k, kids;
k = clas({
list: true
}, this.props.dataType, {
posts: this.props.dataType === 'post',
"default": this.props['data-source'] === 'default'
});
return ul({
kids = this.renderList();
if (!(kids.length === 0 && (this.props.is404 != null))) {
return ul({
className: k
}, kids);
}
return div({
className: k
}, this.renderList());
}, h1({
className: 'error'
}, 'Error: Empty path'), div({}, pre({}, this.props.path), span({}, 'is either empty or does not exist.')));
},
renderList: function() {
var _date, _k, _keys, date, elem, href, i, item, k, len, parts, path, preview, ref1, ref2, ref3, ref4, ref5, ref6, ref7, results, sorted, title, v;
@ -873,7 +889,7 @@ module.exports = query({
},{"./Async.coffee":3,"./Reactify.coffee":12,"classnames":17}],10:[function(require,module,exports){
},{"./Async.coffee":3,"./Reactify.coffee":11,"classnames":16}],10:[function(require,module,exports){
var div, input, recl, ref, textarea;
recl = React.createClass;
@ -915,11 +931,6 @@ module.exports = recl({
},{}],11:[function(require,module,exports){
},{}],12:[function(require,module,exports){
var Virtual, div, load, reactify, recl, ref, rele, span, walk;
recl = React.createClass;
@ -987,7 +998,7 @@ module.exports = _.extend(reactify, {
},{"./LoadComponent.coffee":10}],13:[function(require,module,exports){
},{"./LoadComponent.coffee":10}],12:[function(require,module,exports){
var a, div, input, query, reactify, recl, ref,
slice = [].slice;
@ -1126,7 +1137,7 @@ module.exports = query({
},{"./Async.coffee":3,"./Reactify.coffee":12}],14:[function(require,module,exports){
},{"./Async.coffee":3,"./Reactify.coffee":11}],13:[function(require,module,exports){
var div, query, reactify, recl,
slice = [].slice;
@ -1255,7 +1266,7 @@ module.exports = query({
},{"./Async.coffee":3,"./Reactify.coffee":12}],15:[function(require,module,exports){
},{"./Async.coffee":3,"./Reactify.coffee":11}],14:[function(require,module,exports){
var Dispatcher;
Dispatcher = require('flux').Dispatcher;
@ -1277,7 +1288,7 @@ module.exports = _.extend(new Dispatcher(), {
},{"flux":18}],16:[function(require,module,exports){
},{"flux":17}],15:[function(require,module,exports){
var rend;
rend = React.render;
@ -1451,7 +1462,7 @@ $(function() {
},{"./actions/TreeActions.coffee":1,"./components/AnchorComponent.coffee":2,"./components/BodyComponent.coffee":4,"./components/Components.coffee":6,"./persistence/TreePersistence.coffee":21}],17:[function(require,module,exports){
},{"./actions/TreeActions.coffee":1,"./components/AnchorComponent.coffee":2,"./components/BodyComponent.coffee":4,"./components/Components.coffee":6,"./persistence/TreePersistence.coffee":20}],16:[function(require,module,exports){
/*!
Copyright (c) 2015 Jed Watson.
Licensed under the MIT License (MIT), see
@ -1501,7 +1512,7 @@ $(function() {
}
}());
},{}],18:[function(require,module,exports){
},{}],17:[function(require,module,exports){
/**
* Copyright (c) 2014-2015, Facebook, Inc.
* All rights reserved.
@ -1513,7 +1524,7 @@ $(function() {
module.exports.Dispatcher = require('./lib/Dispatcher')
},{"./lib/Dispatcher":19}],19:[function(require,module,exports){
},{"./lib/Dispatcher":18}],18:[function(require,module,exports){
/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
@ -1765,7 +1776,7 @@ var _prefix = 'ID_';
module.exports = Dispatcher;
},{"./invariant":20}],20:[function(require,module,exports){
},{"./invariant":19}],19:[function(require,module,exports){
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
@ -1820,7 +1831,7 @@ var invariant = function(condition, format, a, b, c, d, e, f) {
module.exports = invariant;
},{}],21:[function(require,module,exports){
},{}],20:[function(require,module,exports){
var dedup;
dedup = {};
@ -1879,7 +1890,7 @@ module.exports = {
},{}],22:[function(require,module,exports){
},{}],21:[function(require,module,exports){
var EventEmitter, MessageDispatcher, QUERIES, TreeStore, _curr, _data, _tree, clog;
EventEmitter = require('events').EventEmitter;
@ -1937,7 +1948,7 @@ TreeStore = _.extend(EventEmitter.prototype, {
data[k] = have[k];
}
if (query.kids) {
if (have.EMPTY) {
if (have.kids === false) {
data.kids = {};
} else {
for (k in tree) {
@ -2000,7 +2011,7 @@ TreeStore = _.extend(EventEmitter.prototype, {
this.loadValues(tree[k], path + "/" + k, v);
}
if (data.kids && _.isEmpty(data.kids)) {
old.EMPTY = true;
old.kids = false;
}
return _data[path] = old;
},
@ -2105,7 +2116,7 @@ module.exports = TreeStore;
},{"../dispatcher/Dispatcher.coffee":15,"events":23}],23:[function(require,module,exports){
},{"../dispatcher/Dispatcher.coffee":14,"events":22}],22:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
@ -2408,4 +2419,4 @@ function isUndefined(arg) {
return arg === void 0;
}
},{}]},{},[16]);
},{}]},{},[15]);

View File

@ -29,7 +29,7 @@ TreeStore = _.extend EventEmitter.prototype, {
if t isnt QUERIES[k] then throw TypeError "Wrong query type: #{k}, '#{t}'"
data[k] = have[k]
if query.kids
if have.EMPTY
if have.kids is false
data.kids = {}
else for k,sub of tree
data.kids ?= {}
@ -60,16 +60,7 @@ TreeStore = _.extend EventEmitter.prototype, {
@loadValues tree[k], path+"/"+k, v
if data.kids && _.isEmpty data.kids
old.EMPTY = true
# XX why here?
# old.body =
# gn: 'div'
# c: [ {gn:'h1', ga:{className:'error'}, c:['Error: Empty path']}
# {gn:'div', c:[
# {gn:'pre', c:[@getCurr()]}
# {gn:'span', c:['is either empty or does not exist.']}
# # {gn:'list'} XX handle empty snip
# ] }]
old.kids = false
_data[path] = old

View File

@ -21,7 +21,7 @@
"lodash.js/2.4.1/lodash.min.js"
"react/0.13.1/react.js"
==
;script(type "text/javascript", src "/~/at/home/lib/urb.js");
;script(type "text/javascript", src "/~/as/own/~/at/home/lib/urb.js");
;meta(name "viewport", content "width=device-width, height=device-height, ".
"initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0");
;link(type "text/css", rel "stylesheet", href "/home/pub/work/src/css/main.css");

View File

@ -51,6 +51,7 @@
[%grams (pair ,@ud (list telegram))] :: beginning, thoughts
[%group register] :: presence
[%house shelf] :: station set
[%glyph (jug char (set partner))] :: relevant binding
== ::
++ speech :: narrative action
$% [%lan p=span q=@t] :: local announce