├── desk ├── desk.herd ├── desk.bill ├── sys.kelvin ├── sur │ ├── herd.hoon │ ├── verb.hoon │ ├── gato.hoon │ ├── docket.hoon │ ├── plum.hoon │ └── xray.hoon ├── desk.docket-0 ├── mar │ ├── noun.hoon │ ├── docket-0.hoon │ ├── kelvin.hoon │ ├── mime.hoon │ ├── bill.hoon │ ├── herd.hoon │ ├── hoon.hoon │ └── txt.hoon ├── ted │ ├── hello.hoon │ ├── tendiebot │ │ ├── stock.hoon │ │ └── crypto.hoon │ └── weather.hoon ├── lib │ ├── tendiebot │ │ └── quote.hoon │ └── docket.hoon └── app │ └── gato.hoon └── README.md /desk/desk.herd: -------------------------------------------------------------------------------- 1 | ~ -------------------------------------------------------------------------------- /desk/desk.bill: -------------------------------------------------------------------------------- 1 | :~ %gato 2 | == -------------------------------------------------------------------------------- /desk/sys.kelvin: -------------------------------------------------------------------------------- 1 | [%zuse 412] 2 | -------------------------------------------------------------------------------- /desk/sur/herd.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | +$ herd (list beef) 3 | +$ beef [who=$@(%our ship) des=desk ver=$@(%trak case)] 4 | -- 5 | -------------------------------------------------------------------------------- /desk/desk.docket-0: -------------------------------------------------------------------------------- 1 | :~ 2 | title+'Gato' 3 | info+'Chatbot helper' 4 | color+0xab.abab 5 | version+[0 0 1] 6 | license+'MIT' 7 | website+'https://github.com/midsum-salrux/gato' 8 | site+/app/gato 9 | == 10 | -------------------------------------------------------------------------------- /desk/sur/verb.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | +$ event 3 | $% [%on-init ~] 4 | [%on-load ~] 5 | [%on-poke =mark] 6 | [%on-watch =path] 7 | [%on-leave =path] 8 | [%on-agent =wire sign=term] 9 | [%on-arvo =wire vane=term sign=term] 10 | [%on-fail =term] 11 | == 12 | -- -------------------------------------------------------------------------------- /desk/mar/noun.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/noun/mar 3 | :: 4 | /? 310 5 | !: 6 | :::: A minimal noun mark 7 | |_ non=* 8 | ++ grab |% 9 | ++ noun * 10 | -- 11 | ++ grad 12 | |% 13 | ++ form %noun 14 | ++ diff |=(* +<) 15 | ++ pact |=(* +<) 16 | ++ join |=([* *] *(unit *)) 17 | ++ mash |=([[ship desk *] [ship desk *]] `*`~|(%noun-mash !!)) 18 | -- 19 | -- 20 | -------------------------------------------------------------------------------- /desk/mar/docket-0.hoon: -------------------------------------------------------------------------------- 1 | /+ dock=docket 2 | |_ =docket:dock 3 | ++ grow 4 | |% 5 | ++ mime 6 | ^- ^mime 7 | [/text/x-docket (as-octt:mimes:html (spit-docket:mime:dock docket))] 8 | ++ noun docket 9 | ++ json (docket:enjs:dock docket) 10 | -- 11 | ++ grab 12 | |% 13 | :: 14 | ++ mime 15 | |= [=mite len=@ud tex=@] 16 | ^- docket:dock 17 | %- need 18 | %- from-clauses:mime:dock 19 | !<((list clause:dock) (slap !>(~) (ream tex))) 20 | 21 | :: 22 | ++ noun docket:dock 23 | -- 24 | ++ grad %noun 25 | -- 26 | -------------------------------------------------------------------------------- /desk/ted/hello.hoon: -------------------------------------------------------------------------------- 1 | /- spider, *gato 2 | /+ *strandio 3 | :: 4 | :: this is common setup for all threads 5 | :: https://developers.urbit.org/reference/arvo/threads/overview 6 | :: 7 | =, strand=strand:spider 8 | =/ m (strand ,vase) 9 | ^- thread:spider 10 | |= arg=vase 11 | ^- form:m 12 | :: 13 | :: see sur/gato.hoon for type definitions 14 | :: 15 | =/ =bird !<(bird arg) 16 | =/ greeting=tape !<(tape vase.bird) 17 | =/ =reply 18 | (crip "{greeting} {(scow %p author.memo.bird)}! You said {(trip text.bird)}") 19 | %- pure:m 20 | !> [reply vase.bird] 21 | -------------------------------------------------------------------------------- /desk/lib/tendiebot/quote.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | +$ quote [name=tape price=@rd day-change-percent=(unit @rd)] 3 | ++ rd-to-tape 4 | |= [n=@rd] 5 | ^- tape 6 | (r-co:co (rlyd n)) 7 | ++ ud-to-tape 8 | |= [n=@ud] 9 | ^- tape 10 | ((d-co:co 0) n) 11 | ++ format 12 | |= [name=tape price=@rd day-change-percent=(unit @rd)] 13 | ^- tape 14 | =/ change (fall day-change-percent .~0) 15 | ;: weld 16 | name 17 | " $" 18 | (rd-to-tape price) 19 | ?: (sig:rd change) " +" " " 20 | (rd-to-tape change) 21 | "%" 22 | == 23 | ++ ticker-rule ;~(pfix (star buc) (plus next)) 24 | -- 25 | -------------------------------------------------------------------------------- /desk/mar/kelvin.hoon: -------------------------------------------------------------------------------- 1 | |_ kal=waft:clay 2 | ++ grow 3 | |% 4 | ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)] 5 | ++ noun kal 6 | ++ hoon 7 | %+ rap 3 8 | %+ turn 9 | %+ sort 10 | ~(tap in (waft-to-wefts:clay kal)) 11 | |= [a=weft b=weft] 12 | ?: =(lal.a lal.b) 13 | (gte num.a num.b) 14 | (gte lal.a lal.b) 15 | |= =weft 16 | (rap 3 '[%' (scot %tas lal.weft) ' ' (scot %ud num.weft) ']\0a' ~) 17 | :: 18 | ++ txt (to-wain:format hoon) 19 | -- 20 | ++ grab 21 | |% 22 | ++ noun waft:clay 23 | ++ mime 24 | |= [=mite len=@ud tex=@] 25 | (cord-to-waft:clay tex) 26 | -- 27 | ++ grad %noun 28 | -- 29 | -------------------------------------------------------------------------------- /desk/mar/mime.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/mime/mar 3 | :: 4 | /? 310 5 | :: 6 | |_ own=mime 7 | ++ grow 8 | ^? 9 | |% 10 | ++ jam `@`q.q.own 11 | -- 12 | :: 13 | ++ grab :: convert from 14 | ^? 15 | |% 16 | ++ noun mime :: clam from %noun 17 | ++ tape 18 | |=(a=_"" [/application/x-urb-unknown (as-octt:mimes:html a)]) 19 | -- 20 | ++ grad 21 | ^? 22 | |% 23 | ++ form %mime 24 | ++ diff |=(mime +<) 25 | ++ pact |=(mime +<) 26 | ++ join |=([mime mime] `(unit mime)`~) 27 | ++ mash 28 | |= [[ship desk mime] [ship desk mime]] 29 | ^- mime 30 | ~|(%mime-mash !!) 31 | -- 32 | -- 33 | -------------------------------------------------------------------------------- /desk/mar/bill.hoon: -------------------------------------------------------------------------------- 1 | |_ bil=(list dude:gall) 2 | ++ grow 3 | |% 4 | ++ mime `^mime`[/text/x-bill (as-octs:mimes:html hoon)] 5 | ++ noun bil 6 | ++ hoon 7 | ^- @t 8 | |^ (crip (of-wall:format (wrap-lines (spit-duz bil)))) 9 | :: 10 | ++ wrap-lines 11 | |= taz=wall 12 | ^- wall 13 | ?~ taz ["~"]~ 14 | :- (weld ":~ " i.taz) 15 | %- snoc :_ "==" 16 | (turn t.taz |=(t=tape (weld " " t))) 17 | :: 18 | ++ spit-duz 19 | |= duz=(list dude:gall) 20 | ^- wall 21 | (turn duz |=(=dude:gall ['%' (trip dude)])) 22 | -- 23 | ++ txt (to-wain:format hoon) 24 | -- 25 | ++ grab 26 | |% 27 | ++ noun (list dude:gall) 28 | ++ mime 29 | |= [=mite len=@ud tex=@] 30 | ~_ tex 31 | !<((list dude:gall) (slap !>(~) (ream tex))) 32 | -- 33 | ++ grad %noun 34 | -- 35 | -------------------------------------------------------------------------------- /desk/mar/herd.hoon: -------------------------------------------------------------------------------- 1 | /- hd=herd 2 | |_ =herd:hd 3 | ++ grow 4 | |% 5 | ++ noun herd 6 | ++ mime 7 | ^- ^mime 8 | [/text/x-herd (as-octt:mimes:html (spit-herd herd))] 9 | ++ spit-herd 10 | |= =herd:hd 11 | ^- tape 12 | =/ lines=tape (zing (turn herd spit-beef)) 13 | ;: weld 14 | ":~\0a" 15 | lines 16 | "==" 17 | == 18 | ++ spit-beef 19 | |= =beef:hd 20 | ^- tape 21 | =/ [who=$@(%our ship) des=desk ver=$@(%trak case)] beef 22 | =- "[{-} {} {(spit-ver ver)}]\0a" 23 | ?: =(%our who) <(scot %p who)> 24 | ++ spit-ver 25 | |= ver=$@(%trak case) 26 | ^- tape 27 | ?@ ver 28 | "[{} {<(scot -.ver p.ver)>}]" 29 | -- 30 | ++ grab 31 | |% 32 | ++ noun herd:hd 33 | ++ mime 34 | |= [=mite len=@ud tex=@] 35 | ^- herd:hd 36 | !<(herd:hd (slap !>(~) (ream tex))) 37 | -- 38 | ++ grad %noun 39 | -- 40 | -------------------------------------------------------------------------------- /desk/sur/gato.hoon: -------------------------------------------------------------------------------- 1 | /- chat 2 | |% 3 | :: each command is a thread with a vase to store state or configuration such as API keys 4 | :: 5 | :: if your thread is in the %foo desk at /ted/ping/pong/hoon, this would be 6 | :: [%foo %ping-pong] 7 | +$ ted [desk=term name=term] 8 | +$ command [=ted =vase] 9 | +$ quilt (map call=cord command) 10 | :: your thread is passed a bird when it runs 11 | :: text is the first plaintext element from the triggering message, minus the "/foo " command 12 | :: memo is the raw chat message 13 | :: vase is taken from the quilt 14 | +$ bird [text=cord =memo:chat =flag:chat =vase] 15 | :: your thread should return a tuna 16 | :: reply is the message you're sending 17 | :: flag is where to send the reply. you can get it from memo. 18 | :: you can update your command's state or config by returning a different vase 19 | +$ tuna [=reply =vase] 20 | :: you can return either a cord or a full formatted chat message 21 | +$ reply $@(cord content:chat) 22 | -- 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gato 2 | 3 | Gato is a way to make chatbots for urbit groups. 4 | 5 | ## Installing 6 | 7 | `|install ~botter-midsum-salrux %gato` 8 | 9 | ## Dojo Usage 10 | 11 | Add a command with `:gato &add ['hello' [%gato %hello] !>("howdy")]` 12 | 13 | You can remove it later with `:gato &remove 'hello'` 14 | 15 | The bot will respond to `/hello lorem ipsum` with `howdy ~sampel-palnet! You said lorem ipsum` 16 | 17 | To change the configuration, use `:gato &set ['hello' [%gato %hello] !>("good morning")]` 18 | 19 | ## Writing Commands 20 | 21 | Each gato command is a thread. See the [thread guide](https://developers.urbit.org/reference/arvo/threads/overview) for how to write a thread, and [sur/gato.hoon](https://github.com/midsum-salrux/gato/blob/master/desk/sur/gato.hoon) for argument and return types. 22 | 23 | ## Examples 24 | 25 | You can find example commands in [/ted](https://github.com/midsum-salrux/gato/tree/master/desk/ted). So far these include: 26 | 27 | - A weather lookup command with geocoding 28 | - A stock and crypto price lookup command (the famous "Tendiebot") 29 | -------------------------------------------------------------------------------- /desk/ted/tendiebot/stock.hoon: -------------------------------------------------------------------------------- 1 | /- spider, *gato 2 | /+ tendiebot-quote, *strandio 3 | =, strand=strand:spider 4 | =, dejs:format 5 | =/ m (strand ,vase) 6 | |^ ted 7 | ++ mine-json 8 | |= symbol=tape 9 | %- ot 10 | :~ name+sa 11 | close+sa 12 | [%'percent_change' sa] 13 | == 14 | ++ url 15 | |= [symbol=tape api-key=tape] 16 | ^- tape 17 | "https://api.twelvedata.com/quote?symbol={symbol}&apikey={api-key}" 18 | ++ numberize 19 | |= [name=tape price=tape change=tape] 20 | ^- quote:tendiebot-quote 21 | :+ name 22 | (ne (need (de:json:html (crip price)))) 23 | `(ne (need (de:json:html (crip change)))) 24 | ++ ted 25 | ^- thread:spider 26 | |= arg=vase 27 | ^- form:m 28 | =/ m (strand ,vase) 29 | =/ =bird !<(bird arg) 30 | =/ api-key !<(tape vase.bird) 31 | =/ symbol (cuss (scan (trip text.bird) ticker-rule:tendiebot-quote)) 32 | ;< =json bind:m (fetch-json (url symbol api-key)) 33 | =/ result (numberize ((mine-json symbol) json)) 34 | =/ =reply (crip (format:tendiebot-quote result)) 35 | %- pure:m 36 | !> [reply vase.bird] 37 | -- 38 | -------------------------------------------------------------------------------- /desk/ted/tendiebot/crypto.hoon: -------------------------------------------------------------------------------- 1 | /- spider, *gato 2 | /+ tendiebot-quote, *strandio 3 | =, strand=strand:spider 4 | =, dejs:format 5 | =/ m (strand ,vase) 6 | |^ ted 7 | ++ mine-json 8 | |= symbol=tape 9 | %- ot 10 | :~ :- %data 11 | %- ot 12 | :~ :- `@tas`(crip symbol) 13 | %- ar 14 | %- ot 15 | :~ name+sa 16 | :- %quote 17 | %- ot 18 | :~ :- %'USD' 19 | %- ot 20 | :~ [%price ne] 21 | [%'percent_change_24h' (mu ne)] 22 | == 23 | == 24 | == 25 | == 26 | == 27 | ++ url 28 | |= [symbol=tape api-key=tape] 29 | ^- tape 30 | "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol={symbol}&CMC_PRO_API_KEY={api-key}" 31 | ++ ted 32 | ^- thread:spider 33 | |= arg=vase 34 | ^- form:m 35 | =/ m (strand ,vase) 36 | =/ =bird !<(bird arg) 37 | =/ api-key !<(tape vase.bird) 38 | =/ symbol (cuss (scan (trip text.bird) ticker-rule:tendiebot-quote)) 39 | ;< =json bind:m (fetch-json (url symbol api-key)) 40 | =/ result `quote:tendiebot-quote`(snag 0 ((mine-json symbol) json)) 41 | =/ =reply (crip (format:tendiebot-quote result)) 42 | %- pure:m 43 | !> [reply vase.bird] 44 | -- 45 | -------------------------------------------------------------------------------- /desk/mar/hoon.hoon: -------------------------------------------------------------------------------- 1 | :::: /hoon/hoon/mar 2 | :: 3 | /? 310 4 | :: 5 | =, eyre 6 | |_ own=@t 7 | :: 8 | ++ grow :: convert to 9 | |% 10 | ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime 11 | ++ elem :: convert to %html 12 | ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}" 13 | :: =+ gen-id="src-{<`@ui`(mug own)>}" 14 | :: ;div 15 | :: ;textarea(id "{gen-id}"):"{(trip own)}" 16 | :: ;script:""" 17 | :: CodeMirror.fromTextArea( 18 | :: window[{}], 19 | :: \{lineNumbers:true, readOnly:true} 20 | :: ) 21 | :: """ 22 | :: == 23 | ++ hymn 24 | :: ;html:(head:title:"Source" "+{elem}") 25 | ;html 26 | ;head 27 | ;title:"Source" 28 | ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"; 29 | ;script@"/lib/syntax/hoon.js"; 30 | ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/". 31 | "codemirror/4.3.0/codemirror.min.css"); 32 | ;link/"/lib/syntax/codemirror.css"(rel "stylesheet"); 33 | == 34 | ;body 35 | ;textarea#src:"{(trip own)}" 36 | ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})' 37 | == 38 | == 39 | ++ txt 40 | (to-wain:format own) 41 | -- 42 | ++ grab 43 | |% :: convert from 44 | ++ mime |=([p=mite q=octs] q.q) 45 | ++ noun @t :: clam from %noun 46 | ++ txt of-wain:format 47 | -- 48 | ++ grad %txt 49 | -- 50 | -------------------------------------------------------------------------------- /desk/sur/docket.hoon: -------------------------------------------------------------------------------- 1 | |% 2 | :: 3 | +$ version 4 | [major=@ud minor=@ud patch=@ud] 5 | :: 6 | +$ glob (map path mime) 7 | :: 8 | +$ url cord 9 | :: $glob-location: How to retrieve a glob 10 | :: 11 | +$ glob-reference 12 | [hash=@uvH location=glob-location] 13 | :: 14 | +$ glob-location 15 | $% [%http =url] 16 | [%ames =ship] 17 | == 18 | :: $href: Where a tile links to 19 | :: 20 | +$ href 21 | $% [%glob base=term =glob-reference] 22 | [%site =path] 23 | == 24 | :: $chad: State of a docket 25 | :: 26 | +$ chad 27 | $~ [%install ~] 28 | $% :: Done 29 | [%glob =glob] 30 | [%site ~] 31 | :: Waiting 32 | [%install ~] 33 | [%suspend glob=(unit glob)] 34 | :: Error 35 | [%hung err=cord] 36 | == 37 | :: 38 | :: $charge: A realized $docket 39 | :: 40 | +$ charge 41 | $: =docket 42 | =chad 43 | == 44 | :: 45 | :: $clause: A key and value, as part of a docket 46 | :: 47 | :: Only used to parse $docket 48 | :: 49 | +$ clause 50 | $% [%title title=@t] 51 | [%info info=@t] 52 | [%color color=@ux] 53 | [%glob-http url=cord hash=@uvH] 54 | [%glob-ames =ship hash=@uvH] 55 | [%image =url] 56 | [%site =path] 57 | [%base base=term] 58 | [%version =version] 59 | [%website website=url] 60 | [%license license=cord] 61 | == 62 | :: 63 | :: $docket: A description of JS bundles for a desk 64 | :: 65 | +$ docket 66 | $: %1 67 | title=@t 68 | info=@t 69 | color=@ux 70 | =href 71 | image=(unit url) 72 | =version 73 | website=url 74 | license=cord 75 | == 76 | :: 77 | +$ charge-update 78 | $% [%initial initial=(map desk charge)] 79 | [%add-charge =desk =charge] 80 | [%del-charge =desk] 81 | == 82 | -- 83 | -------------------------------------------------------------------------------- /desk/sur/plum.hoon: -------------------------------------------------------------------------------- 1 | ^? |% 2 | :: 3 | +$ tile :: XX: ?@(knot (pair styl knot)) 4 | :: 5 | cord 6 | :: 7 | :: A `plum` is the intermediate representation for the pretty-printer. It 8 | :: encodes hoon-shaped data with the least amount of structured needed 9 | :: for formating. 10 | :: 11 | :: A `plum` is either a 12 | :: 13 | :: - `cord`: A simple cord 14 | :: - `[%para *]`: A wrappable paragraph. 15 | :: - `[%tree *]`: A formatted plum tree 16 | :: - `[%sbrk *]`: An indication of a nested subexpression. 17 | :: 18 | :: The formatter will use the tall mode unless: 19 | :: 20 | :: - A plum has only a `wide` style. 21 | :: - The plum is in `%sbrk` form and its subplum (`kid`), when 22 | :: formatted in wide mode, can fit on a single line. 23 | :: 24 | +$ plum 25 | $@ cord 26 | $% [%para prefix=tile lines=(list @t)] 27 | [%tree fmt=plumfmt kids=(list plum)] 28 | [%sbrk kid=plum] 29 | == 30 | :: 31 | :: A `plumfmt` is a description of how to render a `plum`. A `plumfmt` 32 | :: must include a `wide`, a `tall`, or both. 33 | :: 34 | :: A `wide` is a description of how to render a plum in a single 35 | :: line. The nested (`kids`) sub-plums will be interleaved with `delimit` 36 | :: strings, and, if `enclose` is set, then the output will be enclosed 37 | :: with `p.u.enclose` and `q.u.enclose`. 38 | :: 39 | :: For example, to build a plumfmt for string literals, we could write: 40 | :: 41 | :: [wide=[~ '' [~ '"' '"']] tall=~] 42 | :: 43 | :: A `tall` is a description of how to render a plum across multiple 44 | :: lines. The output will be prefixed by `intro`, suffixed by 45 | :: `final.u.indef`, and each subplum prefixed by `sigil.u.indef`. 46 | :: 47 | :: For example, to build a plumfmt for cores, we could write: 48 | :: 49 | :: [wide=~ tall=`['' `['++' '--']]] 50 | :: 51 | +$ plumfmt 52 | $: wide=(unit [delimit=tile enclose=(unit (pair tile tile))]) 53 | tall=(unit [intro=tile indef=(unit [sigil=tile final=tile])]) 54 | == 55 | -- 56 | -------------------------------------------------------------------------------- /desk/ted/weather.hoon: -------------------------------------------------------------------------------- 1 | /- spider, *gato 2 | /+ *strandio 3 | =, strand=strand:spider 4 | =, dejs:format 5 | =/ m (strand ,vase) 6 | |^ ted 7 | +$ geolocation [lat=tape lon=tape name=tape] 8 | ++ ud-to-cord 9 | |= [n=@ud] 10 | ^- cord 11 | (crip ((d-co:co 0) n)) 12 | ++ mine-geocoder-json 13 | |= =json 14 | ^- geolocation 15 | %+ snag 0 16 | %. json 17 | %- ar 18 | %- ot 19 | :~ lat+sa 20 | lon+sa 21 | [%'display_name' sa] 22 | == 23 | ++ geocoder-url 24 | |= [location=tape api-key=tape] 25 | ^- tape 26 | "https://us1.locationiq.com/v1/search?key={api-key}&q={(en-urlt:html location)}&format=json" 27 | ++ weather-decoder 28 | %- ot 29 | :~ :- %'current_weather' 30 | %- ot 31 | :~ temperature+ne 32 | weathercode+ne 33 | == 34 | == 35 | ++ mine-weather-json 36 | |= [=json temperature-unit=tape name=tape] 37 | ^- tape 38 | =/ [temperature=@rd code=@rd] (weather-decoder json) 39 | =/ [temperature-sign=? temperature-value=@ud] 40 | (old:si (need (toi:rd temperature))) 41 | ;: weld 42 | (describe-weather code) ", " 43 | ?: temperature-sign "" "-" 44 | (trip (ud-to-cord temperature-value)) 45 | ?: =(temperature-unit "fahrenheit") "F" "C" 46 | " in " name 47 | == 48 | ++ weather-url 49 | |= [=geolocation temperature-unit=tape] 50 | ^- tape 51 | "https://api.open-meteo.com/v1/forecast?latitude={lat.geolocation}&longitude={lon.geolocation}¤t_weather=true&temperature_unit={temperature-unit}" 52 | ++ describe-weather 53 | |= code=@rd 54 | ^- tape 55 | :: https://open-meteo.com/en/docs 56 | =/ description-list 57 | :~ [.~0 "Clear sky"] 58 | [.~1 "Mainly clear"] 59 | [.~2 "Partly cloudy"] 60 | [.~3 "Overcast"] 61 | [.~45 "Fog"] 62 | [.~48 "Depositing rime fog"] 63 | [.~51 "Light drizzle"] 64 | [.~53 "Moderate drizzle"] 65 | [.~55 "Heavy drizzle"] 66 | [.~56 "Light freezing drizzle"] 67 | [.~57 "Heavy freezing drizzle"] 68 | [.~61 "Slight rain"] 69 | [.~63 "Moderate rain"] 70 | [.~65 "Heavy rain"] 71 | [.~66 "Light freezing rain"] 72 | [.~67 "Heavy freezing rain"] 73 | [.~71 "Slight snow fall"] 74 | [.~73 "Moderate snow fall"] 75 | [.~75 "Heavy snow fall"] 76 | [.~77 "Snow grains"] 77 | [.~80 "Slight rain showers"] 78 | [.~81 "Moderate rain showers"] 79 | [.~82 "Violent rain showers"] 80 | [.~85 "Slight snow showers"] 81 | [.~86 "Heavy snow showers"] 82 | [.~95 "Thunderstorm"] 83 | [.~96 "Thunderstorm"] 84 | [.~99 "Thunderstorm"] 85 | == 86 | =/ descriptions 87 | (~(gas by *(map @rd tape)) description-list) 88 | (fall (~(get by descriptions) code) "Unknown conditions") 89 | ++ ted 90 | ^- thread:spider 91 | |= arg=vase 92 | ^- form:m 93 | =/ m (strand ,vase) 94 | =/ =bird !<(bird arg) 95 | =/ [api-key=tape temperature-unit=tape] !<([tape tape] vase.bird) 96 | ;< geocode=json bind:m (fetch-json (geocoder-url (trip text.bird) api-key)) 97 | =/ =geolocation (mine-geocoder-json geocode) 98 | ;< weather=json bind:m (fetch-json (weather-url geolocation temperature-unit)) 99 | =/ =reply (crip (mine-weather-json weather temperature-unit name.geolocation)) 100 | %- pure:m 101 | !> [reply vase.bird] 102 | -- 103 | -------------------------------------------------------------------------------- /desk/app/gato.hoon: -------------------------------------------------------------------------------- 1 | /- chat, *gato 2 | /+ default-agent, dbug 3 | |% 4 | +$ versioned-state 5 | $% state-0 6 | == 7 | +$ state-0 [%0 =quilt] 8 | +$ card card:agent:gall 9 | ++ chat-subscribe-card 10 | |= =ship 11 | [%pass /chat/updates %agent [ship %chat] %watch /ui] 12 | ++ run-thread-card 13 | |= [call=cord =command =flag:chat text=cord =memo:chat] 14 | ^- card 15 | =/ =bird [text memo flag vase.command] 16 | :* %pass /result/[call]/(scot %p p.flag)/[q.flag] %arvo %k %fard 17 | desk.ted.command name.ted.command %noun 18 | !>(bird) 19 | == 20 | ++ message-card 21 | |= [our=ship =action:chat] 22 | ^- card 23 | [%pass /chat/poke %agent [our %chat] %poke %chat-action !>(action)] 24 | ++ find-slash 25 | |= =memo:chat 26 | ^- [cord cord] 27 | :: find the first raw text segment 28 | =/ first=cord 29 | ?- content.memo 30 | [%notice *] !! 31 | [%story *] 32 | =/ inlines q.p.content.memo 33 | |- 34 | ?~ inlines !! 35 | ?@ i.inlines i.inlines 36 | $(inlines t.inlines) 37 | == 38 | =/ [call=tape text=tape] (scan (trip first) slash-command-rule) 39 | [(crip call) (crip text)] 40 | :: "/mycommand lorem ipsum" to ["mycommand" "lorem ipsum"] 41 | ++ slash-command-rule 42 | ;~ (glue (star ace)) 43 | ;~ pfix 44 | fas 45 | (plus alp) 46 | == 47 | (star next) 48 | == 49 | ++ message 50 | |= [=id:chat =flag:chat =content:chat] 51 | ^- action:chat 52 | :- flag 53 | :- q.id 54 | :- %writs 55 | :- id 56 | :- %add 57 | :- replying=~ 58 | :- author=p.id 59 | :- sent=q.id 60 | content 61 | ++ reply-to-content 62 | |= =reply 63 | ^- content:chat 64 | ?^ reply reply 65 | [%story [~ ~[reply]]] 66 | ++ replace-vase 67 | |= [q=quilt call=cord =vase] 68 | ^- quilt 69 | =/ =command (~(got by q) call) 70 | (~(put by q) call [ted.command vase]) 71 | -- 72 | %- agent:dbug 73 | =| state-0 74 | =* state - 75 | ^- agent:gall 76 | |_ =bowl:gall 77 | +* this . 78 | def ~(. (default-agent this %.n) bowl) 79 | ++ on-init 80 | ^- (quip card _this) 81 | :_ this 82 | ~[(chat-subscribe-card our.bowl)] 83 | ++ on-save 84 | ^- vase 85 | !> state 86 | ++ on-load 87 | |= old-state=vase 88 | ^- (quip card _this) 89 | `this(state !<(versioned-state old-state)) 90 | ++ on-poke 91 | |= [=mark =vase] 92 | ^- (quip card _this) 93 | ?+ mark !! 94 | %add 95 | =/ [call=cord =command] !<([cord command] vase) 96 | `this(quilt (~(put by quilt) call command)) 97 | :: 98 | :: %add and %set are aliases for each other 99 | %set 100 | =/ [call=cord =command] !<([cord command] vase) 101 | `this(quilt (~(put by quilt) call command)) 102 | :: 103 | %remove 104 | =/ call=cord !<(cord vase) 105 | `this(quilt (~(del by quilt) call)) 106 | == 107 | ++ on-watch on-watch:def 108 | ++ on-leave on-leave:def 109 | ++ on-peek on-peek:def 110 | ++ on-agent 111 | |= [=wire =sign:agent:gall] 112 | ^- (quip card _this) 113 | ?+ wire (on-agent:def wire sign) 114 | [%chat %updates ~] 115 | ?+ -.sign (on-agent:def wire sign) 116 | %watch-ack `this 117 | %kick 118 | :_ this 119 | ~[(chat-subscribe-card our.bowl)] 120 | :: 121 | %fact 122 | ?+ p.cage.sign `this 123 | %chat-action-0 124 | =/ =action:chat !<(action:chat q.cage.sign) 125 | =/ =flag:chat p.action 126 | =/ =diff:chat q.q.action 127 | ?+ -.diff `this 128 | %writs 129 | =/ =delta:writs:chat q.p.diff 130 | ?+ -.delta `this 131 | %add 132 | =/ =memo:chat p.delta 133 | :: ?: =(our.bowl author.memo) `this 134 | =/ [call=cord text=cord] (find-slash memo) 135 | =/ =command (~(got by quilt) call) 136 | :_ this 137 | ~[(run-thread-card call command flag text memo)] 138 | == 139 | == 140 | == 141 | == 142 | == 143 | ++ on-arvo 144 | |= [=wire sign=sign-arvo] 145 | ^- (quip card _this) 146 | ?+ wire (on-arvo:def wire sign) 147 | [%result cord cord cord *] 148 | =/ [%result call=cord ship-cord=cord chat=cord *] wire 149 | =/ =ship (slav %p ship-cord) 150 | ?+ sign (on-arvo:def wire sign) 151 | [%khan %arow %.y %noun *] 152 | =/ [%khan %arow %.y %noun result=vase] sign 153 | =/ =tuna !<(tuna result) 154 | :_ this(quilt (replace-vase quilt call vase.tuna)) 155 | :~ %+ message-card our.bowl 156 | (message [our.bowl now.bowl] [ship chat] (reply-to-content reply.tuna)) 157 | == 158 | == 159 | == 160 | ++ on-fail on-fail:def 161 | -- 162 | -------------------------------------------------------------------------------- /desk/lib/docket.hoon: -------------------------------------------------------------------------------- 1 | /- *docket 2 | |% 3 | :: 4 | ++ mime 5 | |% 6 | +$ draft 7 | $: title=(unit @t) 8 | info=(unit @t) 9 | color=(unit @ux) 10 | glob-http=(unit [=url hash=@uvH]) 11 | glob-ames=(unit [=ship hash=@uvH]) 12 | base=(unit term) 13 | site=(unit path) 14 | image=(unit url) 15 | version=(unit version) 16 | website=(unit url) 17 | license=(unit cord) 18 | == 19 | :: 20 | ++ finalize 21 | |= =draft 22 | ^- (unit docket) 23 | ?~ title.draft ~ 24 | ?~ info.draft ~ 25 | ?~ color.draft ~ 26 | ?~ version.draft ~ 27 | ?~ website.draft ~ 28 | ?~ license.draft ~ 29 | =/ href=(unit href) 30 | ?^ site.draft `[%site u.site.draft] 31 | ?~ base.draft ~ 32 | ?^ glob-http.draft 33 | `[%glob u.base hash.u.glob-http %http url.u.glob-http]:draft 34 | ?~ glob-ames.draft 35 | ~ 36 | `[%glob u.base hash.u.glob-ames %ames ship.u.glob-ames]:draft 37 | ?~ href ~ 38 | =, draft 39 | :- ~ 40 | :* %1 41 | u.title 42 | u.info 43 | u.color 44 | u.href 45 | image 46 | u.version 47 | u.website 48 | u.license 49 | == 50 | :: 51 | ++ from-clauses 52 | =| =draft 53 | |= cls=(list clause) 54 | ^- (unit docket) 55 | =* loop $ 56 | ?~ cls (finalize draft) 57 | =* clause i.cls 58 | =. draft 59 | ?- -.clause 60 | %title draft(title `title.clause) 61 | %info draft(info `info.clause) 62 | %color draft(color `color.clause) 63 | %glob-http draft(glob-http `[url hash]:clause) 64 | %glob-ames draft(glob-ames `[ship hash]:clause) 65 | %base draft(base `base.clause) 66 | %site draft(site `path.clause) 67 | %image draft(image `url.clause) 68 | %version draft(version `version.clause) 69 | %website draft(website `website.clause) 70 | %license draft(license `license.clause) 71 | == 72 | loop(cls t.cls) 73 | :: 74 | ++ to-clauses 75 | |= d=docket 76 | ^- (list clause) 77 | %- zing 78 | :~ :~ title+title.d 79 | info+info.d 80 | color+color.d 81 | version+version.d 82 | website+website.d 83 | license+license.d 84 | == 85 | ?~ image.d ~ ~[image+u.image.d] 86 | ?: ?=(%site -.href.d) ~[site+path.href.d] 87 | =/ ref=glob-reference glob-reference.href.d 88 | :~ base+base.href.d 89 | ?- -.location.ref 90 | %http [%glob-http url.location.ref hash.ref] 91 | %ames [%glob-ames ship.location.ref hash.ref] 92 | == == == 93 | :: 94 | ++ spit-clause 95 | |= =clause 96 | ^- tape 97 | %+ weld " {(trip -.clause)}+" 98 | ?+ -.clause "'{(trip +.clause)}'" 99 | %color (scow %ux color.clause) 100 | %site (spud path.clause) 101 | :: 102 | %glob-http 103 | "['{(trip url.clause)}' {(scow %uv hash.clause)}]" 104 | :: 105 | %glob-ames 106 | "[{(scow %p ship.clause)} {(scow %uv hash.clause)}]" 107 | :: 108 | %version 109 | =, version.clause 110 | "[{(scow %ud major)} {(scow %ud minor)} {(scow %ud patch)}]" 111 | == 112 | :: 113 | ++ spit-docket 114 | |= dock=docket 115 | ^- tape 116 | ;: welp 117 | ":~\0a" 118 | `tape`(zing (join "\0a" (turn (to-clauses dock) spit-clause))) 119 | "\0a==" 120 | == 121 | -- 122 | :: 123 | ++ enjs 124 | =, enjs:format 125 | |% 126 | :: 127 | ++ charge-update 128 | |= u=^charge-update 129 | ^- json 130 | %+ frond -.u 131 | ^- json 132 | ?- -.u 133 | %del-charge s+desk.u 134 | :: 135 | %initial 136 | %- pairs 137 | %+ turn ~(tap by initial.u) 138 | |=([=desk c=^charge] [desk (charge c)]) 139 | :: 140 | %add-charge 141 | %- pairs 142 | :~ desk+s+desk.u 143 | charge+(charge charge.u) 144 | == 145 | == 146 | :: 147 | ++ num 148 | |= a=@u 149 | ^- ^tape 150 | =/ p=json (numb a) 151 | ?> ?=(%n -.p) 152 | (trip p.p) 153 | :: 154 | ++ version 155 | |= v=^version 156 | ^- json 157 | :- %s 158 | %- crip 159 | "{(num major.v)}.{(num minor.v)}.{(num patch.v)}" 160 | :: 161 | ++ merge 162 | |= [a=json b=json] 163 | ^- json 164 | ?> &(?=(%o -.a) ?=(%o -.b)) 165 | [%o (~(uni by p.a) p.b)] 166 | :: 167 | ++ href 168 | |= h=^href 169 | %+ frond -.h 170 | ?- -.h 171 | %site s+(spat path.h) 172 | %glob 173 | %- pairs 174 | :~ base+s+base.h 175 | glob-reference+(glob-reference glob-reference.h) 176 | == 177 | == 178 | :: 179 | ++ glob-reference 180 | |= ref=^glob-reference 181 | %- pairs 182 | :~ hash+s+(scot %uv hash.ref) 183 | location+(glob-location location.ref) 184 | == 185 | :: 186 | ++ glob-location 187 | |= loc=^glob-location 188 | ^- json 189 | %+ frond -.loc 190 | ?- -.loc 191 | %http s+url.loc 192 | %ames s+(scot %p ship.loc) 193 | == 194 | :: 195 | ++ charge 196 | |= c=^charge 197 | %+ merge (docket docket.c) 198 | %- pairs 199 | :~ chad+(chad chad.c) 200 | == 201 | :: 202 | ++ docket 203 | |= d=^docket 204 | ^- json 205 | %- pairs 206 | :~ title+s+title.d 207 | info+s+info.d 208 | color+s+(scot %ux color.d) 209 | href+(href href.d) 210 | image+?~(image.d ~ s+u.image.d) 211 | version+(version version.d) 212 | license+s+license.d 213 | website+s+website.d 214 | == 215 | :: 216 | ++ chad 217 | |= c=^chad 218 | %+ frond -.c 219 | ?+ -.c ~ 220 | %hung s+err.c 221 | == 222 | -- 223 | -- 224 | -------------------------------------------------------------------------------- /desk/sur/xray.hoon: -------------------------------------------------------------------------------- 1 | 2 | :: 3 | :: These are the public types for the `xray` library. Analysing a type 4 | :: yields an `ximage`, and everything else here is just some structure 5 | :: within that. 6 | :: 7 | :: `ximage`s can be printed as specs (hoon syntax for types), and can 8 | :: be used to pretty-print typed data. 9 | :: 10 | ^? |% 11 | :: 12 | :: An `xtable` is a graph of types referenced by the top-level type, 13 | :: and the `root` `key` points to the node which corresponds to the 14 | :: type under analysis. 15 | :: 16 | +$ ximage [root=xkey =xtable] 17 | :: 18 | :: A `xkey` is just an identifier for a node in the xray graph. 19 | :: 20 | +$ xkey @ 21 | :: 22 | :: An `xtable` is the xray graph itself. It contains one node for for 23 | :: the type that was analyzed and one node for every type referenced 24 | :: within that type. 25 | :: 26 | :: The `next` field is the the next available xkey (used when inserting 27 | :: new xrays), `xrays` maps keys to graph nodes and `type-map` gives 28 | :: the xkey corresponding to a type. 29 | :: 30 | :: The `type-map` is basically just the reverse of the `xrays` map. It 31 | :: doesn't contain any new information, but is needed for performance 32 | :: reasons. 33 | :: 34 | +$ xtable [next=xkey xrays=(map xkey xray) =type=(map type xkey)] 35 | :: 36 | :: An `xray` is a node in the `ximage` graph. It contains everything 37 | :: we know about a certain `type`. `key` is its identifier in the graph, 38 | :: `type` is the type that it's an xray of, and `xdat` is the basic 39 | :: information we derived about the type. The basic references to other 40 | :: nodes are inside the `xdat` structure, though some of the other 41 | :: fields may contain references as well. 42 | :: 43 | :: - `xshape` is some more information about the xshape of data within 44 | :: a cell. 45 | :: - `xrole` expands on `xshape`, adding further information about the 46 | :: xrole that a node has within a fork. 47 | :: - `pats` is used for printing data: we want to know if this type 48 | :: can be printed as a list, as json, as a tape literal, etc. 49 | :: - `recipes` contains information about how a type was 50 | :: constructed. It's used to get much nicer output when printing types. 51 | :: - `studs` contains "standards names". I actually don't know what this is. 52 | :: - `helps` contains all the documentation about a type. 53 | :: - `loop` indicates whether or not a node references itself. The list 54 | :: type is cyclical, for example. This is used when printing an 55 | :: `ximage`. 56 | :: 57 | +$ xray 58 | $: =xkey 59 | =type 60 | xdat=(unit xdat) 61 | xrole=(unit xrole) 62 | pats=(unit xpat) 63 | studs=(set stud) 64 | recipes=(set recipe) 65 | helps=(set help) 66 | xshape=(unit xshape) 67 | loop=(unit ?) 68 | == 69 | :: 70 | :: - `%void` -- impossible to create. 71 | :: - `%noun` -- could be any noun. 72 | :: - `%atom` -- An atom of some aura, possibly constant 73 | :: - `%cell` -- A cell with a head and a tail. 74 | :: - `%core` -- A core, its garb, its context type, and the types of 75 | :: each of its arms. 76 | :: - `%face` -- A face on another type. 77 | :: - `%fork` -- Could be one or more other types. 78 | :: - `%pntr` -- This is an internal hack, it should never survive 79 | :: analysis; ignore. 80 | :: 81 | +$ xdat 82 | $@ ?(%noun %void) 83 | $% [%atom =aura constant=(unit @)] 84 | [%cell head=xkey tail=xkey] 85 | [%core =garb xray=xkey batt=xbat] 86 | [%face face=$@(term tune) xray=xkey] 87 | [%fork =(set xkey)] 88 | [%pntr xray=xkey] 89 | == 90 | :: 91 | :: The basic xshape of a type: 92 | :: 93 | :: - `%void` -- impossible to create. 94 | :: - `%noun` -- could be any noun. 95 | :: - `%atom` -- always some type of atom; never a cell 96 | :: - `%cell` -- always some type of cell; never an atom. 97 | :: - `%junc` -- is a fork of a cell type and an atom type. 98 | :: 99 | +$ xshape ?(%void %noun %atom %cell %junc) 100 | :: 101 | :: A `xrole` is the of a type, including a more refined understanding 102 | :: of what xrole it plays within a fork. 103 | :: 104 | :: Nodes referenced within a `xrole` often do not actually exist in the 105 | :: original type, since we need to reorganize forks in order to make 106 | :: them more coherent. 107 | :: 108 | :: - `%void` -- impossible to create. 109 | :: - `%noun` -- could be any noun. 110 | :: - `%atom` -- always some type of atom; never a cell 111 | :: - `%constant` -- a cell type whose head is a constant atom. 112 | :: - `%tall` -- a cell type whose head is an atom. 113 | :: - `%wide` -- a cell type whose head is also a cell 114 | :: - `%instance` -- a cell type whose head is a constant atom. 115 | :: - `%option` -- a union of types which are all constant atoms. 116 | :: - `%union` -- a union of types which are all instances (cells whose 117 | :: head is a constant atom). 118 | :: - `%junction` -- a union of an atom type and a cell type. 119 | :: - `%conjunction` -- a union of two cell types, one of them %wide 120 | :: and the other %tall. 121 | :: - `%misjunction` -- any other union type. There's no efficient way 122 | :: to tell which branch to take when analyzing a fork which is a 123 | :: %misjunction, and the type is probably improperly constructed. 124 | :: 125 | +$ xrole 126 | $@ $? %void %noun %atom %tall %wide == 127 | $% [%constant =atom] 128 | [%instance =atom] 129 | [%option =(map atom xkey)] 130 | [%union =(map atom xkey)] 131 | [%junction flat=xkey deep=xkey] 132 | [%conjunction wide=xkey tall=xkey] 133 | [%misjunction one=xkey two=xkey] 134 | == 135 | :: 136 | :: This is just a utility type, it encodes the "battery" structure 137 | :: within a core. 138 | :: 139 | :: It's a map from chapter names to the documentation and arms within 140 | :: that chapter. 141 | :: 142 | +$ xbat (map term (pair what (map term xkey))) 143 | :: 144 | :: A recipe tells us how a type was constructed. 145 | :: 146 | :: - `%direct` is a simple type like `term`, or `xray`. 147 | :: - `%synthetic` is a constructed type, like `(list @)`. 148 | :: 149 | +$ recipe 150 | $% [%direct =term] 151 | [%synthetic =term =(list xkey)] 152 | == 153 | :: 154 | :: A `xpat` is high-level information about the shape of a type. This 155 | :: is used for printing data. 156 | :: 157 | :: This is fairly heuristic. [%a %b %c ~] is recognized as a `path`, 158 | :: `[3 ~[4 5 6]]` is recognized as a list, etc. 159 | :: 160 | :: Most of the xpats have names that make their purpose obvious: 161 | :: for example, the %tape xpat means that data of type type can be 162 | :: printed as if it had the `tape` type. However, `%gear` and `%gate` 163 | :: might not be entirely obvious. 164 | :: 165 | :: - The %gear xpat is any core with a cell subject. 166 | :: - The %gate xpat is a core that looks like a gate. 167 | :: 168 | +$ xpat 169 | $@ ?(%hoon %manx %json %nock %path %plum %skin %spec %tape %tour %type %vase) 170 | $% [%gate sample=xkey product=xkey] 171 | [%gear sample=xkey context=xkey batt=xbat] 172 | [%list item=xkey] 173 | [%tree item=xkey] 174 | [%unit item=xkey] 175 | == 176 | -- 177 | -------------------------------------------------------------------------------- /desk/mar/txt.hoon: -------------------------------------------------------------------------------- 1 | :: 2 | :::: /hoon/txt/mar 3 | :: 4 | /? 310 5 | :: 6 | =, clay 7 | =, differ 8 | =, format 9 | =, mimes:html 10 | |_ txt=wain 11 | :: 12 | ++ grab :: convert from 13 | |% 14 | ++ mime |=((pair mite octs) (to-wain q.q)) 15 | ++ noun wain :: clam from %noun 16 | -- 17 | ++ grow 18 | => v=. 19 | |% 20 | ++ mime => v [/text/plain (as-octs (of-wain txt))] 21 | ++ elem => v ;pre: {(trip (of-wain txt))} 22 | -- 23 | ++ grad 24 | |% 25 | ++ form %txt-diff 26 | ++ diff 27 | |= tyt=wain 28 | ^- (urge cord) 29 | (lusk txt tyt (loss txt tyt)) 30 | :: 31 | ++ pact 32 | |= dif=(urge cord) 33 | ~| [%pacting dif] 34 | ^- wain 35 | (lurk txt dif) 36 | :: 37 | ++ join 38 | |= [ali=(urge cord) bob=(urge cord)] 39 | ^- (unit (urge cord)) 40 | |^ 41 | =. ali (clean ali) 42 | =. bob (clean bob) 43 | |- ^- (unit (urge cord)) 44 | ?~ ali `bob 45 | ?~ bob `ali 46 | ?- -.i.ali 47 | %& 48 | ?- -.i.bob 49 | %& 50 | ?: =(p.i.ali p.i.bob) 51 | %+ bind $(ali t.ali, bob t.bob) 52 | |=(cud=(urge cord) [i.ali cud]) 53 | ?: (gth p.i.ali p.i.bob) 54 | %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob) 55 | |=(cud=(urge cord) [i.bob cud]) 56 | %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali)) 57 | |=(cud=(urge cord) [i.ali cud]) 58 | :: 59 | %| 60 | ?: =(p.i.ali (lent p.i.bob)) 61 | %+ bind $(ali t.ali, bob t.bob) 62 | |=(cud=(urge cord) [i.bob cud]) 63 | ?: (gth p.i.ali (lent p.i.bob)) 64 | %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob) 65 | |=(cud=(urge cord) [i.bob cud]) 66 | ~ 67 | == 68 | :: 69 | %| 70 | ?- -.i.bob 71 | %| 72 | ?. =(i.ali i.bob) 73 | ~ 74 | %+ bind $(ali t.ali, bob t.bob) 75 | |=(cud=(urge cord) [i.ali cud]) 76 | :: 77 | %& 78 | ?: =(p.i.bob (lent p.i.ali)) 79 | %+ bind $(ali t.ali, bob t.bob) 80 | |=(cud=(urge cord) [i.ali cud]) 81 | ?: (gth p.i.bob (lent p.i.ali)) 82 | %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali))) 83 | |=(cud=(urge cord) [i.ali cud]) 84 | ~ 85 | == 86 | == 87 | ++ clean :: clean 88 | |= wig=(urge cord) 89 | ^- (urge cord) 90 | ?~ wig ~ 91 | ?~ t.wig wig 92 | ?: ?=(%& -.i.wig) 93 | ?: ?=(%& -.i.t.wig) 94 | $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) 95 | [i.wig $(wig t.wig)] 96 | ?: ?=(%| -.i.t.wig) 97 | $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) 98 | [i.wig $(wig t.wig)] 99 | -- 100 | :: 101 | ++ mash 102 | |= $: [als=ship ald=desk ali=(urge cord)] 103 | [bos=ship bod=desk bob=(urge cord)] 104 | == 105 | ^- (urge cord) 106 | |^ 107 | =. ali (clean ali) 108 | =. bob (clean bob) 109 | |- ^- (urge cord) 110 | ?~ ali bob 111 | ?~ bob ali 112 | ?- -.i.ali 113 | %& 114 | ?- -.i.bob 115 | %& 116 | ?: =(p.i.ali p.i.bob) 117 | [i.ali $(ali t.ali, bob t.bob)] 118 | ?: (gth p.i.ali p.i.bob) 119 | [i.bob $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)] 120 | [i.ali $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))] 121 | :: 122 | %| 123 | ?: =(p.i.ali (lent p.i.bob)) 124 | [i.bob $(ali t.ali, bob t.bob)] 125 | ?: (gth p.i.ali (lent p.i.bob)) 126 | [i.bob $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)] 127 | =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] 128 | (resolve ali bob) 129 | [fic $(ali ali, bob bob)] 130 | :: ~ :: here, alice is good for a while, but not for the whole 131 | == :: length of bob's changes 132 | :: 133 | %| 134 | ?- -.i.bob 135 | %| 136 | =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] 137 | (resolve ali bob) 138 | [fic $(ali ali, bob bob)] 139 | :: 140 | %& 141 | ?: =(p.i.bob (lent p.i.ali)) 142 | [i.ali $(ali t.ali, bob t.bob)] 143 | ?: (gth p.i.bob (lent p.i.ali)) 144 | [i.ali $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))] 145 | =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] 146 | (resolve ali bob) 147 | [fic $(ali ali, bob bob)] 148 | == 149 | == 150 | :: 151 | ++ annotate :: annotate conflict 152 | |= $: ali=(list @t) 153 | bob=(list @t) 154 | bas=(list @t) 155 | == 156 | ^- (list @t) 157 | %- zing 158 | ^- (list (list @t)) 159 | %- flop 160 | ^- (list (list @t)) 161 | :- :_ ~ 162 | %^ cat 3 '<<<<<<<<<<<<' 163 | %^ cat 3 ' ' 164 | %^ cat 3 `@t`(scot %p bos) 165 | %^ cat 3 '/' 166 | bod 167 | 168 | :- bob 169 | :- ~['------------'] 170 | :- bas 171 | :- ~['++++++++++++'] 172 | :- ali 173 | :- :_ ~ 174 | %^ cat 3 '>>>>>>>>>>>>' 175 | %^ cat 3 ' ' 176 | %^ cat 3 `@t`(scot %p als) 177 | %^ cat 3 '/' 178 | ald 179 | ~ 180 | :: 181 | ++ clean :: clean 182 | |= wig=(urge cord) 183 | ^- (urge cord) 184 | ?~ wig ~ 185 | ?~ t.wig wig 186 | ?: ?=(%& -.i.wig) 187 | ?: ?=(%& -.i.t.wig) 188 | $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) 189 | [i.wig $(wig t.wig)] 190 | ?: ?=(%| -.i.t.wig) 191 | $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) 192 | [i.wig $(wig t.wig)] 193 | :: 194 | ++ resolve 195 | |= [ali=(urge cord) bob=(urge cord)] 196 | ^- [fic=[%| p=(list cord) q=(list cord)] ali=(urge cord) bob=(urge cord)] 197 | =- [[%| bac (annotate alc boc bac)] ali bob] 198 | |- ^- $: $: bac=(list cord) 199 | alc=(list cord) 200 | boc=(list cord) 201 | == 202 | ali=(urge cord) 203 | bob=(urge cord) 204 | == 205 | ?~ ali [[~ ~ ~] ali bob] 206 | ?~ bob [[~ ~ ~] ali bob] 207 | ?- -.i.ali 208 | %& 209 | ?- -.i.bob 210 | %& [[~ ~ ~] ali bob] :: no conflict 211 | %| 212 | =+ lob=(lent p.i.bob) 213 | ?: =(lob p.i.ali) 214 | [[p.i.bob p.i.bob q.i.bob] t.ali t.bob] 215 | ?: (lth lob p.i.ali) 216 | [[p.i.bob p.i.bob q.i.bob] [[%& (sub p.i.ali lob)] t.ali] t.bob] 217 | =+ wat=(scag (sub lob p.i.ali) p.i.bob) 218 | =+ ^= res 219 | %= $ 220 | ali t.ali 221 | bob [[%| (scag (sub lob p.i.ali) p.i.bob) ~] t.bob] 222 | == 223 | :* :* (welp bac.res wat) 224 | (welp alc.res wat) 225 | (welp boc.res q.i.bob) 226 | == 227 | ali.res 228 | bob.res 229 | == 230 | == 231 | :: 232 | %| 233 | ?- -.i.bob 234 | %& 235 | =+ loa=(lent p.i.ali) 236 | ?: =(loa p.i.bob) 237 | [[p.i.ali q.i.ali p.i.ali] t.ali t.bob] 238 | ?: (lth loa p.i.bob) 239 | [[p.i.ali q.i.ali p.i.ali] t.ali [[%& (sub p.i.bob loa)] t.bob]] 240 | =+ wat=(slag (sub loa p.i.bob) p.i.ali) 241 | =+ ^= res 242 | %= $ 243 | ali [[%| (scag (sub loa p.i.bob) p.i.ali) ~] t.ali] 244 | bob t.bob 245 | == 246 | :* :* (welp bac.res wat) 247 | (welp alc.res q.i.ali) 248 | (welp boc.res wat) 249 | == 250 | ali.res 251 | bob.res 252 | == 253 | :: 254 | %| 255 | =+ loa=(lent p.i.ali) 256 | =+ lob=(lent p.i.bob) 257 | ?: =(loa lob) 258 | [[p.i.ali q.i.ali q.i.bob] t.ali t.bob] 259 | =+ ^= res 260 | ?: (gth loa lob) 261 | $(ali [[%| (scag (sub loa lob) p.i.ali) ~] t.ali], bob t.bob) 262 | ~& [%scagging loa=loa pibob=p.i.bob slag=(scag loa p.i.bob)] 263 | $(ali t.ali, bob [[%| (scag (sub lob loa) p.i.bob) ~] t.bob]) 264 | :* :* (welp bac.res ?:((gth loa lob) p.i.bob p.i.ali)) 265 | (welp alc.res q.i.ali) 266 | (welp boc.res q.i.bob) 267 | == 268 | ali.res 269 | bob.res 270 | == 271 | == 272 | == 273 | -- 274 | -- 275 | -- 276 | --------------------------------------------------------------------------------