diff --git a/app/dojo.hoon b/app/dojo.hoon index 68c76af9d8..102b9eb119 100644 --- a/app/dojo.hoon +++ b/app/dojo.hoon @@ -18,7 +18,7 @@ $: say/sole-share :: command-line state dir/beam :: active path poy/(unit dojo-project) :: working - {lib/(list hoof) arc/(list hoof)} :: lib+sur + {lib/(list hoof) sur/(list hoof)} :: lib+sur var/(map term cage) :: variable state old/(set term) :: used TLVs buf/tape :: multiline buffer @@ -154,7 +154,7 @@ :: ;~ pfix fas ;~ pose - (dp-variable (cold %arc hep) ;~(pfix gap dp-hooves)) + (dp-variable (cold %sur hep) ;~(pfix gap dp-hooves)) (dp-variable (cold %lib lus) ;~(pfix gap dp-hooves)) == == @@ -429,7 +429,7 @@ ?+ p.mad . $?($eny $now $our) !! $lib .(lib ~) - $arc .(arc ~) + $sur .(sur ~) $dir .(dir [[our.hid %home ud+0] /]) == =+ cay=(~(got by rez) p.q.mad) @@ -443,7 +443,7 @@ $now ~|(%time-is-immutable !!) $our ~|(%self-is-immutable !!) $lib .(lib ((dy-cast (list hoof) !>(*(list hoof))) q.cay)) - $arc .(arc ((dy-cast (list hoof) !>(*(list hoof))) q.cay)) + $sur .(sur ((dy-cast (list hoof) !>(*(list hoof))) q.cay)) $dir =+ ^= pax ^- path =+ pax=((dy-cast path !>(*path)) q.cay) ?: ?=($~ pax) ~[(scot %p our.hid) %home '0'] @@ -484,7 +484,7 @@ $http ?> ?=($mime p.cay) =+ mim=;;(mime q.q.cay) - =+ maf=(~(add ja *math) %content-span (moon p.mim)) + =+ maf=(~(add ja *math) %content-type (moon p.mim)) (dy-eyre /show q.p.mad [r.p.mad p.p.mad maf ~ q.mim]) :: $show @@ -757,7 +757,7 @@ =- ?~(too - [%cast u.too -]) :+ %ride gen :- [%$ dy-twig-head] - [%plan he-beam blob+** [zuse arc lib ~ ~]] + [%plan he-beam blob+** [zuse sur lib ~ ~]] :: ++ dy-step :: advance project |= nex/@ud diff --git a/app/gmail.hoon b/app/gmail.hoon deleted file mode 100644 index 877ccc777e..0000000000 --- a/app/gmail.hoon +++ /dev/null @@ -1,282 +0,0 @@ -:: Three ways we interactg with this app -:: 1. .^(%gx /=gh=/endpoint) -:: 2. [%peer [our %gh] /endpoint] -:: 3. :gh &gh-poke %post /gists json-data - - -:: This is a driver for the Github API v3. -:: -:: You can interact with this in a few different ways: -:: -:: - .^(%gx /=gh=/read{/endpoint}) or subscribe to -:: /scry/x/read{/endpoint} for authenticated reads. -:: -:: - subscribe to /scry/x/listen/{owner}/{repo}/{events...} -:: for webhook-powered event notifications. For event list, -:: see https://developer.github.com/webhooks/. -:: -:: See the%github app for example usage. -:: -/? 314 -/- rfc, gmail-label, gmail-message -/+ http -:::: -/= rfctext /: /%/rfc /txt/ -:: -// /%/split -::/- gmail -:: /ape/gh/split.hoon defines ++split, which splits a request -:: at the end of the longest possible endpoint. -:: - -=> |% :: => only used for indentation - ++ move (pair bone card) - ++ subscription-result - $% {$arch arch} - {$json json} - {$null $~} - {$inbox (list {message-id/@t thread-id/@t})} - {$message from/@t subject/@t} - == - ++ card - $% {$diff subscription-result} - {$hiss wire {$~ $~} $httr {$hiss hiss}} - == - ++ easy-ot |*({key/@t parser/fist:jo} =+(jo (ot [key parser] ~))) - ++ ofis-google :: XX broken - =- |=(a/cord (rash a fel)) - =< fel=(cook |~(a/@ `@t`(swap 3 a)) (bass 64 .)) - =- (cook welp ;~(plug (plus siw) (stun 0^2 (cold %0 tis)))) - ^= siw - ;~ pose - (cook |=(a/@ (sub a 'A')) (shim 'A' 'Z')) - (cook |=(a/@ (sub a 'G')) (shim 'a' 'z')) - (cook |=(a/@ (add a 4)) (shim '0' '9')) - (cold 62 (just '-')) - (cold 63 (just '_')) - == - -- -:: -|_ $: hid/bowl count/@ - web-hooks/(map @t {id/@t listeners/(set bone)}) - received-ids/(list @t) - == - -:: We can't actually give the response to pretty much anything -:: without blocking, so we just block unconditionally. -:: -++ prep ~& 'prep' _`. :: -:: -++ peek - |= {ren/@tas pax/path} - ^- (unit (unit (pair mark *))) - ~ -:: -++ peer-scry - |= pax/path - ^- {(list move) _+>.$} - ?> ?=({care ^} pax) :: assert %u - => (help i.pax i.t.pax t.t.pax) - => scry - %= make-move - count +(count) - == -:: -++ poke-gmail-req - |= $: method/meth endpoint/path quy/quay - mes/message:rfc - :: label-req:gmail-label - == - ^- {(list move) _+>.$} - ?> ?=(valid-get-endpoint endpoint) - :_ +>.$ :_ ~ - ^- move - :* ost.hid %hiss /poke/[method] `~ %httr %hiss - ^- purl - :+ [& ~ [%& /com/googleapis/www]] - [~ gmail+v1+users+me+`valid-get-endpoint`endpoint] - `quay`[[%alt %json] ~] - :: - :+ method `math`(malt ~[content-type+['application/json']~]) - =+ hoon-json-object=(joba %raw s+(message-to-rfc822:rfc mes)) - =+ request-body=(tact (pojo hoon-json-object)) - (some request-body) - ::(some (pojo label-req-to-json:gmail-label label-req:gmail-label ~)) XX - == -:: -:: HTTP response. We make sure the response is good, then -:: produce the result (as JSON) to whoever sent the request. -:: - -++ sigh-httr - |= {wir/wire res/httr} - ^- {(list move) _+>.$} - :: ~& wir+wir - ?. ?=({care @ @ @ *} wir) - :: pokes don't return anything - ~& poke+res - [~ +>.$] - =+ arg=(path (cue (slav %uv i.t.t.wir))) - :: ~& ittwir+i.t.t.wir - :_ +>.$ :_ ~ - :+ ost.hid %diff - ?+ i.wir null+~ - $x - ?~ r.res - json+(jobe err+s+%empty-response code+(jone p.res) ~) - =+ jon=(rush q.u.r.res apex:poja) - ?~ jon - json+(jobe err+s+%bad-json code+(jone p.res) body+s+q.u.r.res ~) - ?. =(2 (div p.res 100)) - json+(jobe err+s+%request-rejected code+(jone p.res) msg+u.jon ~) - :: - :: Once we know we have good data, we drill into the JSON - :: to find the specific piece of data referred to by 'arg' - :: - |- ^- subscription-result - ?~ arg - =+ switch=t.t.t.t.wir - ?+ switch [%json `json`u.jon] - {$messages $~} - =+ new-mezes=((ot messages+(ar (ot id+so 'threadId'^so ~)) ~):jo u.jon) - ::%+ turn new-mezes - ::|= id - ::?< ?=($~ new-mezes) - ::=. received-ids [new-mezes received-ids] - ::~& received-ids - ::=. received - [%inbox (need new-mezes)] - :: - {$messages @t $~} - :: - :: =+ body-parser==+(jo (ot body+(ot data+(cu ofis-google so) ~) ~)) :: (ok /body/data so):jo - :: ~& %.(u.jon (om (om |=(a/json (some -.a))):jo)) - :: ~& %.(u.jon (ot headers+(cu milt (ar (ot name+so value+so ~))) ~)) - =+ ^- $: headers/{from/@t subject/@t} - ::body-text/wain - == - ~| u.jon - =- (need (reparse u.jon)) - ^= reparse - =+ jo - =+ ^= from-and-subject - |= a/(map @t @t) ^- {@t @t} - [(~(got by a) 'From') (~(got by a) 'Subject')] - =+ ^= text-body - |= a/(list {@t @t}) ^- wain - %- lore - %- ofis-google - (~(got by (~(gas by *(map @t @t)) a)) 'text/plain') - %+ easy-ot %payload - %- ot :~ - headers+(cu from-and-subject (cu ~(gas by *(map @t @t)) (ar (ot name+so value+so ~)))) - :: parts+(cu text-body (ar (ot 'mimeType'^so body+(ot data+so ~) ~))) - == - :: =+ parsed-headers==+(jo ((ot payload+(easy-ot 'headers' (ar some)) ~) u.jon)) :: - :: =+ parsed-message==+(jo ((ot payload+(easy-ot 'parts' (ar body-parser)) ~) u.jon)) :: - ::~& [headers body-text] - ::=+ body==+(jo ((ot body+(easy-ot 'body' (easy-ot 'data' so))) parsed-message)) - [%message headers] - == - - =+ dir=((om:jo some) u.jon) - ?~ dir json+(jobe err+s+%no-children ~) - =+ new-jon=(~(get by u.dir) i.arg) - `subscription-result`$(arg t.arg, u.jon ?~(new-jon ~ u.new-jon)) - :: redo with next argument - :: - $y - ?~ r.res - ~& [err+s+%empty-response code+(jone p.res)] - arch+*arch - =+ jon=(rush q.u.r.res apex:poja) - ?~ jon - ~& [err+s+%bad-json code+(jone p.res) body+s+q.u.r.res] - arch+*arch - ?. =(2 (div p.res 100)) - ~& [err+s+%request-rejected code+(jone p.res) msg+u.jon] - arch+*arch - :: - :: Once we know we have good data, we drill into the JSON - :: to find the specific piece of data referred to by 'arg' - :: - |- ^- subscription-result - =+ dir=((om:jo some) u.jon) - ?~ dir - [%arch `(shax (jam u.jon)) ~] - ?~ arg - [%arch `(shax (jam u.jon)) (~(run by u.dir) $~)] - =+ new-jon=(~(get by u.dir) i.arg) - $(arg t.arg, u.jon ?~(new-jon ~ u.new-jon)) - == - -++ sigh - |= a/* - ~& a+a - :_ +>.$ ~ -:: -++ help - |= {ren/care style/@tas pax/path} - =^ query pax - =+ xap=(flop pax) - ?~ xap [~ ~] - =+ query=(rush i.xap ;~(pfix wut yquy:urlp)) - ?~ query [~ pax] - [u.query (flop t.xap)] - =^ arg pax ~|(pax [+ -]:(split pax)) - ~| [pax=pax arg=arg query=query] - =| mow/(list move) - |% - :: Resolve core - :: - ++ make-move - ^- {(list move) _+>.$} - [(flop mow) +>.$] - :: - ++ endpoint-to-purl - |= endpoint/path - ^- purl - %+ scan - "https://www.googleapis.com/gmail/v1/users/me{<`path`endpoint>}" - auri:epur - :: Send an HTTP req - ++ send-http - |= hiz/hiss - ^+ +> - =+ wir=`wire`[ren (scot %ud count) (scot %uv (jam arg)) style pax] - =+ new-move=[ost.hid %hiss wir `~ %httr [%hiss hiz]] - +>.$(mow [new-move mow]) - :: - ++ scry - ^+ . - ?+ style ~|(%invalid-style !!) - $read read -:: $listen listen - == - :: Standard GET request - ++ read (send-http (endpoint-to-purl pax) %get ~ ~) - - :: Subscription request -:: ++ listen -:: ^+ . -:: =+ events=?>(?=([@ @ *] pax) t.t.pax) -:: |- ^+ +>.$ -:: ?~ events -:: +>.$ -:: ?: (~(has by web-hooks) i.events) :: if hook exists -:: =. +>.$ (update-hook i.events) -:: $(events t.events) -:: =. +>.$ (create-hook i.events) -:: $(events t.events) - :: - -- --- - - - - - - - - - diff --git a/app/gmail/rfc.txt b/app/gmail/rfc.txt deleted file mode 100644 index f569d3a587..0000000000 --- a/app/gmail/rfc.txt +++ /dev/null @@ -1,6 +0,0 @@ -From: urbit-test@gmail.com -To: jhenry.ault@gmail.com -Subject: As basic as it gets - -This is the plain text body of the message. Note the blank line -between the header information and the body of the message. diff --git a/app/gmail/split.hoon b/app/gmail/split.hoon deleted file mode 100644 index a4fc2ce2a4..0000000000 --- a/app/gmail/split.hoon +++ /dev/null @@ -1,71 +0,0 @@ -!: -|% -:: Splits a path into the endpoint prefix and the remainder, -:: which is assumed to be a path within the JSON object. We -:: choose the longest legal endpoint prefix. -:: -++ split - |= pax/path - :: =- ~& [%pax pax - (valid-endpoint pax)] - - =+ l=(lent pax) - |- ^- {path path} - ?: ?=(valid-get-endpoint (scag l pax)) - [(scag l pax) (slag l pax)] - ?~ l - ~& %bad-endpoint - ~|(%bad-endpoint !!) - $(l (dec l)) -:: -:: These are all the github GET endpoints, sorted with -:: `env LC_ALL=C sort` -:: -:: end-points include required query parameters -++ valid-get-endpoint - $? {$drafts id/@t $~} - {$drafts $~} - {$history $~} - {$labels id/@t $~} - {$labels $~} - {$messages id/@t $attachments id/@t $~} - {$messages id/@t $~} - {$messages $~} - {$profile $~} - {$threads id/@t $~} - {$threads $~} - == - -++ vaild-post-endpoint - $? {$drafts $send $~} - {$drafts $~} - {$messages id/@t $modify $~} - {$messages id/@t $trash $~} - {$messages id/@t $untrash $~} - {$messages $import $~} - {$messages $send $~} - {$messages $~} - {$labels $~} - {$threads id/@t $trash $~} - {$threads id/@t $untrash $~} - {$threads id/@t $modify} - {$stop $~} - {$watch $~} - == - -++ valid-delete-endpoint - $? {$drafts id/@t $~} - {$labels id/@t $~} - {$messages id/@t $~} - {$thread id/@t $~} - == -++ valid-put-endpoint - $? {$drafts id/@t $~} - {$labels id/@t $~} - == -++ valid-patch-endpoint - $? {$labels id/@t $~} - == - --- - -:: - diff --git a/app/twit.hoon b/app/twit.hoon index 430f1054be..80cdd97f7c 100644 --- a/app/twit.hoon +++ b/app/twit.hoon @@ -1,6 +1,6 @@ :: Twitter daemon :: -:::: /hook/core/twit/app +:::: /hoon/twit/app :: /- plan-acct /+ twitter, talk diff --git a/arvo/clay.hoon b/arvo/clay.hoon index 315f4e4e3c..ed4fc23d56 100644 --- a/arvo/clay.hoon +++ b/arvo/clay.hoon @@ -1296,7 +1296,12 @@ $delta p.q $direct p.q == - ++ lobe-to-silk :: XX maybe move hoo{n,k} stuff here + ++ page-to-silk :: %hoon bootstrapping + |= a/page + ?. ?=($hoon p.a) [%volt a] + [%$ p.a [%atom %t ~] q.a] + :: + ++ lobe-to-silk |= {pax/path lob/lobe} ^- silk =+ ^- hat/(map path lobe) @@ -1311,9 +1316,9 @@ [%$ p.-] =+ bol=(~(got by lat.ran) lob) ?- -.bol - $direct [%volt q.bol] + $direct (page-to-silk q.bol) $delta ~| delta+q.q.bol - [%pact $(lob q.q.bol) [%volt r.bol]] + [%pact $(lob q.q.bol) (page-to-silk r.bol)] == :: ++ page-to-lobe |=(page (shax (jam +<))) @@ -2529,8 +2534,8 @@ [%$ +:(need fil.ank:(descend-path:(zu ank:(need alh)) pax))] =+ bol=(~(got by lat.ran) lob) ?- -.bol - $direct [%volt q.bol] - $delta [%pact $(lob q.q.bol) [%volt r.bol]] + $direct (page-to-silk q.bol) + $delta [%pact $(lob q.q.bol) (page-to-silk r.bol)] == :: ++ reduce-merge-points diff --git a/arvo/eyre.hoon b/arvo/eyre.hoon index c25986a174..850054cb50 100644 --- a/arvo/eyre.hoon +++ b/arvo/eyre.hoon @@ -67,10 +67,14 @@ ++ whir-of {p/knot:ship q/term r/?($mess $lens) s/wire} :: path in dock ++ whir-se ?($core vi-arm) :: build/call ++ vi-arm - $? $out :: ++out mod request - $res :: ++res use result - $bak :: ++bak auth response - $in :: ++in handle code + $? $filter-request :: ++out mod request + $filter-response :: ++res use result + $receive-auth-response :: ++bak auth response + $receive-auth-query-string :: ++in handle code + $out + $res + $bak + $in == :: -- :: |% :: models @@ -213,8 +217,8 @@ |= {urb/json jaz/cord} ^- cord =- (cat 3 (crip -) jaz) """ - var _urb = {(pojo urb)} - window.urb = window.urb || \{}; for(k in _urb) window.urb[k] = _urb[k] + var _urb = {(pojo urb)}; + window.urb = window.urb || \{}; for(k in _urb) window.urb[k] = _urb[k]; """ :: @@ -1069,14 +1073,15 @@ ^- (each perk httr) |^ =+ hit=as-magic-filename ?^ hit [%| u.hit] - ?: is-spur - [%& %spur (flop q.pok)] + =+ hem=as-aux-request + ?^ hem + ?. check-oryx + ~|(%bad-oryx ~|([grab-oryx vew.cyz:for-client] !!)) + [%& u.hem] =+ bem=as-beam ?^ bem [%& %beam u.bem] - ?. check-oryx - ~|(%bad-oryx ~|([grab-oryx vew.cyz:for-client] !!)) - =+ hem=as-aux-request - ?^ hem [%& u.hem] + ?: is-spur + [%& %spur (flop q.pok)] ~|(strange-path+q.pok !!) :: ++ as-magic-filename @@ -1096,16 +1101,17 @@ == == :: - ++ is-spur |(?~(q.pok & ((sane %tas) i.q.pok))) - ++ as-beam + ++ is-spur |(?~(q.pok & ((sane %ta) i.q.pok))) + ++ as-beam :: /~sipnym/desk/3/... ^- (unit beam) - ?~ q.pok ~ - =+ ^- (unit {@ dez/desk rel/?}) :: /=desk/, /=desk=/ - (rush i.q.pok ;~(plug tis sym ;~(pose (cold | tis) (easy &)))) - ?~ - (tome q.pok) :: /~ship/desk/case/... - :+ ~ [our dez.u r.top] - ?. rel.u (flop t.q.pok) - (weld (flop t.q.pok) s.top) :: /=desk/... as hoon /=desk%/... + =+ =< tyk=(zl:jo (turn q.pok .)) :: a path whose elements + |=(a/knot `(unit tyke)`(rush a gasp:vast)) :: are in /=foo==/=bar + ?~ tyk ~ :: syntax + =+ %- posh:(vang & (tope top)) :: that the base path + [[~ (zing u.tyk)] ~] :: can interpolate into + ?~ - ~ :: + =+ (plex:vast %conl u) :: staticly, and make a + (biff - tome) :: valid beam :: ++ as-aux-request :: /~/... req parser ^- (unit perk) @@ -1706,9 +1712,9 @@ [[%& 12]~ %$ bale+!>(*(bale @))] :: XX specify on type? ?~ cor ~ ?~ u.cor ~ - ?: (has-arm %wyp) ~ - ?: (has-arm %upd) - [[%& 13]~ ride+[limb+%upd prep-cor]]~ + ?: (has-arm %discard-state) ~ + ?: (has-arm %update) + [[%& 13]~ ride+[limb+%update prep-cor]]~ [[%& 13]~ %$ noun+(slot 13 u.cor)]~ :: ++ call @@ -1740,8 +1746,8 @@ ?~ ole abet :: process hiss =. hen p.u.ole - ?~ u.cor (eyre-them %out r.u.ole) :: don't process - (call %out hiss+r.u.ole) + ?~ u.cor (eyre-them %filter-request r.u.ole) :: don't process + (call %filter-request hiss+r.u.ole) :: ++ fin-httr |= vax/vase:httr @@ -1753,26 +1759,31 @@ :: Interfaces :: ++ get-news _build - ++ get-quay |=(quy/quay (call %in quay+!>(quy))) + ++ get-quay |=(quy/quay (call %receive-auth-query-string quay+!>(quy))) ++ get-req |=(a/{mark vase:hiss} pump(req (~(put to req) hen a))) ++ get-thou |= {wir/whir-se hit/httr} ?+ wir !! - $in (call %bak httr+!>(hit)) - $out - ?. (has-arm %res) (fin-httr !>(hit)) - (call %res httr+!>(hit)) + ?($receive-auth-query-string $in) (call %receive-auth-response httr+!>(hit)) + ?($filter-request $out) + ?. (has-arm %filter-response) (fin-httr !>(hit)) + (call %filter-response httr+!>(hit)) == :: ++ get-made |= {wir/whir-se dep/@uvH res/(each cage tang)} ^+ abet ?: ?=($core wir) (update dep res) %. res - ?-(wir $out res-out, $res res-res, $bak res-bak, $in res-in) + ?- wir + ?($filter-request $out) res-out + ?($filter-response $res) res-res + ?($receive-auth-response $bak) res-bak + ?($receive-auth-query-string $in) res-in + == :: ++ update |= {dep/@uvH gag/(each cage tang)} - :: ~& got-upd/dep + :: ~& got-update/dep =. ..vi (pass-note %core [%f [%wasp our dep &]]) ?~ -.gag pump(cor `q.p.gag) ?: &(=(~ cor) =(%$ usr)) @@ -1840,13 +1851,13 @@ :: ++ res-in %+ on-error dead-this |. - (handle-moves send+(do-send %in) ~) + (handle-moves send+(do-send %receive-auth-query-string) ~) :: ++ res-res %+ on-error dead-hiss |. %- handle-moves :~ give+do-give - send+(do-send %out) + send+(do-send %filter-request) redo+_pump == :: @@ -1854,7 +1865,7 @@ %+ on-error dead-this |. %- handle-moves :~ give+do-give - send+(do-send %in) + send+(do-send %receive-auth-query-string) redo+_pump(..vi (give-html 200 ~ exit:xml)) == :: @@ -1863,7 +1874,7 @@ %+ on-error warn |. %- handle-moves :~ give+do-give - send+(do-send %out) + send+(do-send %filter-request) show+do-show == -- -- diff --git a/arvo/ford.hoon b/arvo/ford.hoon index cb36e6533d..ebb78d82c4 100644 --- a/arvo/ford.hoon +++ b/arvo/ford.hoon @@ -156,7 +156,7 @@ (rap 3 |-([i.a ?~(t.a ~ ['-' $(a t.a)])])) :: ++ tear :: split term - =- |=(a/term (rush a (most hep sym))) + =- |=(a/term `(list term)`(fall (rush a (most hep sym)) /[a])) sym=(cook crip ;~(plug low (star ;~(pose low nud)))) :: ++ za :: per event @@ -608,21 +608,39 @@ ~/ %fame |= {cof/cafe bem/beam} ^- (bolt beam) - %+ cope - ?~ s.bem (flue cof) - =+ opt=`(list term)`(fall (tear i.s.bem) ~) - ?~ opt (flue cof) - |- ^- (bolt (unit beam)) - =. i.s.bem (tack opt) + =^ pax bem [(flop s.bem) bem(s ~)] + |^ (cope opts (flux |=(a/(unit beam) (fall a bem)))) + :: + ++ opts :: search unless done + ^- (bolt (unit beam)) + ?^ pax (wide(pax t.pax) (tear i.pax)) %+ cope (lima cof %hoon bem) - |= {cof/cafe vax/(unit vase)} ^- (bolt (unit beam)) - ?^ vax (fine cof `bem) - ?~ t.opt (flue cof) - %+ cope ^$(opt t.opt, t.s.bem :_(t.s.bem i.opt), cof cof) - |= {cof/cafe bem/(unit beam)} ^- (bolt (unit beam)) - ?^ bem (fine cof bem) - ^$(opt :_(t.t.opt (tack i.opt i.t.opt ~)), cof cof) - (flux |=(a/(unit beam) (fall a bem))) + (flux |=(a/(unit vase) ?~(a ~ `bem))) + :: + ++ wide :: match segments + |= sub/(list term) ^- (bolt (unit beam)) + ?~ sub opts + ?~ t.sub opts(s.bem [i.sub s.bem]) + => .(sub `(list term)`sub) :: TMI + =- (cope - flat) + %^ lash cof bem + |= {cof/cafe dir/knot} ^- (bolt (unit beam)) + =+ sus=(tear dir) + ?. =(sus (scag (lent sus) sub)) + (flue cof) + %_ ^$ + cof cof + sub (slag (lent sus) sub) + s.bem [dir s.bem] + == + :: + ++ flat :: at most one + |= {cof/cafe opt/(map term beam)} ^- (bolt (unit beam)) + ?~ opt (flue cof) + ?: ?=({^ $~ $~} opt) (fine cof `q.n.opt) + =+ all=(~(run by `(map term beam)`opt) tope) + (flaw cof leaf+"fame: fork {}" ~) + -- :: ++ fang :: protocol door |= {cof/cafe for/mark} ^- (bolt vase) @@ -642,6 +660,7 @@ [~ u=(^case a)] nuck:so :: + ++ mota ;~(pfix pat mota:vez) :: atom odor ++ hath (sear plex (stag %conl poor)):vez :: hood path ++ have (sear tome ;~(pfix fas hath)) :: hood beam ++ hith :: static path @@ -716,7 +735,7 @@ (stag %lin ;~(pfix pam lin:read)) (stag %man ;~(pfix tar man:read)) (stag %nap ;~(pfix cab day:read)) - (stag %now ;~(pfix pat day:read)) + (stag %nod ;~(pfix cab now:read)) (stag %saw ;~(pfix sem saw:read)) (stag %see ;~(pfix col see:read)) (stag %sic ;~(pfix ket sic:read)) @@ -770,6 +789,10 @@ =< ;~(sfix (star (sear . day)) gap duz) |= a/^horn ^- (unit {term ^horn}) ?+(-.a ~ $dub `[p.a q.a]) + :: + ++ now + %+ rail ;~((glue cab) mota day) + ;~(pfix gap ;~(plug mota day)) :: ++ saw %+ rail @@ -898,11 +921,17 @@ ++ keel :: apply mutations |= {cof/cafe suh/vase yom/(list (pair wing vase))} ^- (bolt vase) - %+ cool =< |.(leaf+"ford: keel {<(murn yom +)>}") - |= {a/wing b/span *} - =+ c=p:(slap suh wing+a) - ?: (~(nest ut c) | b) ~ - (some [a c b]) + %+ cool + =< |. ^- tank + :+ %palm [" " ~ ~ ~] + ~[leaf+"ford: keel" rose+[" " ~ ~]^(murn yom +)] + |= {a/wing b/span *} ^- (unit tank) + =+ typ=(mule |.(p:(slap suh wing+a))) + ?: ?=($| -.typ) + (some (show [%c %pull] %l a)) + ?: (~(nest ut p.typ) | b) ~ + %^ some %palm ["." ~ ~ ~] + ~[(show [%c %mute] %l a) >[p.typ b]<] %^ maim cof %+ slop suh |- ^- vase @@ -941,27 +970,23 @@ %+ cool |.(leaf+"ford: load {} {<(tope bem)>}") =. s.bem [for s.bem] %+ cope (liar cof bem) - |= {cof/cafe cay/cage} + |= {cof/cafe cay/cage} ^- (bolt vase) ?. =(for p.cay) (flaw cof leaf+"unexpected mark {}" ~) - ((lake for) cof q.cay) + (fine cof q.cay) :: ++ lake :: check+coerce - |= for/mark + |= {fit/? for/mark} |= {cof/cafe sam/vase} ^- (bolt vase) %+ cool |.(leaf+"ford: check {<[for bek `@p`(mug q.sam)]>}") - ?: ?=($hoon for) - =+ mas=((soft @t) q.sam) - ?~ mas - (flaw cof [leaf+"ford: bad hoon: {<[for bek]>}"]~) - (fine cof [%atom %t ~] u.mas) %+ cope (fang cof for) |= {cof/cafe tux/vase} =+ typ=p:(slot 6 tux) =. typ ?+(-.typ typ $face q.typ) ?: (~(nest ut typ) | p.sam) (fine cof typ q.sam) + ?. fit (flaw cof [%leaf "ford: invalid type: {}"]~) ?. (slob %grab p.tux) (flaw cof [%leaf "ford: no grab: {<[for bek]>}"]~) =+ gab=(slap tux [%limb %grab]) @@ -982,11 +1007,6 @@ ?~ von [p=cof q=[%1 [%c %w bem ~] ~ ~]] (fine cof bem(r [%ud ((hard @) +.+:(need u.von))])) :: - ++ lave :: validate - |= {cof/cafe for/mark som/*} - ^- (bolt vase) - ((lake for) cof [%noun som]) - :: ++ lane :: span infer |= {cof/cafe typ/span gen/twig} %+ (cowl cof) (mule |.((~(play ut typ) gen))) @@ -1004,10 +1024,10 @@ ++ leap :: XX load with path ~/ %leap |= {cof/cafe arg/coin bem/beam bom/beam} - %+ (clef %boil) (fine cof arg bem bom) - |= {cof/cafe arg/coin bem/beam bom/beam} %+ cope (lamp cof bem) |= {cof/cafe bem/beam} + %+ (clef %boil) (fine cof arg bem bom) + |= {cof/cafe arg/coin bem/beam bom/beam} %+ cope (fame cof bem) |= {cof/cafe bem/beam} (cope (fade cof %hoon bem) abut:(meow bom arg)) @@ -1085,7 +1105,7 @@ :: %+ cool |.(leaf+"ford: link {} {} {}") ?: =(too for) (fine cof vax) ?: |(=(%noun for) =(%$ for)) - ((lake too) cof vax) + ((lake & too) cof vax) %+ cope (fang cof for) |= {cof/cafe pro/vase} ^- (bolt vase) ?: :: =< $ ~% %limb-grow link-jet ~ |. @@ -1230,8 +1250,6 @@ :: $bunt %+ cool |.(leaf+"ford: bunt {}") - ?: ?=($hoon p.kas) - (fine cof %& p.kas [%atom %t ~] '') %+ cope (fang cof p.kas) |= {cof/cafe tux/vase} =+ [typ=p val=q]:(slot 6 tux) @@ -1346,7 +1364,7 @@ :: $vale %+ cool |.(leaf+"ford: vale {} {<`@p`(mug q.kas)>}") - %+ cope (lave cof p.kas q.kas) + %+ cope ((lake & p.kas) cof [%noun q.kas]) (flux |=(vax/vase `gage`[%& p.kas vax])) :: $volt @@ -1559,6 +1577,10 @@ $now %+ cope (chad cof bax %da p.hon) (flux |=(a/vase noun+a)) + :: + $nod + %+ cope (chad cof bax p.hon q.hon) + (flux |=(a/vase noun+a)) :: $nap %+ cope (chai cof bax p.hon) @@ -1599,7 +1621,7 @@ %+ cope (fade cof %hoon how) |= {cof/cafe hyd/hood} %+ cope (abut:(meow how arg) cof hyd) - ;~(cope (lake q.hon) (flux |=(a/vase [q.hon a]))) + ;~(cope (lake | q.hon) (flux |=(a/vase [q.hon a]))) == :: ++ head :: consume structures @@ -1713,12 +1735,6 @@ |=({cof/cafe p/silk q/silk} (cope (make cof q) furl)) == |= {cof/cafe cay/cage coy/cage} ^- (bolt gage) - ?: ?=($hoon p.cay) - ?. ?=($txt-diff p.coy) - (flaw cof leaf+"{} mark with bad diff type: {}" ~) - %+ cope (maul cof !>(pact-hoon) (slop q.cay q.coy)) - (flux |=(vax/vase:cord [%& p.cay vax])) - :: %+ cope (fang cof p.cay) |= {cof/cafe pro/vase} ?. (slab %grad p.pro) diff --git a/arvo/hoon.hoon b/arvo/hoon.hoon index 76e1847943..435ec4fd54 100644 --- a/arvo/hoon.hoon +++ b/arvo/hoon.hoon @@ -1088,7 +1088,7 @@ |- ^- @ =+ c=(fnv (mix p.b (fnv q.b))) =+ d=(mix (rsh 0 31 c) (end 0 31 c)) - ?. =(0 c) c + ?. =(0 d) d $(q.b +(q.b)) =+ b=2.166.136.261 |- ^- @ @@ -7269,7 +7269,9 @@ :+ %per [%name %v %$ 1] :: => v=. :+ %pin :+ %name %a :: =+ ^= a [%per [%limb %v] p.gen] :: =>(v {p.gen}) - :+ %pin [%name %b [%per [%limb %v] q.gen]] :: =+ b==>(v {q.gen}) + :+ %pin + :+ %name %b :: =+ ^= b + [%cast [%base %noun] [%per [%limb %v] q.gen]] :: =+ `*`=>(v {q.gen}) :+ %pin :: =+ c=(a b) [%name %c [%call [%limb %a] [%limb %b] ~]] :: [%sure [%same [%limb %c] [%limb %b]] [%limb %c]] :: ?>(=(c b) c) @@ -7733,8 +7735,6 @@ =- [p.tez (doge q.p.tez q.tez)] ^= tez ^- {p/{p/(map span @) q/(map @ wine)} q/wine} - ?: (~(meet ut sut) -:!>(*span)) - [dex %span] ?- sut $noun [dex sut] $void [dex sut] @@ -7783,7 +7783,9 @@ ?^(p.sut yad [p.yad [%face p.sut q.yad]]) :: {$fork *} - =+ yed=(~(tap in p.sut)) + ?: (~(meet ut sut) -:!>(*span)) + [dex %span] + =+ yed=(sort (~(tap in p.sut)) aor) =- [p [%pick q]] |- ^- {p/{p/(map span @) q/(map @ wine)} q/(list wine)} ?~ yed @@ -10560,6 +10562,7 @@ == :: ++ wire path :: event pretext ++ sloy + !: |= sod/slyd ^- slyt |= {ref/* raw/*} diff --git a/arvo/zuse.hoon b/arvo/zuse.hoon index 239a30ece8..f3138184b0 100644 --- a/arvo/zuse.hoon +++ b/arvo/zuse.hoon @@ -2235,7 +2235,8 @@ {$lin p/(list mark) q/horn} :: /& translates {$man p/(map knot horn)} :: /* hetero map {$nap p/horn} :: /_ homo map - {$now p/horn} :: /@ list by @da + {$now p/horn} :: DEPRECATED + {$nod p/term q/horn} :: /_ @ list by odor {$saw p/twig q/horn} :: /; operate on {$see p/hops q/horn} :: /: relative to {$sic p/twig q/horn} :: /^ cast diff --git a/gen/change.hoon b/gen/change.hoon deleted file mode 100644 index 4414e8b587..0000000000 --- a/gen/change.hoon +++ /dev/null @@ -1,90 +0,0 @@ -:: -:::: /hoon/change/gen - :: -/? 310 -:: -:::: - !: -:- %say -|= * -:- %noun -=- %+ turn - - |= {a/@tas b/@tas} - ?: | - ^- @ta - %- crip - ;: weld - "s/\\$" - (trip a) - "/" - "?($" - (trip a) - " $" - (trip b) - ")" - "/g" - == - ?: | - ^- @ta - %- crip - ;: weld - "s/%" - (trip a) - "/" - "%" - (trip b) - "/g" - == - ?: & - ^- @ta - %- crip - ;: weld - "s/\\?(\\$" - (trip a) - " \\$" - (trip b) - ")/$" - (trip b) - "/g" - == - !! -^- (list (pair @tas @tas)) -:~ [%flap %claw] :: used in ames - [%slug %shoe] - [%rack %bank] - [%gate %lamb] - [%lock %gill] - :: [%lamp %gate] reused - [%bud %scon] - [%qua %conq] - [%dub %cons] - [%tri %cont] :: collides with %trip - [%ray %conl] - [%all %conp] - - [%cold %bunt] :: parser jet - [%quid %calq] - [%quip %calt] - [%with %open] - :: [%kick %nock] reused; used in ames - [%live %poll] :: also a hint - [%show %dump] :: used in %ames - - :: [%fate %show] reused - - [%germ %ddup] :: also a hint - [%type %peep] - [%fly %fix] - [%ram %rev] :: also %ramp - [%eat %sip] - [%has %pin] - [%saw %nip] - [%dig %ifcl] :: %digitalocean in ape/cloud - [%nay %deny] - [%aye %sure] - [%deal %deft] :: used in all vanes - [%dab %ifat] - [%non %ifno] :: also %none - [%fit %fits] :: also %fitz - [%nock %code] :: reused -== diff --git a/gen/code.hoon b/gen/code.hoon index 360226406f..48e94e97a7 100644 --- a/gen/code.hoon +++ b/gen/code.hoon @@ -1,17 +1,14 @@ :: :::: /hoon/code/gen :: -/- sole -=+ sole -:- %ask +:- %say |= $: {now/@da eny/@uvI bec/beak} $~ $~ == -^- (sole-result) -%+ sole-yo - :- %leaf - %+ slag 1 - %+ scow %p - .^(@p %a /(scot %p p.bec)/code/(scot %da now)/(scot %p p.bec)) -sole-no +:- %tang +:_ ~ +:- %leaf +%+ slag 1 +%+ scow %p +.^(@p %a /(scot %p p.bec)/code/(scot %da now)/(scot %p p.bec)) diff --git a/gen/curl-hiss.hoon b/gen/curl-hiss.hoon index ff54f14084..7b9b4c3aff 100644 --- a/gen/curl-hiss.hoon +++ b/gen/curl-hiss.hoon @@ -1,5 +1,5 @@ :: -:::: /hoon/curl/gen +:::: /hoon/curl-hiss/gen :: /? 310 /- sole diff --git a/gen/gmail/list.hoon b/gen/gmail/list.hoon deleted file mode 100644 index 99f5bd0f85..0000000000 --- a/gen/gmail/list.hoon +++ /dev/null @@ -1,18 +0,0 @@ -:: -:::: /hoon/list/gmail/gen - :: -/? 310 -:: -:::: - !: -:- %say -|= $: {now/@da eny/@uvI bec/beak} - arg/$@($~ {number/@u $~}) - $~ - == -?~ arg $(arg [5 ~]) -:- %noun -%+ turn (scag number.arg .^((list {@t @t}) %gx /=gmail=/read/messages)) -|= {message-id/@t thread-id/@t} -=+ .^({from/@t subject/@t} %gx /=gmail=/read/messages/[message-id]) -[from=from (trip subject)] diff --git a/gen/gmail/send.hoon b/gen/gmail/send.hoon deleted file mode 100644 index 564ccf16bc..0000000000 --- a/gen/gmail/send.hoon +++ /dev/null @@ -1,14 +0,0 @@ -:: -:::: /hoon/send/gmail/gen - :: -/? 310 -/- rfc -:- %say -|= {^ {to/tape subject/tape $~} _from="urbit-test@gmail.com"} -:- %gmail-req -:^ %post /messages/'send' ~['uploadType'^'simple'] -^- message:rfc -=+ parse-adr=;~((glue pat) (cook crip (star ;~(less pat next))) (cook crip (star next))) -:+ (scan from parse-adr) - (scan to parse-adr) -[(crip subject) ''] diff --git a/gen/hello.hoon b/gen/hello.hoon index 28c9f71754..74d7b3dc94 100644 --- a/gen/hello.hoon +++ b/gen/hello.hoon @@ -8,4 +8,4 @@ :- %say |= {^ {{txt/@tas $~} $~}} :- %noun -(crip (weld "hello, " (flop (trip txt)))) +(crip (weld "hello, " (trip txt))) diff --git a/gen/hood/invite.hoon b/gen/hood/invite.hoon deleted file mode 100644 index 6a063eca18..0000000000 --- a/gen/hood/invite.hoon +++ /dev/null @@ -1,12 +0,0 @@ -:: -:::: /hoon/invite/hood/gen - :: -/? 310 -:: -:::: - !: -:- %say -|= $: {now/@da eny/@uvI bec/beak} - {{who/@p myl/@t $~} $~} - == -[%helm-invite who myl] diff --git a/gen/make.hoon b/gen/make.hoon deleted file mode 100644 index fdc7b4898e..0000000000 --- a/gen/make.hoon +++ /dev/null @@ -1,6 +0,0 @@ -:: -:::: /hoon/make/gen - :: -/? 310 -:- %say -|=({^ arg/(list @) foo/_`@`1 bar/_`@`2} noun+[arg foo bar]) diff --git a/lib/basic-auth.hoon b/lib/basic-auth.hoon index c4e1bc9336..8885ac9d17 100644 --- a/lib/basic-auth.hoon +++ b/lib/basic-auth.hoon @@ -1,8 +1,33 @@ -!: -=+ keys=@t -|= bal/(bale keys) -?~ key.bal - ~|(%basic-auth-no-key ~_(leaf+"Run |init-auth-basic {<`path`dom.bal>}" !!)) -=+ aut=authorization+(cat 3 'Basic ' key.bal) -~& aut=`{@tas @t}`aut -|=(a/hiss [%send %_(a q.q (~(add ja q.q.a) -.aut +.aut))]) +:: Basic authentication +:: +:::: /hoon/basic-auth/lib + :: +|% +++ keys @t +-- +:: +:::: + :: +|_ {bal/(bale keys) $~} +++ auth + |% + ++ header + ^- cord + ?~ key.bal + ~_ leaf+"Run |init-auth-basic {<`path`dom.bal>}" + ~|(%basic-auth-no-key !!) + (cat 3 'Basic ' key.bal) + -- +:: +++ add-auth-header + |= a/hiss ^- hiss + ~& auth+(earn p.a) + %_(a q.q (~(add ja q.q.a) %authorization header:auth)) +:: +++ standard + |% + ++ out-adding-header + |= a/hiss ^- sec-move + [%send (add-auth-header a)] + -- +-- diff --git a/lib/down-jet/rend.hoon b/lib/down-jet/rend.hoon index be77989cbc..55900040e0 100644 --- a/lib/down-jet/rend.hoon +++ b/lib/down-jet/rend.hoon @@ -210,7 +210,7 @@ |= a/tape ^- tape ?~ a ~ ?: ?| [?=(^ q)]:(alp 1^1 a) - (~(has in (silt "!*'();:@&=+$,/?/%.~_")) i.a) :: XX reparse + (~(has in (silt "#!*'();:@&=+$,/?/%.~_")) i.a) :: XX reparse == [i.a $(a t.a)] (weld (urle (trip i.a)) $(a t.a)) diff --git a/lib/drum.hoon b/lib/drum.hoon index 61b0e22221..ecb2050264 100644 --- a/lib/drum.hoon +++ b/lib/drum.hoon @@ -475,7 +475,10 @@ ++ se-talk |= tac/(list tank) ^+ +> - (se-emit 0 %poke /drum/talk [our %talk] (said:talk our %drum now eny tac)) + :: XX talk should be usable for stack traces, see urbit#584 which this change + :: closed for the problems there + ((slog (flop tac)) +>) + ::(se-emit 0 %poke /drum/talk [our %talk] (said:talk our %drum now eny tac)) :: ++ se-text :: return text |= txt/tape diff --git a/lib/hep-to-cab.hoon b/lib/hep-to-cab.hoon new file mode 100644 index 0000000000..524520b0eb --- /dev/null +++ b/lib/hep-to-cab.hoon @@ -0,0 +1,25 @@ +:: rewrite query string keys +:: +:::: /hoon/hep-to-cab/lib + :: +/? 310 +:: +:::: ~fyr + :: +=< term +|% +++ gsub :: replace chars + |= {a/@t b/@t t/@t} + ^- @t + ?: =('' t) t + %+ mix (lsh 3 1 $(t (rsh 3 1 t))) + =+ c=(end 3 1 t) + ?:(=(a c) b c) +:: +++ term |=(a/^term (gsub '-' '_' a)) :: single atom +++ path |=(a/^path (turn a term)) :: path elements +++ quay :: query string keys + |= a/^quay ^+ a + %+ turn a + |=({p/@t q/@t} [(term p) q]) +-- diff --git a/lib/interpolate.hoon b/lib/interpolate.hoon new file mode 100644 index 0000000000..595a161a06 --- /dev/null +++ b/lib/interpolate.hoon @@ -0,0 +1,48 @@ +:: /foo/:bar/baz interpolation syntax +:: +:::: /hoon/interpolate/lib + :: +/? 310 +:: +:::: ~fyr + :: +|% +++ parse-url + |= a/$@(cord:purl purl) ^- purl + ?^ a a + ~| bad-url+a + (rash a auri:epur) +:: +++ add-query + |= {a/$@(@t purl) b/quay} ^- purl + ?@ a $(a (parse-url a)) :: deal with cord + a(r (weld r.a b)) +:: +++ into-url + |= {a/$@(cord purl) b/(unit hart) c/(list (pair term knot))} + ^- purl + ?@ a $(a (parse-url a)) :: deal with cord + %_ a + p ?^(b u.b p.a) + q.q (into-path q.q.a c) + == +:: +++ into-path :: [/a/:b/c [%b 'foo']~] -> /a/foo/c + =+ replacable=|=(a/knot `(unit term)`(rush a ;~(pfix col sym))) + |= {a/path b/(list (pair term knot))} ^- path + ?~ a ?~(b ~ ~|(unused-values+b !!)) + =+ (replacable i.a) + ?~ - [i.a $(a t.a)] :: literal value + ?~ b ~|(no-value+u !!) + ?. =(u p.i.b) ~|(mismatch+[u p.i.b] !!) + [q.i.b $(a t.a, b t.b)] +:: +++ into-path-partial :: [/a/:b/c [d+'bar' b+'foo']~] -> [/a/foo/c [d+'bar']~] + |= {pax/path quy/quay} ^- {path quay} + =+ ^= inline :: required names + %- ~(gas in *(set term)) + (murn pax replacable:into-path) + =^ inter quy + (skid quy |=({a/knot @} (~(has in inline) a))) + [(into-path pax inter) quy] +-- diff --git a/lib/oauth1.hoon b/lib/oauth1.hoon index 82dabf87a1..dbb2d6c870 100644 --- a/lib/oauth1.hoon +++ b/lib/oauth1.hoon @@ -2,6 +2,7 @@ :: :::: /hoon/oauth1/lib :: +/+ interpolate, hep-to-cab |% ++ keys cord:{key/@t sec/@t} :: app key pair ++ token :: user keys @@ -15,20 +16,7 @@ :::: :: |% -++ fass :: rewrite quay - |= a/quay - %+ turn a - |= {p/@t q/@t} ^+ +< - [(gsub '-' '_' p) q] -:: -++ gsub :: replace chars - |= {a/@t b/@t t/@t} - ^- @t - ?: =('' t) t - %+ mix (lsh 3 1 $(t (rsh 3 1 t))) - =+ c=(end 3 1 t) - ?:(=(a c) b c) -:: +++ parse-url parse-url:interpolate ++ join |= {a/cord b/(list cord)} ?~ b '' @@ -43,7 +31,7 @@ ++ to-header |= a/quay ^- tape %+ joint ", " - (turn a |=({k/@t v/@t} `tape`~[k '="' v '"'])) :: normalized later + (turn a |=({k/@t v/@t} `tape`~[k '="' v '"'])) :: normalized later :: :: partial tail:earn for sorting ++ encode-pairs @@ -52,7 +40,7 @@ |= {k/@t v/@t} ^- tape :(weld (urle (trip k)) "=" (urle (trip v))) :: -++ parse-pairs :: x-form-urlencoded +++ parse-pairs :: x-form-urlencoded |= bod/(unit octs) ^- quay-enc ~| %parsing-body ?~ bod ~ @@ -60,6 +48,7 @@ :: ++ post-quay |= {a/purl b/quay} ^- hiss + =. b (quay:hep-to-cab b) =- [a %post - ?~(b ~ (some (tact +:(tail:earn b))))] (my content-type+['application/x-www-form-urlencoded']~ ~) :: @@ -69,60 +58,30 @@ =- (mean (flop `tang`[>a< -])) (turn (lore (crip b)) |=(c/cord leaf+(trip c))) :: -++ dbg-post `purl`[`hart`[| `6.000 [%& /localhost]] `pork``/testing `quay`/] ++ bad-response |=(a/@u ?:(=(2 (div a 100)) | ~&(bad-httr+a &))) ++ quay-keys |-($@(knot {$ $})) :: improper tree -++ grab-quay :: ?=({@t @t @t} ((grab-quay *httr) %key1 %key2 %key3)) - |* {a/httr b/quay-keys} - ~| bad-quay+r.a - =+ quy=(rash q:(need r.a) yquy:urlp) - ~| quy - =+ all=(malt quy) +++ grab-quay :: ?=({@t @t @t} (grab-quay r:*httr %key1 %key2 %key3)) + |* {a/(unit octs) b/quay-keys} + =+ ~| bad-quay+a + c=(rash q:(need `(unit octs)`a) yquy:urlp) + ~| grab-quay+[c b] + =+ all=(malt c) %. b |* b/quay-keys ?@ b ~|(b (~(got by all) b)) [(..$ -.b) (..$ +.b)] -:: -++ parse-url - |= a/$@(cord:purl purl) ^- purl - ?^ a a - ~| bad-url+a - (rash a auri:epur) -:: -++ interpolate-url - |= {a/$@(cord purl) b/(unit hart) c/(list (pair term knot))} - ^- purl - ?@ a $(a (parse-url a)) :: deal with cord - %_ a - p ?^(b u.b p.a) - q.q (interpolate-path q.q.a c) - == -:: -++ interpolate-path :: [/a/:b/c [%b 'foo']~] -> /a/foo/c - |= {a/path b/(list (pair term knot))} ^- path - ?~ a ?~(b ~ ~|(unused-values+b !!)) - =+ (rush i.a ;~(pfix col sym)) - ?~ - [i.a $(a t.a)] :: not interpolable - ?~ b ~|(no-value+u !!) - ?. =(u p.i.b) ~|(mismatch+[u p.i.b] !!) - [q.i.b $(a t.a, b t.b)] -- !: :::: :: -|= {request/$@(@t purl) dialog/$@(@t purl) code-exchange/$@(@t purl)} -=+ :+ dialog-url=(parse-url dialog) - exchange-url=(parse-url code-exchange) - token-reqs-url=(parse-url request) -|_ {done/* (bale keys) tok/token} -+- core-move $^({sec-move _done} sec-move) :: stateful +|_ {(bale keys) tok/token} ++ consumer-key key:decode-keys ++ consumer-secret sec:decode-keys ++ decode-keys :: XX from bale w/ typed %jael ^- {key/@t sec/@t $~} ?. =(~ `@`key) ~| %oauth-bad-keys - ((hard {cid/@t cis/@t $~}) (lore key)) + ((hard {key/@t sec/@t $~}) (lore key)) %+ mean-wall %oauth-no-keys """ Run |init-oauth1 {<`path`dom>} @@ -130,45 +89,54 @@ {(trip oauth-callback)} """ :: +++ exchange-token + |= a/$@(@t purl) ^- hiss + (post-quay (parse-url a) ~) +:: +++ request-token + |= a/$@(@t purl) ^- hiss + (post-quay (parse-url a) oauth-callback+oauth-callback ~) +:: ++ our-host .^(hart %e /(scot %p our)/host/fake) ++ oauth-callback ~& [%oauth-warning "Make sure this urbit ". "is running on {(earn our-host `~ ~)}"] %- crip %- earn - %^ interpolate-url 'https://our-host/~/ac/:domain/:user/in' + %^ interpolate 'https://our-host/~/ac/:domain/:user/in' `our-host :~ domain+(join '.' (flop dom)) user+(scot %ta usr) == :: +++ auth-url + |= url/$@(@t purl) ^- purl + %+ add-query:interpolate url + %- quay:hep-to-cab + ?. ?=({$request-token ^} tok) + ~|(%no-token-for-dialog !!) + :- oauth-token+oauth-token.tok + ?~(usr ~ [screen-name+usr]~) :: -++ toke-url - |= quy/quay ^- purl - %_ dialog-url - r (fass ?~(usr quy [screen-name+usr quy])) - == +++ grab-token-response + |= a/httr ^- {tok/@t sec/@t} + (grab-quay r.a 'oauth_token' 'oauth_token_secret') :: -++ token-exchange (post-quay exchange-url ~) -++ token-request (post-quay token-reqs-url oauth-callback+oauth-callback ~) ++ identity %+ weld ?~(usr "default identity for " "{(trip usr)}@") (trip (join '.' (flop dom))) :: -:: use token to sign authorization header. requires: -:: ++ res (res-handle-reqt handle-token) :: take request token -:: ++ bak (res-save-access handle-token) :: obtained access token -++ out-math - ^- $-(hiss $%({$send hiss} {$show purl})) - ?~ tok - _[%send (add-auth ~ token-request)] - ?: ?=($request-token -.tok) - _[%show (toke-url oauth-token+oauth-token.tok ~)] - |= a/hiss ^- {$send hiss} - [%send (add-auth [oauth-token+oauth-token.tok]~ a)] +++ check-screen-name + |= a/httr ^- ? + =+ nam=(grab-quay r.a 'screen_name') + ?~ usr & + ?: =(usr nam) & + =< | + %- %*(. slog pri 1) + (flop p:(mule |.(~|(wrong-user+[req=usr got=nam] !!)))) :: -++ in-oauth-token - |= a/quay ^- sec-move +++ check-token-quay + |= a/quay ^+ %& =. a (sort a aor) ?. ?=({{$'oauth_token' oauth-token/@t} {$'oauth_verifier' @t} $~} a) ~|(no-token+a !!) @@ -180,58 +148,15 @@ ?. =(oauth-token.tok oauth-token.q.i.a) ~| wrong-token+[id=usr q.i.a] ~|(%multiple-tokens-unsupported !!) - [%send (add-auth a token-exchange)] + %& :: -++ token-response ['oauth_token' 'oauth_token_secret'] -+- bak-save-access - |= handle/$-(token _done) - %- (res-parse token-response 'screen_name') - |= {access-token/{tok/@t sec/@t} nam/knot} ^- core-move - ?. ?~(usr & =(usr nam)) - %- %- %*(. slog pri 1) - (flop p:(mule |.(~|(wrong-user+[req=usr got=nam] !!)))) - [[%redo ~] (handle `token`~)] - [[%redo ~] (handle `token`[%access-token access-token])] -:: -+- res-parse - |* para/quay-keys - |= handle/$-(_?~(para ~ (grab-quay *httr para)) core-move) - |= a/httr ^- core-move - ?: (bad-response p.a) - [%give a] - :: [%redo ~] :: handle 4xx? - (handle (grab-quay a para)) -:: -++ res-give |=(a/httr [%give a]) -+- res-handle-reqt - |= handle/$-(token _done) ^- $-(httr core-move) - ?~ tok - (res-save-reqt handle) - res-give -:: -+- res-save-reqt - |= handle/$-(token _done) ^- $-(httr core-move) - %- (res-parse token-response 'oauth_callback_confirmed') - |= {request-token/{tok/@t sec/@t} cof/term} ^- core-move - ?. =(%true cof) - ~|(%callback-rejected !!) - [[%redo ~] (handle `token`[%request-token request-token])] -:: -:: -++ add-auth - =< |= $: auq/quay :: extra oauth parameters - hiz/{purl meth hed/math (unit octs)} - == - ^- hiss - ~& add-auth+(earn -.hiz) - %_ hiz - hed (~(add ja hed.hiz) %authorization (authorization auq hiz)) - == +++ auth |% - ++ authorization + ++ header |= {auq/quay url/purl med/meth math bod/(unit octs)} + ^- cord =^ quy url [r.url url(r ~)] :: query string handled separately - =. auq (fass (weld auq auth-quay)) + =. auq (quay:hep-to-cab (weld auq computed-query)) =+ ^- qen/quay-enc :: semi-encoded for sorting %+ weld (parse-pairs bod) (encode-pairs (weld auq quy)) @@ -240,7 +165,7 @@ =. auq ['oauth_signature'^(crip (urle sig)) auq] (crip "OAuth {(to-header auq)}") :: - ++ auth-quay + ++ computed-query ^- quay :~ oauth-consumer-key+consumer-key oauth-nonce+(scot %uw (shaf %non eny)) @@ -267,4 +192,138 @@ (trip ?^(tok token-secret.tok '')) == -- +:: +++ add-auth-header + |= {extra/quay request/{url/purl meth hed/math (unit octs)}} + ^- hiss + :: =. url.request [| `6.000 [%& /localhost]] :: for use with unix nc + ~& add-auth-header+(earn url.request) + %_ request + hed + (~(add ja hed.request) %authorization (header:auth extra request)) + == +:: expected semantics, to be copied and modified if anything doesn't work +++ standard + |* {done/* save/$-(token *)} :: save/$-(token _done) + |% + ++ save ^-($-(token _done) ^save) :: shadow(type canary) + ++ core-move $^({sec-move _done} sec-move) :: stateful + :: + :: use token to sign authorization header. expects: + :: ++ res res-handle-request-token :: save request token + :: ++ in (in-token-exhange 'http://...') :: handle callback + ++ out-add-header + |= {request-url/$@(@t purl) dialog-url/$@(@t purl)} + :: + |= a/hiss ^- $%({$send hiss} {$show purl}) + ?- tok + $~ + [%send (add-auth-header ~ (request-token request-url))] + :: + {$access-token ^} + [%send (add-auth-header [oauth-token+oauth-token.tok]~ a)] + :: + {$request-token ^} + [%show (auth-url dialog-url)] + == + :: + :: If no token is saved, the http response we just got has a request token + ++ res-handle-request-token + |= a/httr ^- core-move + ?^ tok [%give a] + ?. =(%true (grab-quay r.a 'oauth_callback_confirmed')) + ~|(%callback-rejected !!) + =+ request-token=(grab-token-response a) + [[%redo ~] (save `token`[%request-token request-token])] + :: + :: Exchange oauth_token in query string for access token. expects: + :: ++ bak bak-save-token :: save access token + ++ in-exchange-token + |= exchange-url/$@(@t purl) + :: + |= a/quay ^- sec-move + ?> (check-token-quay a) + [%send (add-auth-header a (exchange-token exchange-url))] + :: + :: If a valid access token has been returned, save it + ++ bak-save-token + |= a/httr ^- core-move + ?: (bad-response p.a) + [%give a] :: [%redo ~] :: handle 4xx? + ?. (check-screen-name a) + [[%redo ~] (handle `token`~)] + =+ access-token=(grab-token-response a) + [[%redo ~] (save `token`[%access-token access-token])] + -- -- +:: +:::: Example "standard" sec/ core: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth1 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth1) tok/token:oauth1} +:: ++ aut (~(standard oauth1 bal tok) . |=(tok/token:oauth1 +>(tok tok))) +:: ++ out +:: %+ out-add-header:aut +:: request-token='https://my-api.com/request_token' +:: oauth-dialog='https://my-api.com/authorize' +:: :: +:: ++ res res-handle-request-token:aut +:: ++ in +:: %- in-exchagne-token:aut +:: exchange-url='https://my-api.com/access_token' +:: :: +:: ++ bak bak-save-token:aut +:: -- +:: +:: +:::: Equivalent imperative code: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth1 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth1) tok/token:oauth1} +:: ++ aut ~(. oauth1 bal tok) +:: ++ out :: add header +:: =+ aut +:: |= req/hiss ^- $%({$send hiss} {$show purl}) +:: ?~ tok +:: [%send (add-auth-header ~ (request-token 'https://my-api.com/request_token'))] +:: ?: ?=($request-token -.tok) +:: [%show (auth-url 'https://my-api.com/authorize')] +:: [%send (add-auth-header [oauth-token+ouath-token.tok]~ req)] +:: :: +:: ++ res :: handle request token +:: =+ aut +:: |= res/httr ^- $%({{$redo $~} _..res} {$give httr}) +:: ?^ tok [%give a] +:: ?> =(%true (grab r.res 'oauth_callback_confirmed')) +:: =. tok [%request-token (grab-token-response res)] +:: [[%redo ~] ..res] +:: :: +:: ++ in :: exchange token +:: =+ aut +:: |= inp/quay ^- {$send hiss} +:: ?> (check-token-quay inp) +:: :- %send +:: (add-auth-header inp (exchange-token 'https://my-api.com/access_token')) +:: :: +:: ++ bak :: save token +:: =+ aut +:: |= bak/httr ^- $%({{$redo $~} _..bak} {$give httr}) +:: ?: (bad-response bak) [%give bak] +:: =. tok [%access-token (grab-token-response res)] +:: [[%redo ~] ..bak] +:: -- +:: diff --git a/lib/oauth2.hoon b/lib/oauth2.hoon index 99bb99b35b..c491d016f5 100644 --- a/lib/oauth2.hoon +++ b/lib/oauth2.hoon @@ -1,80 +1,47 @@ +:: OAuth 2.0 %authorization :: :::: /hoon/oauth2/lib :: +/+ hep-to-cab, interpolate |% -++ fass :: rewrite quay - |= a/quay - %+ turn a - |= {p/@t q/@t} ^+ +< - [(gsub '-' '_' p) q] -:: -++ gsub :: replace chars - |= {a/@t b/@t t/@t} - ^- @t - ?: =('' t) t - %+ mix (lsh 3 1 $(t (rsh 3 1 t))) - =+ c=(end 3 1 t) - ?:(=(a c) b c) -:: -++ join +++ parse-url parse-url:interpolate +++ join |= {a/cord b/(list cord)} ?~ b '' (rap 3 |-([i.b ?~(t.b ~ [a $(b t.b)])])) :: +++ post-quay + |= {a/purl b/quay} ^- hiss + =. b (quay:hep-to-cab b) + =- [a %post - ?~(b ~ (some (tact +:(tail:earn b))))] + (my content-type+['application/x-www-form-urlencoded']~ ~) +:: ++ mean-wall !. |= {a/term b/tape} ^+ !! =- (mean (flop `tang`[>a< -])) (turn (lore (crip b)) |=(c/cord leaf+(trip c))) :: -++ dbg-post `purl`[`hart`[| `6.000 [%& /localhost]] `pork``/testing `quay`/] ++ bad-response |=(a/@u ?:(=(2 (div a 100)) | ~&(bad-httr+a &))) ++ grab-json |* {a/httr b/fist:jo} ~| bad-json+r.a ~| (poja q:(need r.a)) (need (;~(biff poja b) q:(need r.a))) -:: -++ parse-url - |= a/$@(cord:purl purl) ^- purl - ?^ a a - ~| bad-url+a - (rash a auri:epur) -:: -++ interpolate-url - |= {a/$@(cord purl) b/(unit hart) c/(list (pair term knot))} - ^- purl - ?@ a $(a (parse-url a)) :: deal with cord - %_ a - p ?^(b u.b p.a) - q.q (interpolate-path q.q.a c) - == -:: -++ interpolate-path :: [/a/:b/c [%b 'foo']~] -> /a/foo/c - |= {a/path b/(list (pair term knot))} ^- path - ?~ a ?~(b ~ ~|(unused-values+b !!)) - =+ (rush i.a ;~(pfix col sym)) - ?~ - [i.a $(a t.a)] :: not interpolable - ?~ b ~|(no-value+u !!) - ?. =(u p.i.b) ~|(mismatch+[u p.i.b] !!) - [q.i.b $(a t.a, b t.b)] -- :: :::: :: |% ++ token ?($~ @t) -++ refresh {tok/token needed/@da pending/_`?`|} +++ refresh {tok/token expiry/@da pending/_`?`|} +++ both-tokens {token refresh} ++ keys cord:{cid/@t cis/@t} -++ core-move |*(a/* $^({sec-move _a} sec-move)) ::here's a change -- :: :::: :: -|= {dialog/$@(cord:purl purl) code-exchange/$@(cord:purl purl)} -=+ :+ state-usr=| - dialog-url=(parse-url dialog) - exchange-url=(parse-url code-exchange) -|_ {(bale keys) scope/(list cord)} +=+ state-usr=| +|_ {(bale keys) tok/token} ++ client-id cid:decode-keys ++ client-secret cis:decode-keys ++ decode-keys :: XX from bale w/ typed %jael @@ -89,55 +56,32 @@ {(trip redirect-uri)} """ :: -++ our-host .^(hart %e /(scot %p our)/host/fake) ++ auth-url + |= {scopes/(list @t) url/$@(@t purl)} ^- purl ~& [%oauth-warning "Make sure this urbit ". "is running on {(earn our-host `~ ~)}"] - ^- purl - %_ dialog-url - r - %+ welp r.dialog-url - %- fass - :~ state+?.(state-usr '' (pack usr /'')) - client-id+client-id - redirect-uri+redirect-uri - scope+(join ' ' scope) - == + %+ add-query:interpolate url + %- quay:hep-to-cab + :~ state+?.(state-usr '' (pack usr /'')) + client-id+client-id + redirect-uri+redirect-uri + scope+(join ' ' scopes) == :: +++ our-host .^(hart %e /(scot %p our)/host/fake) ++ redirect-uri %- crip %- earn - %^ interpolate-url 'https://our-host/~/ac/:domain/:user/in' + %^ interpolate 'https://our-host/~/ac/:domain/:user/in' `our-host :~ domain+(join '.' (flop dom)) user+?:(state-usr '_state' (scot %ta usr)) == :: :: -++ out-filtered - |= {tok/token aut/$-(hiss hiss)} - |= a/hiss ^- sec-move - ?~(tok [%show auth-url] [%send (aut a)]) -:: -++ out-quay - |= {nam/knot tok/token} - %+ out-filtered tok - |=(a/hiss %_(a r.p :_(r.p.a nam^`@t`tok))) -:: -++ out-math - |= ber/token - =+ hed=(cat 3 'Bearer ' `@t`ber) - %+ out-filtered ber - |= a/hiss ^+ a - :: =. p.a dbg-post - %_(a q.q (~(add ja q.q.a) %authorization hed)) -:: -++ toke-req - |= {grant-type/cord quy/quay} ^- {$send hiss} - :+ %send exchange-url - :+ %post (malt ~[content-type+~['application/x-www-form-urlencoded']]) - =- `(tact +:(tail:earn -)) - %- fass +++ request-token + |= {a/$@(@t purl) grant-type/cord quy/quay} ^- hiss + %+ post-quay (parse-url a) + %- quay:hep-to-cab %+ welp quy :~ client-id+client-id client-secret+client-secret @@ -145,60 +89,295 @@ grant-type+grant-type == :: -++ in-code - |= a/quay ^- sec-move - =+ code=~|(%no-code (~(got by (malt a)) %code)) - (toke-req 'authorization_code' code+code ~) +++ request-token-by-code + |=({a/$@(@t purl) b/@t} (request-token a 'authorization_code' code+b ~)) :: -++ token-type 'token_type'^(cu cass sa):jo -++ expires-in 'expires_in'^ni:jo -++ access-token 'access_token'^so:jo -++ refresh-token 'refresh_token'^so:jo -++ bak-save-access - |* {done/* handle/$-(cord:token *)} :: $+(token _done) - %- (bak-parse done access-token ~) - |=(tok/cord:token [[%redo ~] (handle tok)]) +++ grab-token + |= a/httr ^- axs/@t + (grab-json a (ot 'access_token'^so ~):jo) :: -++ bak-parse - |* {done/* parse/(pole {knot fist}:jo)} - |= handle/$-(_?~(parse ~ (need *(ot:jo parse))) (core-move done)) - |= a/httr ^- (core-move done) - ?: (bad-response p.a) - [%give a] - :: [%redo ~] :: handle 4xx? - (handle (grab-json a (ot:jo parse))) +++ grab-expiring-token + |= a/httr ^- {axs/@t exp/@u} + (grab-json a (ot 'access_token'^so 'expires_in'^ni ~):jo) :: -++ res-give |=(a/httr [%give a]) +++ grab-both-tokens + |= a/httr ^- {axs/@t exp/@u ref/@t} + (grab-json a (ot 'access_token'^so 'expires_in'^ni 'refresh_token'^so ~):jo) +:: +++ auth + ?~ tok ~|(%no-bearer-token !!) + |% + ++ header `cord`(cat 3 'Bearer ' `@t`tok) + ++ query `cord`tok + -- +:: +++ add-auth-header + |= request/{url/purl meth hed/math (unit octs)} + ^+ request + :: =. p.url.request [| `6.000 [%& /localhost]] :: for use with unix nc + ~& add-auth-header+(earn url.request) + request(hed (~(add ja hed.request) %authorization header:auth)) +:: +++ add-auth-query + |= {token-name/cord request/{url/purl meth math (unit octs)}} + ^+ request + :: =. p.url.request [| `6.000 [%& /localhost]] :: for use with unix nc + ~& add-auth-query+(earn url.request) + request(r.url [[token-name query:auth] r.url.request]) :: ++ re - |* cor/* :: XX redundant with *export, but type headaches - |_ {ref/refresh export/$-(refresh _cor)} - ++ out-fix-expired - |= default/$-(hiss sec-move) - ^- $-(hiss (core-move cor)) - ?~ tok.ref default - ?. (lth needed.ref (add now ~m59.s30)) - default - |= a/hiss - :_ (export ref(pending &)) - (toke-req 'refresh_token' refresh-token+tok.ref ~) + |_ ref/refresh + ++ needs-refresh ?~(tok.ref | is-expired) + ++ is-expired (lth expiry.ref (add now ~m5)) + ++ update + |= exp/@u ^+ ref + ref(pending |, expiry (add now (mul ~s1 exp))) :: - ++ res-handle-refreshed - |= {handle-access/_=>(cor |=(@t +>)) default/$-(httr sec-move)} - ^- $-(httr (core-move cor)) - ?. pending.ref default - %- (bak-parse cor expires-in access-token ~) - |= {exp/@u tok/axs/@t} ^- {sec-move _cor} - =. +>.handle-access - (export tok.ref (add now (mul ~s1 exp)) |) - [[%redo ~] (handle-access axs.tok)] + ++ update-if-needed + |= exchange-url/$@(@t purl) + ^- {(unit hiss) refresh} + ?~ tok.ref `ref + ?. is-expired `ref + :_ ref(pending &) + `(request-token exchange-url 'refresh_token' refresh-token+tok.ref ~) + -- +:: +:: expected semantics, to be copied and modified if anything doesn't work +++ standard + |* {done/* save/$-(token *)} + |% + ++ save ^-($-(token _done) ^save) :: shadow(type canary) + ++ core-move $^({sec-move _done} sec-move) :: stateful :: - ++ bak-save-tokens - |= handle-access/_=>(cor |=(@t +>)) - %- (bak-parse cor expires-in access-token refresh-token ~) - |= {exp/@u tok/{axs/@t ref/@t}} ^- {sec-move _cor} - =. +>.handle-access - (export ref.tok (add now (mul ~s1 exp)) |) - [[%redo ~] (handle-access axs.tok)] + :: Insert token into query string. expects: + :: ++ in (in-code-to-token 'http://...') :: handle callback + ++ out-add-query-param + |= {token-name/knot scopes/(list cord) dialog/$@(@t purl)} + :: + |= a/hiss ^- $%({$send hiss} {$show purl}) + ?~ tok [%show (auth-url scopes dialog)] + [%send (add-auth-query token-name a)] + :: + :: Add token as a header. expects: + :: ++ in (in-code-to-token 'http://...') :: handle callback + ++ out-add-header + |= {scopes/(list cord) dialog/$@(@t purl)} + :: + |= a/hiss ^- sec-move + ?~ tok [%show (auth-url scopes dialog)] + [%send (add-auth-header a)] + :: + :: Exchange code in query string for access token. expects: + :: ++ bak bak-save-token :: save access token + ++ in-code-to-token + |= exchange-url/$@(@t purl) + :: + |= a/quay ^- sec-move + =+ code=~|(%no-code (~(got by (malt a)) %code)) + [%send (request-token-by-code exchange-url code)] + :: + :: If an access token has been returned, save it + ++ bak-save-token + |= a/httr ^- core-move + ?: (bad-response p.a) + [%give a] :: [%redo ~] :: handle 4xx? + [[%redo ~] (save `token`(grab-token a))] + -- +:: +++ standard-refreshing + |* {done/* ref/refresh save/$-({token refresh} *)} + =+ s=(standard done |=(tok/token (save tok ref))) + |% + ++ save ^-($-(both-tokens _done) ^save) :: shadow(type canary) + ++ core-move $^({sec-move _done} sec-move) :: stateful + :: + :: See ++out-add-query-param:standard + :: Refresh token if we have an expired one, ask for authentication if none is present, + :: insert auth token into the query string if it's valid. expects: + :: ++ in (in-code-to-token 'http://...') :: handle callback + :: ++ res res-save-after-refresh + ++ out-refresh-or-add-query-param + |= {exchange/$@(@t purl) s-args/{knot (list cord) $@(@t purl)}} + :: + |= a/hiss ^- core-move + =^ upd ref (~(update-if-needed re ref) exchange) + ?^ upd [[%send u.upd] (save tok ref)] + %.(a (out-add-query-param.s s-args)) + :: + :: See ++out-add-header:standard + :: Refresh token if we have an expired one, ask for authentication if none is present, + :: add token as a header if it's valid. expects: + :: ++ in (in-code-to-token 'http://...') :: handle callback + :: ++ res res-save-after-refresh + ++ out-refresh-or-add-header + |= {exchange/$@(@t purl) s-args/{(list cord) dialog/$@(@t purl)}} + :: + |= a/hiss ^- core-move + =^ upd ref (~(update-if-needed re ref) exchange) + ?^ upd [[%send u.upd] (save tok ref)] + %.(a (out-add-header.s s-args)) + :: + :: If the last request refreshed the access token, save it. + ++ res-save-after-refresh + |= a/httr ^- core-move + ?. pending.ref [%give a] + =+ `{axs/token exp/@u}`(grab-expiring-token a) + =. ref (~(update re ref) exp) + [[%redo ~] (save axs ref)] + :: + :: Exchange code in query string for access and refresh tokens. expects: + :: ++ bak bak-save-both-tokens :: save access token + ++ in-code-to-token in-code-to-token.s + :: + :: If valid access and refresh tokens have been returned, save them + ++ bak-save-both-tokens + |= a/httr ^- core-move + =+ `{axs/token exp/@u ref-new/token}`(grab-both-tokens a) + =. tok.ref ref-new + =. ref (~(update re ref) exp) + [[%redo ~] (save axs ref)] -- -- +:: +:: XX move-me +:: +:: +:::: Example "standard" sec/ core: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth2 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +:: ++ out +:: %+ out-add-header:aut scope=/full +:: oauth-dialog='https://my-api.com/authorize' +:: :: +:: ++ in +:: %- in-code-to-token:aut +:: exchange-url='https://my-api.com/access_token' +:: :: +:: ++ bak bak-save-token:aut +:: -- +:: +:: +:::: Equivalent imperative code: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth2 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++ aut ~(. oauth2 bal tok) +:: ++ out :: add header +:: =+ aut +:: |= req/hiss ^- $%({$send hiss} {$show purl}) +:: ?~ tok +:: [%show (auth-url scope=/full 'https://my-api.com/authorize')] +:: [%send (add-auth-header req)] +:: :: +:: ++ in :: code to token +:: =+ aut +:: |= inp/quay ^- {$send hiss} +:: =+ code=~|(%no-code (~(got by (malt inp)) %code)) +:: [%send (request-token-by-code 'https://my-api.com/access_token' code)] +:: :: +:: ++ bak :: save token +:: =+ aut +:: |= bak/httr ^- $%({{$redo $~} _..bak} {$give httr}) +:: ?: (bad-response bak) [%give bak] +:: =. tok (grab-token bak) +:: [[%redo ~] ..bak] +:: -- +:: +::: ::: + ::::: :: +::: ::: +:: +:::: Example "standard-refreshing" sec/ core: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth2 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth2) tok/token:oauth2 ref/refresh:oauth2} +:: ++ aut +:: %^ ~(standard-refreshing oauth2 bal tok) . ref +:: |=({tok/token ref/refresh}:oauth2 +>(tok tok, ref ref)) +:: :: +:: ++ exchange-url 'https://my-api.com/access_token' +:: ++ out +:: %^ out-refresh-or-add-header:aut exchange-url +:: scope=/full +:: oauth-dialog='https://my-api.com/authorize' +:: :: +:: ++ res res-save-after-refresh:aut +:: ++ in (in-code-to-token:aut exchange-url) +:: ++ bak bak-save-both-tokens:aut +:: -- +:: +:: +:::: Equivalent imperative code: + :: +:: +:: :: +:: :::: /hoon/my-api/com/sec +:: :: +:: /+ oauth2 +:: :: +:: :::: +:: :: +:: |_ {bal/(bale keys:oauth2) axs/token:oauth2 ref/refresh:oauth2} +:: ++ aut ~(. oauth2 bal axs) +:: ++ exchange-url 'https://my-api.com/access_token' +:: ++ out :: refresh or add header +:: =+ aut +:: |= req/hiss ^- $^({{$send hiss} _..out} $%({$send hiss} {$show purl})) +:: ?~ axs +:: [%show (auth-url scope=/full 'https://my-api.com/authorize')] +:: =^ upd ref (~(update-if-needed re ref) exchange-url) +:: ?^ upd [[%send u.upd] ..out] +:: [%send (add-auth-header req)] +:: :: +:: ++ res :: save after refresh +:: =+ aut +:: |= a/httr ^- $^({{$redo $~} _..res} {$give httr}) +:: ?. pending.ref [%give a] +:: =+ `{axs/token exp/@u}`(grab-expiring-token a) +:: [[%redo ~] ..out(axs axs, ref (~(update re ref) exp))] +:: :: +:: ++ in :: exchange token +:: =+ aut +:: |= inp/quay ^- {$send hiss} +:: =+ code=~|(%no-code (~(got by (malt inp)) %code)) +:: [%send (request-token-by-code exchange-url code)] +:: +:: ++ bak :: save both tokens +:: =+ aut +:: |= a/httr ^- {{$redo $~} _..res} +:: =+ `{axs/token exp/@u ref-new/token}`(grab-both-tokens a) +:: =. tok.ref ref-new +:: [[%redo ~] ..bak(axs axs, ref (~(update re ref) exp))] +:: :: +:: :: +:: ++ bak +:: =+ aut +:: |= bak/httr ^- $%({{$redo $~} _..bak} {$give httr}) +:: ?: (bad-response bak) [%give bak] +:: =. tok (grab-token bak) +:: [[%redo ~] ..bak] +:: -- +:: diff --git a/lib/twitter.hoon b/lib/twitter.hoon index 3301092278..64b043590e 100644 --- a/lib/twitter.hoon +++ b/lib/twitter.hoon @@ -4,54 +4,18 @@ :: /? 314 /- twitter +/+ interpolate, hep-to-cab =+ sur-twit:^twitter :: XX !: :::: functions :: |% -++ fass :: rewrite path - |= a/path - %+ turn a - |=(b/@t (gsub '-' '_' b)) -:: -++ gsub :: replace chars - |= {a/@t b/@t t/@t} - ^- @t - ?: =('' t) t - %+ mix (lsh 3 1 $(t (rsh 3 1 t))) - =+ c=(end 3 1 t) - ?:(=(a c) b c) -:: ++ join |= {a/char b/(list @t)} ^- @t %+ rap 3 ?~ b ~ |-(?~(t.b b [i.b a $(b t.b)])) :: -++ interpolate-some :: [/a/:b/c [d+'bar' b+'foo']~] -> [/a/foo/c [d+'bar']~] - |= {pax/path quy/quay} ^- {path quay} - =+ ^= inline :: required names - %- ~(gas in *(set term)) - (murn pax replacable:interpolate-path) - =^ inter quy - (skid quy |=({a/knot @} (~(has in inline) a))) - [(interpolate-path pax inter) quy] -:: -++ interpolate-path :: [/a/:b/c [%b 'foo']~] -> /a/foo/c - =+ replacable=|=(a/knot `(unit term)`(rush a ;~(pfix col sym))) - |= {a/path b/(list (pair term knot))} ^- path - ?~ a ?~(b ~ ~|(unused-values+b !!)) - =+ (replacable i.a) - ?~ - [i.a $(a t.a)] :: literal value - ?~ b ~|(no-value+u !!) - ?. =(u p.i.b) ~|(mismatch+[u p.i.b] !!) - [q.i.b $(a t.a, b t.b)] -:: -++ interpolate-url :: XX friendlier url format #717 - |= {a/tape b/(list (pair term knot))} ^- purf - =+ url=`purf`(scan a aurf:epur) - url(q.q.p (interpolate-path q.q.p.url b)) -:: ++ valve :: produce request |= {med/?($get $post) pax/path quy/quay} ^- hiss @@ -87,17 +51,22 @@ :: ++ user-url |= a/scr ^- purf - (interpolate-url "https://twitter.com/:scr" scr+a ~) + :_ ~ + %^ into-url:interpolate 'https://twitter.com/:scr' + ~ + ~[scr+a] :: ++ post-url - |= {a/scr b/tid} ^- purf - %+ interpolate-url "https://twitter.com/:scr/status/:tid" + |= {a/scr b/tid} ^- purf + :_ ~ + %^ into-url:interpolate 'https://twitter.com/:scr/status/:tid' + ~ ~[scr+a tid+(tid:print b)] -- ++ parse :: json reparsers |% ++ ce |*({a/_* b/fist:jo} (cu:jo |=(c/a c) b)) :: output type - ++ fasp |*(a/{@tas *} [(gsub '-' '_' -.a) +.a]) :: XX usable electroplating + ++ fasp |*(a/{@tas *} [(hep-to-cab -.a) +.a]) :: XX usable electroplating ++ user (cook crip (plus ;~(pose aln cab))) ++ mean (ot errors+(ar (ot message+so code+ni ~)) ~):jo ++ post @@ -160,12 +129,13 @@ quy/quay == ^- {path quay} - %+ interpolate-some (fass pax) + %+ into-path-partial:interpolate + (path:hep-to-cab pax) =- (weld - quy) %+ turn ban |= p/param ^- {@t @t} - :- (gsub '-' '_' -.p) + :- (hep-to-cab -.p) ?+ -.p p.p :: usually plain text ?($source-id $target-id) (tid:print p.p) ?($id $name $user-id) (lid:print p.p) diff --git a/mar/gmail/req.hoon b/mar/gmail/req.hoon deleted file mode 100644 index d8d872ff13..0000000000 --- a/mar/gmail/req.hoon +++ /dev/null @@ -1,8 +0,0 @@ -/- rfc, gmail-label - -|_ {method/meth endpoint/path query/quay mes/?(message:rfc label-req:gmail-label)} :: jon=(unit json)] -++ grab - |% - ++ noun {method/meth endpoint/path query/quay mes/?(message:rfc label-req:gmail-label)}:: jon=(unit json)] - -- --- diff --git a/mar/json.hoon b/mar/json.hoon index 37ba530e34..c73b01fd5f 100644 --- a/mar/json.hoon +++ b/mar/json.hoon @@ -9,7 +9,7 @@ :: ++ grow :: convert to |% - ++ mime [/text/json (taco txt)] :: convert to %mime + ++ mime [/application/json (taco txt)] :: convert to %mime ++ txt (crip (pojo jon)) -- ++ grab diff --git a/mar/urb.hoon b/mar/urb.hoon index 602f3bed2f..f5bb65b2e5 100644 --- a/mar/urb.hoon +++ b/mar/urb.hoon @@ -10,7 +10,8 @@ urb.waspAll = function(sel){ [].map.call(document.querySelectorAll(sel), urb.waspElem) } - if(urb.wasp){urb.waspAll('script'); urb.waspAll('link')} + urb.waspAll('script'); urb.waspAll('link') + ''' ++ grow :: convert to |% @@ -21,18 +22,22 @@ ;html ;head ;meta(charset "utf-8", urb_injected ""); - ;* ?~ dep ~ - :~ ;script@"/~/on/{}.js"(urb_injected ""); - ;script(urb_injected "") - ;- (trip urb-wasp-data-js) - ;- "urb.waspData({(pojo %s (scot %uv dep-bod))})" - == - == ;* hed == ;body ;* bod - ;script(urb_injected ""):"{(trip linked-deps-js)}" + ;* ?~ dep ~ + :~ ;script@"/~/on/{}.js"(urb_injected "", async "", onload "setTimeout(urb.onDep,2000)"); + ;script(urb_injected "") + ;- (trip urb-wasp-data-js) + ; window.urb = window.urb || \{} + ; urb.onDep = function()\{ + ; urb.waspDeps(); + ; urb.waspData({(pojo %s (scot %uv dep-bod))}); + ;- (trip linked-deps-js) + ; } + == + == == == -- diff --git a/mar/urb/wasp-data.js b/mar/urb/wasp-data.js index b630f80080..5ff8f8bccf 100644 --- a/mar/urb/wasp-data.js +++ b/mar/urb/wasp-data.js @@ -1,7 +1,10 @@ // debugging urb.verb = false urb.sources = {} -urb.deps.map(function(a){urb.sources[a] = "dep"}) + +urb.waspDeps = function(){ + urb.deps.map(function(a){urb.sources[a] = "dep"}) +} urb.waspElem = function(ele){ url = ele.src || ele.href diff --git a/ren/tree/body.hoon b/ren/tree/body.hoon index 3161bbc7ee..506806c8df 100644 --- a/ren/tree/body.hoon +++ b/ren/tree/body.hoon @@ -3,7 +3,10 @@ :: /? 310 /= dat /% /tree-json/ :: default include +/= dat-sen /| /: /%%/ /% /tree-json/ :: default include + /~ ~ + == ^- marl -;= ;script(type "text/javascript"): window.tree = {(pojo (joba %data dat))} +;= ;script(type "text/javascript"): window.tree = {(pojo (jobe data+dat sein+dat-sen ~))} ;div#tree; == diff --git a/ren/tree/comments.hoon b/ren/tree/comments.hoon index a51fb6647f..c8b801554c 100644 --- a/ren/tree/comments.hoon +++ b/ren/tree/comments.hoon @@ -2,7 +2,7 @@ :::: /hoon/comments/tree/ren :: /? 310 -/: /%/comments /@ /&elem&/md/ :: XX descend horn +/: /%/comments /_ @da /&elem&/md/ :: :::: :: diff --git a/ren/tree/head.hoon b/ren/tree/head.hoon index fdbf6786c9..3b6a15c104 100644 --- a/ren/tree/head.hoon +++ b/ren/tree/head.hoon @@ -8,32 +8,57 @@ /$ %+ cork fuel :: after parsing params, |= gas/epic ^- ? :: check that the fcgi %+ lien (~(tap in (~(get ju aut.ced.gas) %$))) :: has an identity - |=(a/knot !=(%pawn (slav %p a))) :: which isn't a comet + |=(a/knot !=(%pawn (clan (slav %p a)))) :: which isn't a comet +/= dbg + /^ {nopack/? nomin/?} + /$ %+ cork fuel :: after parsing params, + |= gas/epic ^- {? ?} :: check if the query + :- (~(has by qix.gas) 'dbg.nopack') :: dictates separate files + (~(has by qix.gas) 'dbg.nomin') :: and/or unminified assets :: +|% +++ cdnjs + |=(a/tape "//cdnjs.cloudflare.com/ajax/libs/{a}{?:(nomin.dbg "" ".min")}.js") +++ maxcdn + |=(a/tape "//maxcdn.bootstrapcdn.com/{a}{?:(nomin.dbg "" ".min")}.js") +-- !: :::: :: ^- marl ;= ;title: Tree ;meta(name "viewport", content "width=device-width, initial-scale=1"); - ;link(type "text/css", rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.min.css"); - ;link(type "text/css", rel "stylesheet", href "/lib/css/fonts.css"); - ;link(type "text/css", rel "stylesheet", href "/lib/css/bootstrap.css"); - ;link(type "text/css", rel "stylesheet", href "/lib/css/codemirror.css"); - ;link(type "text/css", rel "stylesheet", href "/tree/main.css"); +:: ;link(type "text/css", rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.min.css"); + ;* ?. nopack.dbg + :_ ~ + ;link(type "text/css", rel "stylesheet", href "/=home=/web/tree/~.main_codemirror_fonts_bootstrap.css"); +:: ;link(type "text/css", rel "stylesheet", href "/=home=/web/tree/~.main_codemirror_bootstrap.css"); + ;= + ;link(type "text/css", rel "stylesheet", href "/=home=/web/lib/css/fonts.css"); + ;link(type "text/css", rel "stylesheet", href "/=home=/web/lib/css/bootstrap.css"); + ;link(type "text/css", rel "stylesheet", href "/=home=/web/lib/css/codemirror.css"); + ;link(type "text/css", rel "stylesheet", href "/=home=/web/tree/main.css"); + == ::;link(type "text/css", rel "stylesheet", href "http://localhost:8000/docs/pub/tree/main.css"); + ;script(type "text/javascript", src "{(cdnjs "jquery/2.1.3/jquery")}"); + ;script(type "text/javascript", src "{(maxcdn "bootstrap/3.3.6/js/bootstrap")}"); + ;script(type "text/javascript", src "{(cdnjs "lodash.js/2.4.1/lodash")}"); + ;script(type "text/javascript", src "{(cdnjs "react/0.14.6/react")}"); + ;script(type "text/javascript", src "{(cdnjs "react/0.14.6/react-dom")}"); + ;script(type "text/javascript", src "{(cdnjs "flux/2.1.1/Flux")}"); +:: ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"); +:: ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/". +:: "codemirror/4.3.0/mode/markdown/markdown.min.js"); + ;* ?. nopack.dbg + :_ ~ + ;script(type "text/javascript", src "{?.(aut "" "/~~")}". + "/~/at/=home=/web/tree/~.main_urb.js"); +:: "/~/at/=home=/web/tree/~.main_hoon_urb.js"); + ;= +:: ;script(type "text/javascript", src "/=home=/web/lib/js/hoon.js"); + ;script(type "text/javascript", src "/=home=/web/tree/main.js"); + ;script(type "text/javascript", src "{?.(aut "" "/~~")}". + "/~/at/=home=/web/lib/js/urb.js"); + == ;link(type "application/rss+xml", rel "alternate", href "{(spud tub)}.rss-xml"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/flux/2.1.1/Flux.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"); - ;script(type "text/javascript", src "/lib/js/urb.js"); - ;script(type "text/javascript", src "/lib/js/hoon.js"); - ;script(type "text/javascript", src "/tree/main.js"); - ;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/". - "codemirror/4.3.0/mode/markdown/markdown.min.js"); - ;script(type "text/javascript", src "{?.(aut "" "/~~")}". - "/~/at/lib/js/urb.js"); == diff --git a/ren/tree/json.hoon b/ren/tree/json.hoon index 0c97cb91dd..b0cbd97919 100644 --- a/ren/tree/json.hoon +++ b/ren/tree/json.hoon @@ -42,7 +42,7 @@ |= a/$%({$t p/cord} {$r p/json} {$j p/json} {$m mime}) ?- -.a $t [%s p.a] - $m (jobe mite+[%s (moon p.a)] octs+[%s q.q.a] ~) + $m (jobe mite+[%s (moon p.a)] octs+(jape (sifo q.q.a)) ~) $r p.a $j p.a == @@ -75,7 +75,7 @@ :: [tree .] ^- json -=+ default='spur.t_mime.m_body.r_comt.j_plan.j_beak.t_kids.name.t' +=+ default='spur.t_body.r_comt.j_plan.j_beak.t_meta.j_kids_meta.j_head.r' =+ ^= schem =+ seh=(fall (~(get by qix.gas) 'q') default) ~|(bad-noun+seh ;;(schema (rash seh read-schem))) diff --git a/sec/com/asana.hoon b/sec/com/asana.hoon new file mode 100644 index 0000000000..c84e3196bf --- /dev/null +++ b/sec/com/asana.hoon @@ -0,0 +1,41 @@ +:: Test url +https://app.asana.com/api/1.0/users/me +:: +:::: /hoon/asana/com/sec + :: +/+ oauth2 +:: +:::: + :: +|% +++ dialog-url 'https://app.asana.com/-/oauth_authorize?response_type=code' +++ exchange-url 'https://app.asana.com/-/oauth_token' +-- +:: +:::: + :: +|_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +++ filter-request (out-add-header:aut scope=~ dialog-url) +:: +++ receive-auth-query-string (in-code-to-token:aut exchange-url) +++ receive-auth-response bak-save-token:aut +-- +:: create a developer app by logging into https://app.asana.com/, and clicking +:: "My Profile Settings" > Apps > "Manage my developer apps" + +:: Be sure to be on https://localhost:8443 and to have registered +:: 'http://localhost:8443/~/ac/asana.com/~./in' as the redirect URI. +:: (If unable to change port number of ship, change the redirect URI port in %eyre) + +:: |init-oauth2 /com/asana + +:: Enter this sample command to get your user information: +:: +https://app.asana.com/api/1.0/users/me + +:: Before you receive the response, you'll have to clink on the link. +:: If you successfully auth, you should receive the response in the dojo. + + diff --git a/sec/com/digitalocean.hoon b/sec/com/digitalocean.hoon new file mode 100644 index 0000000000..e74252310d --- /dev/null +++ b/sec/com/digitalocean.hoon @@ -0,0 +1,40 @@ +:: Test url +https://api.digitalocean.com/v2/account +:: +:::: /hoon/digitalocean/com/sec + :: +/+ oauth2 +:: +:::: + :: +|% +++ dialog-url 'https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code' +++ exchange-url 'https://cloud.digitalocean.com/v1/oauth/token' +-- +:: +:::: + :: +|_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +++ filter-request (out-add-header:aut scope=~[%read %write] dialog-url) +:: +++ receive-auth-query-string (in-code-to-token:aut exchange-url) +++ receive-auth-response bak-save-token:aut +-- +:: create a developer app on https://cloud.digitalocean.com/settings/api/applications/new +:: to get a client id and secret + +:: Be sure to be on https://localhost:8443 and to have registered +:: 'http://localhost:8443/~/ac/digitalocean.com/~./in' as the redirect URI. +:: (If unable to change port number of ship, change the redirect URI port in %eyre) + +:: |init-oauth2 |init-oauth2 /com/digitalocean + +:: Enter home this sample command to get your user information: +:: +https://api.digitalocean.com/v2/account +:: Before you receive the response, you'll have to clink on the link. +:: If you successfully auth, you should receive the response in the dojo. + + diff --git a/sec/com/dropboxapi.hoon b/sec/com/dropboxapi.hoon new file mode 100644 index 0000000000..a1436ad3a7 --- /dev/null +++ b/sec/com/dropboxapi.hoon @@ -0,0 +1,41 @@ +:: Test url +https://api.dropboxapi.com/2/users/get_current_account &json ~ +:: +:::: /hoon/dropboxapi/com/sec + :: +/+ oauth2 +:: +:::: + :: +|% +++ dialog-url 'https://www.dropbox.com/1/oauth2/authorize?response_type=code' +++ exchange-url 'https://api.dropboxapi.com/1/oauth2/token' +-- +:: +:::: + :: +|_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +++ filter-request (out-add-header:aut scope=~ dialog-url) +:: +++ receive-auth-query-string (in-code-to-token:aut exchange-url) +++ receive-auth-response bak-save-token:aut +-- +:: create a developer app on https://www.dropbox.com/developers-v1/apps to get a +:: client id and secret. + +:: Be sure to be on https://localhost:8443 and to have registered +:: 'http://localhost:8443/~/ac/dropboxapi.com/~./in' as the redirect URI. +:: (If unable to change port number of ship, change the redirect URI port in %eyre) + +:: |init-oauth2 |init-oauth2 /com/dropbox + +:: Enter this sample command to show your user info: +:: +https://api.dropboxapi.com/2/users/get_current_account &json ~ + +:: Before you receive the response, you'll have to click on the link in the +:: dojo to authenticate yourself. + +:: You should receive a response listing the contents of that directory. diff --git a/sec/com/facebook.hoon b/sec/com/facebook.hoon index 4f12879558..6a3a19e8d2 100644 --- a/sec/com/facebook.hoon +++ b/sec/com/facebook.hoon @@ -6,21 +6,37 @@ :: :::: :: -=+ ^= aut - %+ oauth2 - dialog='https://www.facebook.com/dialog/oauth?response_type=code' - exchange='https://graph.facebook.com/v2.3/oauth/access_token' -|_ {bal/(bale keys.aut) access-token/token.aut} -++ auth ~(. aut bal /'user_about_me'/'user_posts') -++ out (out-quay:auth key='access_token' value=access-token) -++ in in-code:auth -++ bak - %- (bak-parse:auth . access-token.aut expires-in.aut ~) - |= {access-token/@t expires-in/@u} - ?: (lth expires-in ^~((div ~d7 ~s1))) :: short-lived token - %^ toke-req:auth grant-type='fb_exchange_token' - [key='fb_exchange_token' value=access-token] - ~ - [[%redo ~] ..bak(access-token access-token)] -::++ wyp ~ +|% +++ dialog-url 'https://www.facebook.com/dialog/oauth?response_type=code' +++ exchange-url 'https://graph.facebook.com/v2.3/oauth/access_token' +-- +:: +:::: + :: +|_ {bal/(bale keys:oauth2) access-token/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut + %+ ~(standard oauth2 bal access-token) . + |=(access-token/token:oauth2 +>(access-token access-token)) +:: +++ filter-request + %^ out-add-query-param:aut 'access_token' + scope=~['user_about_me' 'user_posts'] + dialog-url +:: +++ receive-auth-query-string (in-code-to-token:aut exchange-url) +:: +++ receive-auth-response + |= a/httr ^- core-move:aut + ?: (bad-response:aut p.a) + [%give a] :: [%redo ~] :: handle 4xx? + =+ `{access-token/@t expires-in/@u}`(grab-expiring-token:aut a) + ?. (lth expires-in ^~((div ~d7 ~s1))) :: short-lived token + [[%redo ~] ..bak(access-token access-token)] + :- %send + %^ request-token:aut exchange-url + grant-type='fb_exchange_token' + [key='fb_exchange_token' value=access-token]~ -- diff --git a/sec/com/github.hoon b/sec/com/github.hoon index c6d19453cd..72915a85fa 100644 --- a/sec/com/github.hoon +++ b/sec/com/github.hoon @@ -5,5 +5,6 @@ /+ basic-auth !: |_ {bal/(bale keys:basic-auth) $~} -++ out (basic-auth bal) +++ aut ~(standard basic-auth bal ~) +++ filter-request out-adding-header:aut -- diff --git a/sec/com/googleapis.hoon b/sec/com/googleapis.hoon index b4b53fc3e7..8e5af6d9d4 100644 --- a/sec/com/googleapis.hoon +++ b/sec/com/googleapis.hoon @@ -2,7 +2,7 @@ :: :::: /hoon/googleapis/com/sec :: -/+ oauth2 +/+ oauth2, interpolate, hep-to-cab :: :::: :: @@ -18,40 +18,38 @@ ++ auth-usr |= usr/iden =+ lon=(fall (slaw %t usr) usr) - =< .(state-usr &) - %- oauth2 - :_ exchange='https://www.googleapis.com/oauth2/v4/token' - ^= dialog - %* . (need (epur 'https://accounts.google.com/o/oauth2/v2/auth')) - r - %- fass:oauth2 - :~ login-hint+?~(lon '' (crip (rash lon suffix-email))) - access-type+%offline - response-type+%code - prompt+%consent - == + %+ add-query:interpolate 'https://accounts.google.com/o/oauth2/v2/auth' + %- quay:hep-to-cab + :~ login-hint+?~(lon '' (crip (rash lon suffix-email))) + access-type+%offline + response-type+%code + prompt+%consent == --- -!: -:::: - :: -|_ {bal/(bale keys:oauth2) user-state} -++ auth-re ~(. (re:auth .) ref |=(a/_ref +>(ref a))) -++ auth ~(. (auth-usr usr.bal) bal scopes) ++ scopes :~ 'https://mail.google.com' 'https://www.googleapis.com/auth/plus.me' 'https://www.googleapis.com/auth/userinfo.email' == :: -++ out (out-fix-expired:auth-re (out-math:auth ber)) -++ res |=(a/httr ((res-handle-refreshed:auth-re save-access res-give:auth) a)) -:: -++ save-access |=(a/cord:[token:oauth2] +>(ber a)) -:: -++ in - |= a/quay - (in-code:auth a) -++ bak |=(a/httr ((bak-save-tokens:auth-re save-access) a)) -++ upd *user-state +++ exchange-url 'https://www.googleapis.com/oauth2/v4/token' +-- +!: +:::: + :: +|_ {bal/(bale keys:oauth2) own/user-state} +:: ++auth is a "standard refreshing oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ auth + =+ a=~(standard-refreshing oauth2 bal ber.own) + (a(state-usr &) ..auth ref.own |=(a/user-state ..auth(own a))) +:: +++ filter-request (out-refresh-or-add-header:auth exchange-url scopes dialog-url) +++ dialog-url (auth-usr usr.bal) +:: +++ filter-response res-save-after-refresh:auth +:: +++ receive-auth-query-string (in-code-to-token:auth exchange-url) +++ receive-auth-response bak-save-both-tokens:auth +:: ++ update *user-state -- diff --git a/sec/com/instagram.hoon b/sec/com/instagram.hoon new file mode 100644 index 0000000000..4a52764aba --- /dev/null +++ b/sec/com/instagram.hoon @@ -0,0 +1,42 @@ +:: Test url +https://api.instagram.com/v1/users/self +:: +:::: /hoon/instagram/com/sec + :: +/+ oauth2 +:: +:::: + :: +|% +++ dialog-url 'https://api.instagram.com/oauth/authorize?response_type=code' +++ exchange-url 'https://api.instagram.com/oauth/access_token' +-- +:: +:::: + :: +|_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +++ filter-request + %^ out-add-query-param:aut 'access_token' + scope=~[%basic] + dialog-url +:: +++ receive-auth-query-string (in-code-to-token:aut exchange-url) +++ receive-auth-response bak-save-token:aut +-- +:: create a developer app on https://www.instagram.com/developer/ to get a +:: client id and secret + +:: Be sure to be on https://localhost:8443, and to have registered +:: http://localhost:8443/~/ac/instagram.com/~./in as the redirect URI. +:: (If unable to change port number of ship, change the redirect URI port in %eyre) +:: |init-oauth2 |init-oauth2 /com/instagram + +:: Enter this sample command to get your user information: +:: +https://api.instagram.com/v1/users/self + +:: Before you receive the response, you'll have to clink on the link to +:: authenicate yourself. You should then receive the response. + diff --git a/sec/com/slack.hoon b/sec/com/slack.hoon index b30af8fe45..766f272dfa 100644 --- a/sec/com/slack.hoon +++ b/sec/com/slack.hoon @@ -6,13 +6,16 @@ :: :::: :: -=+ ^= aut - %+ oauth2 - 'https://slack.com/oauth/authorize' - 'https://slack.com/api/oauth.access' -|_ {(bale keys:oauth2) tok/token.aut} -++ aut ~(. ^aut +<- /client/admin) -++ out (out-quay:aut 'token'^tok) -++ in in-code:aut -++ bak (bak-save-access:aut . |=(tok/token:aut +>(tok tok))) +|_ {bal/(bale keys:oauth2) tok/token:oauth2} +:: ++aut is a "standard oauth2" core, which implements the +:: most common handling of oauth2 semantics. see lib/oauth2 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth2 bal tok) . |=(tok/token:oauth2 +>(tok tok))) +++ filter-request + %^ out-add-query-param:aut 'token' + scope=~[%client %admin] + oauth-dialog='https://slack.com/oauth/authorize' +:: +++ receive-auth-query-string (in-code-to-token:aut url='https://slack.com/api/oauth.access') +++ receive-auth-response bak-save-token:aut -- diff --git a/sec/com/twitter.hoon b/sec/com/twitter.hoon index 19102d4861..cca9ce65ab 100644 --- a/sec/com/twitter.hoon +++ b/sec/com/twitter.hoon @@ -1,22 +1,27 @@ :: Test url +https://api.twitter.com/1.1/account/verify_credentials.json -:: +:: :::: /hoon/twitter/com/sec :: /+ oauth1 !: :::: :: -=+ ^= aut - %^ oauth1 - 'https://api.twitter.com/oauth/request_token' - 'https://api.twitter.com/oauth/authorize' - 'https://api.twitter.com/oauth/access_token' -|_ {(bale keys:oauth1) tok/token:oauth1} -++ aut ~(. ^aut . +<- +<+) :: XX electroplating -++ out out-math:aut -++ in in-oauth-token:aut -++ bak (bak-save-access:aut save-token) -++ res (res-handle-reqt:aut save-token) -++ save-token |=(tok/token:aut +>(tok tok)) -::++ wyp ~ +|_ {bal/(bale keys:oauth1) tok/token:oauth1} +:: ++aut is a "standard oauth1" core, which implements the +:: most common handling of oauth1 semantics. see lib/oauth1 for more details, +:: and examples at the bottom of the file. +++ aut (~(standard oauth1 bal tok) . |=(tok/token:oauth1 +>(tok tok))) +++ filter-request + %+ out-add-header:aut + token-request='https://api.twitter.com/oauth/request_token' + oauth-dialog='https://api.twitter.com/oauth/authorize' +:: +++ filter-response res-handle-request-token:aut +:: +++ receive-auth-query-string + %- in-exchange-token:aut + exchange-url='https://api.twitter.com/oauth/access_token' +:: +++ receive-auth-response bak-save-token:aut +:: ++ discard-state ~ -- diff --git a/sur/gmail-label.hoon b/sur/gmail-label.hoon deleted file mode 100644 index 9e6a9a30c7..0000000000 --- a/sur/gmail-label.hoon +++ /dev/null @@ -1,34 +0,0 @@ -:: This structure is the hoon equivalent of the labels resource used by the -:: gmail api - - -|% -++ label-list-visibility - $? $'labelHide' :: Do not show the label in the label list - $'labelShow' :: Show the label in the label list. (Default) - $'labelShowIfUnread' :: Show the label if any unread msgs w/that label. - == -++ message-list-visibility - $? $hide :: Do not show the label in the message list. - $show :: Show the label in the message list. (Default) - == --- - -|% -:: label request is the body of the post request you send to gmail to create -:: a labels resource -++ label-req {llv/label-list-visibility mlv/message-list-visibility name/@t} - -:: the label resource returned by gmail in response to your successful request -++ label * - -++ label-req-to-json - |= label-req - %- jobe :^ - ['name' `json`s+name] - ['labelListVisibility' `json`s+(crip (sifo `cord`llv))] - ['messageListVisibility' `json`s+(crip (sifo `cord`mlv))] - ~ --- - - diff --git a/sur/gmail-message.hoon b/sur/gmail-message.hoon deleted file mode 100644 index 810b4c03c7..0000000000 --- a/sur/gmail-message.hoon +++ /dev/null @@ -1 +0,0 @@ -{to/@p subj/@t body/wain} diff --git a/web/tree/~.main_codemirror_fonts_bootstrap.css b/web/tree/~.main_codemirror_fonts_bootstrap.css new file mode 100644 index 0000000000..7acb8b76b4 --- /dev/null +++ b/web/tree/~.main_codemirror_fonts_bootstrap.css @@ -0,0 +1,7707 @@ +@charset "UTF-8"; +.col-md-10.body { + padding-left: 0; } + +@media (max-width: 767px) { + .col-md-10.body { + margin-top: 0.9375rem; + padding-left: 0.9375rem; } } + +img.logo { + height: 2rem; + width: 2rem; } + +img.logo.first { + margin-bottom: 2rem; } + +div.logo { + width: 4rem; + height: 4rem; + background-color: #000; + display: inline-block; + margin-right: 1rem; + border-radius: 50%; + vertical-align: middle; + margin-top: -.8rem; } + +div.logo:before { + content: "~"; + color: #FFFFFF; + font-size: 4rem; + vertical-align: middle; + line-height: 3rem; + margin-top: .2rem; + text-align: center; + width: 2rem; + display: inline-block; + font-weight: 200; } + +div.logo.inverse:before { + color: #fff; } + +.lead .logo.inverse { + margin-top: -1.4rem; } + +.short { + width: 75%; } + +.meta-data { + padding: 1rem; + background-color: #f7f7f9; + font-family: 'scp'; + max-width: 12rem; + margin-bottom: 2rem; } + .meta-data h2, + .meta-data h3 { + padding: 0; + margin: 0; + font-size: 1rem; + line-height: 2rem; } + +.link-next { + margin-top: 4rem; } + .link-next a { + padding: .6rem; + border: 2px solid; + text-decoration: none; + font-weight: 500; + margin-top: 4rem; } + .link-next a:hover { + background-color: #000; + color: #fff; } + +.loading:before { + font-family: 'scp'; + background-color: #000; + color: #fff; + padding: 0; + margin: 0; + width: 1.6rem; + height: 1.6rem; + text-align: center; + font-size: .8rem; + line-height: 1.7rem; + display: block; + font-weight: 600; + z-index: 3; } + +.loading.state-0:before { + content: "\25D3"; } + +.loading.state-1:before { + content: "\25D1"; } + +.loading.state-2:before { + content: "\25D2"; } + +.loading.state-3:before { + content: "\25D0"; } + +@media (min-width: 768px) { + .ctrl { + width: 180px; } + .ctrl.open, + .ctrl:hover { + max-width: 360px; + min-width: 180px; + width: auto; } } + +@media (min-width: 992px) { + .ctrl { + width: 235px; } + .ctrl.open, + .ctrl:hover { + max-width: 470px; + min-width: 235px; + width: auto; } } + +@media (min-width: 1200px) { + .ctrl { + width: 285px; } + .ctrl.open, + .ctrl:hover { + max-width: 570px; + min-width: 285px; + width: auto; } } + +#head .loading { + display: none; } + +@media (max-width: 543px) { + #head { + top: 0; + z-index: 10; + width: 100%; + position: absolute; } + #head.m-down, + #head.m-up { + position: absolute; } + #head.m-down.m-fixed { + position: fixed; } } + +@media (max-width: 543px) { + .nav.container { + left: 0; } } + +.menu .contents { + padding-top: 3rem; } + +.ctrl { + padding-left: 0; + padding-right: 0; + background-color: #fff; + transition: max-width .2s ease-in-out; + position: fixed; + height: 100%; + z-index: 100; } + .ctrl ul.nav { + margin-top: 2rem; + overflow-x: hidden; + overflow-y: scroll; + height: 100%; } + .ctrl ul.nav li { + width: 100%; + overflow: hidden; + white-space: nowrap; + margin-bottom: .6rem; } + .ctrl ul.nav:hover { + overflow-x: visible; } + .ctrl a.nav-link { + letter-spacing: 1px; + text-decoration: none; + border-bottom: 2px solid; + line-height: 1rem; } + .ctrl .selected a.nav-link { + font-weight: 500; } + +.ctrl.navbar { + position: relative; + margin-bottom: 3rem; + padding: 0; + background-color: transparent; + width: auto; } + .ctrl.navbar, + .ctrl.navbar .items { + height: 3rem; } + .ctrl.navbar .icon, + .ctrl.navbar ul.nav, + .ctrl.navbar li { + display: inline-block; + padding: 0; } + .ctrl.navbar ul.nav { + margin-top: 0; + overflow: visible; } + .ctrl.navbar ul.nav li { + width: auto; + display: inline-block; + min-width: 16.66667%; } + .ctrl.navbar ul.nav .right { + float: right; } + .ctrl.navbar ul.nav .btn { + margin: 0; + padding: 0; + border: 0; + text-transform: none; } + +.ctrl.navbar.open, +.ctrl.navbar:hover { + max-width: none; + min-width: none; } + +@media (max-width: 991px) { + ul.nav { + line-height: 1.3rem; } + a.nav-link { + font-size: .8rem; } } + +@media (max-width: 767px) { + .ctrl { + position: relative; + max-height: 3rem; + max-width: 100%; + padding-top: 1rem; + background-color: #fff; + overflow: hidden; + border-bottom: 2px solid #B1B7BD; + -webkit-transition: max-height 0.2s ease-in-out; + -moz-transition: max-height 0.2s ease-in-out; + transition: max-height 0.2s ease-in-out; } + .ctrl ul.nav { + line-height: 2rem; + margin: 0 0 2rem 0.9375rem; } + .ctrl.open, + .ctrl:hover { + width: inherit; + max-width: inherit; } + .ctrl.open { + height: auto; + max-height: 12rem; + min-height: 3rem; } + a.nav-link { + font-size: 1rem; + line-height: 1rem; + text-decoration: none; + border-bottom: 2px solid; } + .ctrl.open ul.nav { + max-height: 9rem; + overflow-y: scroll; } } + +.navbar-toggler { + font-size: 24px; + transition: opacity .2s, transform .3s, margin-left .2s; + -webkit-transition: opacity .2s, transform .3s, margin-left .2s; } + +.open .navbar-toggler { + transform: rotate(0.25turn); + opacity: .2; + margin-left: -.2rem; } + +.items { + height: 80%; } + +@media (min-width: 768px) { + .ctrl .navbar-toggler { + display: none; } + .ctrl .navbar-toggler.show { + display: block; + padding: 0; } } + +@media (max-width: 767px) { + .navbar-toggler { + padding: 0; + margin-left: 2rem; + vertical-align: top; + line-height: 18px; } + .open .navbar-toggler { + margin-left: 2rem; } } + +.icon div, .icon a { + display: inline-block; } + +.icon a { + margin-right: .6rem; } + +.icon .home { + margin: 0 0.9375rem 0.9375rem 0; + width: 24px; + height: 24px; + border-radius: 50%; + background-color: transparent; + border: 6px solid #B1B7BD; + cursor: pointer; } + +.icon .home:hover { + border-color: #55595c; } + +.icon .dpad { + display: block; } + +.icon .up { + width: 1px; + height: 1px; + border: 12.0006px solid transparent; + border-bottom: 18px solid #000; + border-top: 0 solid transparent; } + +.icon .prev { + width: 1px; + height: 1px; + border: 12.0006px solid transparent; + border-right: 18px solid #000; + border-left: 0 solid transparent; } + +.icon .next { + width: 1px; + height: 1px; + border: 12.0006px solid transparent; + border-left: 18px solid #000; + border-right: 0 solid transparent; + margin-right: 0; } + +@media (max-width: 991px) { + .icon .home { + width: 18px; + height: 18px; + border-radius: 50%; + background-color: transparent; + border-width: 4px; } + .icon .up { + width: 1px; + height: 1px; + border: 8.0004px solid transparent; + border-bottom: 12px solid #000; + border-top: 0 solid transparent; + margin-left: 1px; } + .icon .prev { + width: 1px; + height: 1px; + border: 8.0004px solid transparent; + border-right: 12px solid #000; + border-left: 0 solid transparent; + margin-right: .6rem; } + .icon .next { + width: 1px; + height: 1px; + border: 8.0004px solid transparent; + border-left: 12px solid #000; + border-right: 0 solid transparent; } } + +@media (max-width: 767px) { + .icon { + margin-left: 0.9375rem; + height: 2rem; } + .icon .dpad { + display: inline; } + .icon .home { + margin-top: 0; + margin-bottom: 0; } } + +[data-path*='/docs'] .selected .nav-link, +[data-path^='/work'] .selected .nav-link { + color: #55595c; } + +[data-path*='/docs'] .nav-link, +[data-path^='/work'] .nav-link { + font-weight: 500; } + +[data-path*='/docs'] .home, +[data-path^='/work'] .home { + background-color: #55595c; + border-color: #55595c; } + +[data-path*='/docs'] .home:hover, +[data-path^='/work'] .home:hover { + background-color: #B1B7BD; + border-color: #B1B7BD; + opacity: .6; } + +[data-path*='/docs'] .home:before, +[data-path^='/work'] .home:before { + content: "~"; + color: #fff; + line-height: .8rem; + font-size: 1.4rem; } + +@media (max-width: 991px) { + [data-path*='/docs'] .home:before, + [data-path^='/work'] .home:before { + line-height: 0.7rem; + font-size: 1rem; + margin-left: .06rem; } } + +@media (max-width: 767px) { + [data-path*='/docs'] .home:before, + [data-path^='/work'] .home:before { + line-height: .7rem; + margin-left: .05rem; + font-size: 1rem; } } + +[data-path^='/docs/system/hoon/runes'] .nav-link { + font-family: 'scp'; } + +[data-path^='/docs/system/hoon/runes'] .nav-link, +[data-path^='/docs/system/hoon/runes'] .ctrl .selected a.nav-link { + font-weight: 600; } + +.app { + vertical-align: top; + font-size: 1.6rem; + font-weight: 500; + line-height: 1.6rem; + margin-top: 0; } + +@media (max-width: 991px) { + .app { + font-size: 1.3rem; + line-height: 1.3rem; } } + +@media (max-width: 767px) { + .app { + margin-top: .1rem; + line-height: 1rem; } } + +.context { + margin-top: 1rem; } + .context .name { + font-weight: 300; + font-size: 1.2rem; + font-family: 'scp'; } + +@media (max-width: 991px) { + .context .name { + font-size: 1rem; } } + +@media (max-width: 767px) { + .context { + line-height: 1rem; + margin-bottom: 1rem; } } + +.urbit.navbar.ctrl { + margin-top: 1rem; } + .urbit.navbar.ctrl .icon .home { + border-color: #B1B7BD; + background-color: #B1B7BD; + width: 3rem; + height: 3rem; + margin: 0 4rem 0 0; } + .urbit.navbar.ctrl .icon .home:before { + content: "~"; + color: #fff; + font-size: 2.6rem; + line-height: 2.6rem; + text-align: center; + width: 2.4rem; + display: inline-block; } + .urbit.navbar.ctrl ul.nav li { + height: 3rem; + vertical-align: middle; + min-width: 0; + margin-right: 2rem; } + .urbit.navbar.ctrl ul.nav li a { + text-decoration: none; + color: #000; + font-weight: 500; + font-size: 1rem; + border-bottom: 3px solid #000; + margin-top: 1rem; } + .urbit.navbar.ctrl ul.nav .btn { + border: 3px solid #000; + margin-top: -3px; + height: 3rem; + padding: 0rem; } + .urbit.navbar.ctrl ul.nav .btn a { + font-size: 1rem; + color: #000; + letter-spacing: 0; } + .urbit.navbar.ctrl ul.nav .btn.selected, + .urbit.navbar.ctrl ul.nav .btn:hover { + background-color: #000; } + .urbit.navbar.ctrl ul.nav .btn.selected a, + .urbit.navbar.ctrl ul.nav .btn:hover a { + color: #fff; } + .urbit.navbar.ctrl ul.nav li a:hover, + .urbit.navbar.ctrl ul.nav li.selected a { + color: #55595c; + border-color: #55595c; } + .urbit.navbar.ctrl .subnav ul.nav { + height: 1.5rem; } + .urbit.navbar.ctrl .subnav ul.nav li { + height: 1.5rem; } + .urbit.navbar.ctrl .subnav ul.nav li a { + line-height: 1.5rem; } + .urbit.navbar.ctrl .subnav ul.nav .btn { + position: relative; + height: 3rem; } + .urbit.navbar.ctrl .subnav ul.nav .btn a { + line-height: 3rem; } + +.urbit.home.navbar.ctrl .icon .home { + opacity: 0; + border-color: #fff; + background-color: #fff; } + +.urbit.home.navbar.ctrl .icon .home:before { + color: #B1B7BD; } + +.urbit.home.navbar.ctrl ul li a { + color: #fff; + border-color: #fff; } + +@media (max-width: 767px) { + .urbit.home.navbar.ctrl .icon .home { + display: none; } + .urbit.navbar.ctrl { + height: auto; + margin: 0; + position: absolute; + border: none; } + .urbit.navbar.ctrl .icon { + margin-top: 1rem; + margin-bottom: .5rem; } + .urbit.navbar.ctrl .icon .home { + width: 18px; + height: 18px; + margin: 0 1rem 0 0; } + .urbit.navbar.ctrl .icon .home:before { + font-size: 1rem; + line-height: .7rem; + width: .6rem; } + .urbit.navbar.ctrl .icon .navbar-toggler { + margin-left: 0; } + .urbit.navbar.ctrl .icon .navbar-toggler, + .urbit.navbar.ctrl .icon .open .navbar-toggler { + opacity: 1; } + .urbit.navbar.ctrl ul.nav, + .urbit.navbar.ctrl .subnav ul.nav { + overflow: visible; + background-color: #fff; + height: auto; + margin-left: -1rem; + padding-left: 1rem; + padding-top: .8rem; + float: left; } + .urbit.navbar.ctrl ul.nav li, + .urbit.navbar.ctrl .subnav ul.nav li { + display: block; + height: 1.5rem; } + .urbit.navbar.ctrl ul.nav li a, + .urbit.navbar.ctrl .subnav ul.nav li a { + line-height: 1.5rem; + margin-top: 0; + color: #000; } + .urbit.navbar.ctrl ul.nav li.btn, + .urbit.navbar.ctrl .subnav ul.nav li.btn { + height: 1.5rem; + border: 0; } + .urbit.navbar.ctrl ul.nav li.btn a, + .urbit.navbar.ctrl .subnav ul.nav li.btn a { + color: #64DE79; + line-height: 1.5rem; } } + +#tree > div > .container { + padding-top: 3rem; + padding-bottom: 6rem; } + +@media (max-width: 767px) { + #tree > div > .container { + padding-top: 0; } + #body { + padding-top: 4rem; } } + +.lead h1:first-of-type { + padding-bottom: 0; } + +.flush { + padding-top: 0; } + +.h-arrow { + width: 100%; + height: 9rem; + margin-bottom: 3rem; } + .h-arrow h1, + .h-arrow img { + float: left; } + .h-arrow img { + height: 6rem; + margin: 1rem 0 0 1rem; } + .h-arrow h1 { + color: #000; + display: inline-block; + line-height: 4rem; } + .h-arrow h1 code { + background-color: transparent; + color: #000; } + +.footer { + margin-top: 6rem; + font-weight: 500; + color: #B1B7BD; } + .footer a { + color: #55595c; + text-decoration: none; + border-bottom: 2px solid #55595c; + margin-left: .6rem; } + +ol { + counter-reset: li; + list-style: none; + padding-left: 2rem; } + +ol > li { + margin-bottom: 2rem; } + +.top ol { + padding-left: 0; } + +ol > li:before { + content: counter(li) "."; + counter-increment: li; + text-align: left; + font-weight: 500; + float: left; + margin-right: 1rem; + margin-left: -2rem; } + +.body[data-path*='/docs'] h1, +.body[data-path^='/work'] h1 { + color: #000; } + +.body[data-path*='/docs'] h1 code, +.body[data-path^='/work'] h1 code { + background-color: transparent; + color: #000; + padding: 0; } + +.body[data-path*='/docs'] .book h2, +.body[data-path^='/work'] .book h2 { + color: #B1B7BD; } + +.body[data-path*='/docs'] .book h2 code, +.body[data-path^='/work'] .book h2 code { + color: #000; + background-color: transparent; } + +.body[data-path*='/docs'] .book h2 a, +.body[data-path^='/work'] .book h2 a { + color: #000; } + +.body[data-path*='/docs'] .book hr, +.body[data-path^='/work'] .book hr { + margin-bottom: 3rem; } + +.body[data-path^='/work'] h2 { + color: #000; } + +.body[data-path^='/docs/system/hoon/runes/'] h1 { + color: #B1B7BD; } + +.body[data-path^='/docs/system/hoon/runes/basic'] h1 { + color: #000; } + +.body[data-path^='/docs/system/hoon/library/'] h3 { + font-size: 1.5rem; } + +.body[data-path^='/docs/system/hoon/library/'] h2 { + font-size: 1rem; } + +.body[data-path^='/docs/system/hoon/library/'] .toc h3 { + padding-top: 0; + margin-bottom: 0; } + +.body .urbit { + padding-bottom: 9rem; } + .body .urbit .logo { + background-color: transparent; + border: .3rem solid #fff; } + .body .urbit .logo:before { + line-height: 3.4rem; } + .body .urbit h1 { + color: #000; + line-height: 4rem; } + .body .urbit a.green:hover { + color: #64DE79; } + .body .urbit .container.stack { + margin-bottom: 3rem; } + .body .urbit .container.stack p { + font-size: 1.2rem; + line-height: 2rem; } + .body .urbit .container.stack.six { + margin-top: 12rem; + margin-bottom: 6rem; } + .body .urbit .btn.black { + text-transform: none; + text-decoration: none; + border: 3px solid #000; + letter-spacing: 0; + margin: 0 1rem 1rem 0; } + .body .urbit button.submit:hover, + .body .urbit .btn.black:hover { + background-color: #000; + color: #fff; } + .body .urbit .front { + padding-bottom: 4rem; } + .body .urbit .front h1 { + padding-top: 0; } + .body .urbit .front h1, + .body .urbit .front h1 a { + font-size: 4rem; + line-height: 6rem; } + .body .urbit .image-fs { + height: 44rem; + margin-bottom: 3rem; } + .body .urbit .image-fs .text-container, + .body .urbit .image-fs .image-container { + position: absolute; } + .body .urbit .image-fs .text-container { + display: table; + height: 44rem; + width: 100%; + z-index: 1; } + .body .urbit .image-fs .text-container .text { + display: table-cell; + vertical-align: middle; } + .body .urbit .image-fs .text-container .rect { + margin-left: auto; + margin-right: auto; } + .body .urbit .image-fs .text-container .rect h1 { + padding-bottom: 1rem; + text-align: left; } + @media (min-width: 544px) { + .body .urbit .image-fs .text-container .rect { + width: 480px; } } + @media (min-width: 768px) { + .body .urbit .image-fs .text-container .rect { + width: 600px; } } + @media (min-width: 992px) { + .body .urbit .image-fs .text-container .rect { + width: 783.33333px; } } + @media (min-width: 1200px) { + .body .urbit .image-fs .text-container .rect { + width: 950px; } } + .body .urbit .image-fs .text-container .rect { + padding: 0 30px 0 30px; } + .body .urbit .image-fs .text-container .rect.no-header { + font-weight: 500; + color: #fff; + font-size: 1.4rem; } + .body .urbit .image-fs .text-container .rect.no-header p.email { + font-size: 1rem; } + .body .urbit .image-fs .image-container { + z-index: 0; + height: 44rem; + width: 100%; + overflow: hidden; + background-repeat: no-repeat; + background-position: center center; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; } + .body .urbit .image-fs h1 { + text-align: center; + color: #fff; } + .body .urbit .image-fs.first { + margin-top: -9rem; } + .body .urbit .image-fs.first h1 { + padding-bottom: 0; } + .body .urbit .slide { + margin-bottom: 12rem; + position: relative; } + .body .urbit .slide h1 { + padding-bottom: 1rem; } + .body .urbit .slide .pair { + display: table; } + .body .urbit .slide .pair .text, + .body .urbit .slide .pair .image { + display: table-cell; + vertical-align: middle; } + .body .urbit .slide .pair .image.right { + padding-left: 5%; } + .body .urbit .slide .pair .image.left { + padding-right: 5%; } + .body .urbit .slide .pair .text { + width: 75%; } + .body .urbit .slide .pair .image { + width: 20%; } + .body .urbit .slide .pair p:last-child { + margin-bottom: 0; } + .body .urbit .end { + padding: 1rem; + background-color: #64DE79; + color: white; + text-decoration: none; + font-size: 2rem; + font-weight: 500; } + .body .urbit input.email { + font-weight: 500; + background-color: #000; + color: #fff; + font-size: 1rem; + margin-right: 1rem; + border: 3px solid #000; + padding: .375rem 1rem; + margin: 0 1rem 0 0; + line-height: 1.6rem; + vertical-align: top; + margin-bottom: .6rem; } + .body .urbit input.email::-moz-placeholder { + color: #D2D2D2; } + .body .urbit input.email::-webkit-input-placeholder { + color: #D2D2D2; } + .body .urbit button.submit { + text-transform: none; + text-decoration: none; + background-color: #000000; + color: #fff; + font-weight: 500; + letter-spacing: 0; } + .body .urbit .last a { + display: block; + font-weight: 500; + color: #55595c; + line-height: 2rem; } + .body .urbit .last h2 { + padding-top: 0; + padding-bottom: 1rem; + margin-bottom: 0; } + .body .urbit .fade-out { + background: -webkit-linear-gradient(top, rgba(153, 153, 153, 0) 0%, white 100%); + background: linear-gradient(to bottom, rgba(153, 153, 153, 0) 0%, white 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00999999', endColorstr='#ffffff',GradientType=0 ); + margin-top: -14rem; + position: absolute; + height: 12rem; + width: 100%; } + .body .urbit .grams { + margin: 2rem 0; } + .body .urbit .grams .gram label { + background-color: #000; } + .body .urbit .grams .gram .speech { + font-size: 1.6rem; } + .body .urbit .grams .gram .iden, + .body .urbit .grams .gram .path { + max-width: 12rem; + white-space: nowrap; + overflow: hidden; + vertical-align: middle; } + +@media (max-width: 767px) { + .body .urbit .slide .pair, + .body .urbit .slide .pair .text, + .body .urbit .slide .pair .image { + display: block; + width: 100%; } + .body .urbit .slide .pair .image { + text-align: center; } + .body .urbit .slide .pair .image.left { + margin-bottom: 2rem; } + .body .urbit .slide .pair .image.right { + margin-top: 2rem; } + .body .urbit .last .col-md-4 { + margin-top: 2rem; } + .body .urbit .last .col-md-4.col-md-offset-1 { + margin-top: 0; } } + +@media (max-width: 767px) { + #body.plan { + padding-top: 0; } } + +.body .plan .above { + background-color: #000; } + .body .plan .above .mono, + .body .plan .above h6 { + font-size: 1.2rem; } + .body .plan .above h6 { + padding-top: 0; } + .body .plan .above .mono { + font-weight: 200; } + .body .plan .above > .container { + padding-top: 6rem; + padding-bottom: 6rem; } + .body .plan .above .home { + border-radius: 50%; + height: 2.4rem; + width: 2.4rem; + border: 4px solid #fff; + display: inline-block; + float: left; + margin-left: -4.4rem; + margin-top: 1rem; } + .body .plan .above .edit { + background-color: transparent; + border: 0; + padding: 0; + font-weight: 500; + border-bottom: 3px solid #fff; + line-height: 1rem; + padding-top: 2rem; } + .body .plan .above .grid .tr .td { + font-family: 'scp'; } + .body .plan .above .grid .tr .td:first-child { + font-family: 'bau'; } + .body .plan .above input { + background-color: #373a3c; + border: none; } + .body .plan .above .panel a { + text-decoration: none; + border-bottom: 2px solid #55595c; + font-weight: 500; + color: #55595c; } + .body .plan .above .panel a:hover { + border-color: #fff; + color: #fff; } + +.body .plan .panel.stack { + padding-top: 0; + padding-bottom: 0; } + +.body .plan .plan.stack { + padding-top: 4rem; } + +.body .plan .pull-right { + float: right; } + +.body .plan .above, +.body .plan .above a { + color: #fff; } + +.body .plan .service { + white-space: nowrap; } + +.body .plan .service:before { + content: " "; + display: inline-block; + border-radius: 50%; + height: .5rem; + width: .5rem; + background-color: #64DE79; + margin-right: .6rem; } + +.body .plan .grid .td { + display: table-cell; } + +.body .plan .grid .tr .td:first-child { + min-width: 9rem; + margin-right: 2rem; + letter-spacing: 1px; + color: #B1B7BD; } + +.stream .mini-module { + margin-top: 3rem; } + +.stream h6 { + color: #55595c; + font-size: 1rem; + margin-bottom: 2rem; } + +@media (max-width: 767px) { + .grid .td { + display: block; } + .tr .td:first-child { + margin-top: 1rem; } } + +@keyframes menu-open { + 0% { + visibility: hidden; } + 1% { + visibility: visible; } + 100% { + visibility: visible; } } + +@keyframes menu-close { + 0% { + visibility: visible; } + 1% { + visibility: visible; } + 100% { + visibility: hidden; } } + +.menu { + padding-left: 0; + padding-right: 0; + position: fixed; + overflow: hidden; + z-index: 101; + margin-top: -3rem; } + .menu .contents { + padding-left: 0.9375rem; + padding-right: 0.9375rem; + padding-bottom: 6rem; + position: relative; + left: -100%; + -webkit-transition: left 0.3s ease-in-out; + -moz-transition: left 0.3s ease-in-out; + transition: left 0.3s ease-in-out; } + .menu .close { + margin-top: -2rem; } + .menu .close:hover { + opacity: 1; } + .menu h2 { + font-size: 1rem; + padding-top: 3rem; } + .menu h2:first-of-type { + padding-top: 0; } + .menu label.sum { + font-family: 'scp'; + margin-left: 0.9375rem; + font-size: 1.2rem; } + +.menu.depth-1 .contents { + background-color: #f7f7f9; + border-left: 2px solid #B1B7BD; } + +.menu.depth-2 .contents { + background-color: #eceeef; + border-left: 2px solid #B1B7BD; } + +.menu.closed { + animation-name: menu-close; + animation-duration: .3s; + animation-fill-mode: forwards; } + +.menu.open { + animation-name: menu-open; + animation-duration: .3s; + animation-fill-mode: forwards; } + +.menu.open .contents { + left: 0; } + +@media (max-width: 767px) { + .menu { + height: 100%; + padding-left: 0; + padding-right: 2.8125rem; + border-left: 0; } + .menu .contents { + left: inherit; + top: -100%; + padding-top: 0.9375rem; + padding-bottom: 2.8125rem; + -webkit-transition: top 0.3s ease-in-out; + -moz-transition: top 0.3s ease-in-out; + transition: top 0.3s ease-in-out; } + .menu.depth-1 .contents, + .menu.depth-2 .contents { + border-left: 0; + border-bottom: 2px solid #B1B7BD; } + .menu .close { + margin-top: 0; } + .menu.open .contents { + top: 3rem; } } + +.list h1, +.list h1:first-of-type { + font-size: inherit; + font-weight: inherit; + padding-bottom: 0; + margin-bottom: 0; + line-height: 2rem; } + +.list h1.error { + font-size: 1.6rem; + font-weight: 500; } + +.list.children h1 { + font-weight: 500; + font-size: 1.4rem; } + +.list.post .date { + font-family: 'scp'; + font-size: .7rem; + margin-bottom: .6rem; } + +.list.post .author { + font-size: 1rem; + padding-top: 0; } + +.list.post .author:before { + content: "—"; + margin-right: .6rem; } + +.body[data-path*='/docs'] .list, +.body[data-path^='/work'] .list { + list-style-type: none; + padding-left: 0; } + .body[data-path*='/docs'] .list a, + .body[data-path*='/docs'] .list h1, + .body[data-path^='/work'] .list a, + .body[data-path^='/work'] .list h1 { + color: #55595c; + font-weight: 500; + height: 2rem; + display: inline; + text-decoration: none; } + .body[data-path*='/docs'] .list h1, + .body[data-path^='/work'] .list h1 { + border-bottom: 2px solid #000; } + +.body[data-path^='/work'] .list.main a, +.body[data-path^='/work'] .list.main h1 { + font-size: 2rem; + line-height: 4rem; + height: 4rem; } + +.body[data-path^='/work'] .list.main h1 { + border-width: 4px; } + +.body[data-path*='/docs'] .list.runes a h1, +.body[data-path*='/docs'] .list.runes a div, +.body[data-path*='/docs'] .list.runes a p { + display: inline-block; } + +.body[data-path*='/docs'] .list.runes a p { + font-weight: 300; } + +.body[data-path*='/docs'] .list.runes a { + text-decoration: none; } + +.body[data-path*='/docs'] .list.runes a, +.body[data-path*='/docs'] .list.runes a h1 code { + color: #000; } + +.body[data-path*='/docs'] .list.runes a h1 { + display: block; + margin-bottom: .3rem; + height: auto; + border-bottom: none; } + +.body[data-path*='/docs'] .list.runes a h1 code { + background-color: transparent; + font-weight: 500; + font-size: 1.2rem; + padding: 0; + border-bottom: 2px solid #000; } + +.body[data-path*='/docs'] .list.runes a code { + background-color: #eceeef; } + +.body[data-path*='/docs'] .list.runes a code { + padding: .3rem; } + +.urbit ul.blog { + list-style-type: none; + padding-left: 0; } + .urbit ul.blog li { + margin-bottom: 12rem; } + .urbit ul.blog .continue { + font-weight: 500; + text-decoration: none; + border-bottom: 3px solid #000; } + +@media (max-width: 767px) { + .urbit ul.blog li { + margin-bottom: 6rem; } } + +.kids.runes h1 { + padding-top: 3rem; } + +.kids.runes h2 { + font-size: 1.5rem; + margin-bottom: 1rem; } + +.kids.runes > div { + margin-top: 6rem; } + +.kids.runes > hr { + display: none; } + +.kids.runes > div p:first-of-type { + font-weight: 500; } + +#body.post .date { + font-family: 'scp'; + color: #B1B7BD; + font-size: .7rem; + font-weight: 200; } + +#body.post .date, +#body.post p.preview, +#body.post h3.author { + margin-bottom: .6rem; } + +#body.post h3.author { + padding-top: 0; + font-size: 1rem; + font-weight: 200; } + +#body.post h3.author:before { + content: "—"; + margin-right: .6rem; } + +.urbit .post h1.title, +.urbit .post p.preview, +.urbit.post h1.title, +.urbit.post p.preview { + font-weight: 500; } + +.urbit .post h1.title, +.urbit.post h1.title { + font-size: 2rem; + padding-bottom: 0; } + +.urbit .post h1.title, +.urbit .post img, +.urbit.post h1.title, +.urbit.post img { + width: 100%; + margin-bottom: 2rem; } + +.urbit .post img, +.urbit.post img { + border: 12px solid #000; } + +.urbit.post .preview { + max-width: 75%; } + +.sections h1 { + font-size: 2rem; + color: #0500F0; } + +.sections h1:first-of-type { + padding-bottom: 0; } + +.sections li h1 { + font-size: 1.2rem; } + +.sections ul { + list-style-type: none; + font-weight: 500; + padding-left: 0; } + +.sections ul li, +.sections ul li a, +.sections ul li h1 span { + color: #55595c; + margin-bottom: 1rem; + line-height: 1.5rem; } + +.sections .kids > div { + display: inline-block; + vertical-align: top; + margin-bottom: 3rem; + float: none; } + +.sections .kids > div p { + font-weight: 500; } + +.sections hr { + display: none; } + +.lead-offset { + margin-left: 4rem; } + +@media (max-width: 991px) { + .lead-offset { + margin-left: 4rem; } } + +@media (max-width: 767px) { + .lead-offset { + margin-left: 0; } + .sections h1 { + font-size: 1.6rem; } } + +.add-comment { + width: 100%; + border-top: 3px dotted #f7f7f9; + margin-top: 6rem; } + .add-comment .btn { + font-size: .8rem; } + .add-comment textarea { + width: 66%; + display: block; + height: 12rem; + background-color: #f7f7f9; + border-bottom: 0; + margin-bottom: 2rem; + margin-top: 3rem; + padding: .3rem; } + +.comments { + padding-top: 3rem; } + .comments .comment { + margin-top: 2rem; } + .comments .comment > span { + font-family: 'scp'; + font-size: .8rem; + color: #B1B7BD; } + .comments .comment h2 { + padding-top: 0; + font-size: 1rem; + font-weight: 500; } + .comments .comment h2 code { + background-color: transparent; + padding: 0; } + .comments .comment p { + width: 66%; } + +@media (max-width: 767px) { + .add-comment textarea, + .comments .comment p { + width: 100%; } } +.CodeMirror { + height: 100% +} +.cm-s-default .cm-atom {color: #70f} +.cm-s-default .cm-operator {color: #097} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau.woff"); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff"); + font-weight: 400; + font-style: italic; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff"); + font-weight: 500; + font-style: normal; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff"); + font-weight: 500; + font-style: italic; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff"); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff"); + font-weight: 600; + font-style: italic; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-super.woff"); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: "bau"; + src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff"); + font-weight: 600; + font-style: italic; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff"); + font-weight: 200; + font-style: normal; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-light.woff"); + font-weight: 300; + font-style: normal; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff"); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff"); + font-weight: 500; + font-style: normal; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-bold.woff"); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: "scp"; + src: url("//storage.googleapis.com/urbit-extra/scp-black.woff"); + font-weight: 700; + font-style: normal; +}/*! + * Bootstrap v4.0.0-alpha.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +[hidden], +template { + display: none; +} + +a { + background-color: transparent; +} + +a:active { + outline: 0; +} + +a:hover { + outline: 0; +} + +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +h1 { + margin: .67em 0; + font-size: 2em; +} + +mark { + color: #000; + background: #ff0; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -.5em; +} + +sub { + bottom: -.25em; +} + +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +figure { + margin: 1em 40px; +} + +hr { + height: 0; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} + +pre { + overflow: auto; +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} + +button { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +input { + line-height: normal; +} + +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} + +legend { + padding: 0; + border: 0; +} + +textarea { + overflow: auto; +} + +optgroup { + font-weight: bold; +} + +table { + border-spacing: 0; + border-collapse: collapse; +} + +td, +th { + padding: 0; +} + +@media print { + *, + *::before, + *::after { + text-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + abbr[title]::after { + content: " (" attr(title) ")"; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} + +html { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +*, +*::before, +*::after { + -webkit-box-sizing: inherit; + box-sizing: inherit; +} + +@-moz-viewport { + width: device-width; +} + +@-ms-viewport { + width: device-width; +} + +@-webkit-viewport { + width: device-width; +} + +@viewport { + width: device-width; +} + +html { + font-size: 18px; + + -webkit-tap-highlight-color: transparent; +} + +body { + font-family: "bau", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 1rem; + line-height: 1.5; + color: #373a3c; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: none !important; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #b1b7bd; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: bold; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +a { + color: #000; + text-decoration: underline; +} + +a:focus, a:hover { + color: #000; + text-decoration: underline; +} + +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; +} + +[role="button"] { + cursor: pointer; +} + +a, +area, +button, +[role="button"], +input, +label, +select, +summary, +textarea { + -ms-touch-action: manipulation; + touch-action: manipulation; +} + +table { + background-color: transparent; +} + +caption { + padding-top: .75rem; + padding-bottom: .75rem; + color: #b1b7bd; + text-align: left; + caption-side: bottom; +} + +th { + text-align: left; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +textarea { + margin: 0; + line-height: inherit; + border-radius: 0; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; +} + +input[type="search"] { + -webkit-box-sizing: inherit; + box-sizing: inherit; + -webkit-appearance: none; +} + +output { + display: inline-block; +} + +[hidden] { + display: none !important; +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: .5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +h1 { + font-size: 2.5rem; +} + +h2 { + font-size: 2rem; +} + +h3 { + font-size: 1.5rem; +} + +h4 { + font-size: 1.5rem; +} + +h5 { + font-size: 1rem; +} + +h6 { + font-size: 1rem; +} + +.h1 { + font-size: 2.5rem; +} + +.h2 { + font-size: 2rem; +} + +.h3 { + font-size: 1.5rem; +} + +.h4 { + font-size: 1.5rem; +} + +.h5 { + font-size: 1rem; +} + +.h6 { + font-size: 1rem; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: 6rem; + font-weight: 300; +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, .1); +} + +small, +.small { + font-size: 80%; + font-weight: normal; +} + +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} + +.list-inline-item:not(:last-child) { + margin-right: 5px; +} + +.dl-horizontal { + margin-right: -1.875rem; + margin-left: -1.875rem; +} + +.dl-horizontal::after { + display: table; + clear: both; + content: ""; +} + +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +.blockquote { + padding: .5rem 1rem; + margin-bottom: 1rem; + font-size: 1.25rem; + border-left: .25rem solid #eceeef; +} + +.blockquote-footer { + display: block; + font-size: 80%; + line-height: 1.5; + color: #b1b7bd; +} + +.blockquote-footer::before { + content: "\2014 \00A0"; +} + +.blockquote-reverse { + padding-right: 1rem; + padding-left: 0; + text-align: right; + border-right: .25rem solid #eceeef; + border-left: 0; +} + +.blockquote-reverse .blockquote-footer::before { + content: ""; +} + +.blockquote-reverse .blockquote-footer::after { + content: "\00A0 \2014"; +} + +.img-fluid, .carousel-inner > .carousel-item > img, +.carousel-inner > .carousel-item > a > img { + display: block; + max-width: 100%; + height: auto; +} + +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: .25rem; + line-height: 1.5; + background-color: #fff; + border: 1px solid #ddd; + border-radius: .25rem; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} + +.img-circle { + border-radius: 50%; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1; +} + +.figure-caption { + font-size: 90%; + color: #b1b7bd; +} + +code, +kbd, +pre, +samp { + font-family: "scp", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +code { + padding: .2rem .4rem; + font-size: 90%; + color: #2f2f2f; + background-color: #f7f7f7; +} + +kbd { + padding: .2rem .4rem; + font-size: 90%; + color: #fff; + background-color: #333; +} + +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + font-size: 90%; + line-height: 1.5; + color: #373a3c; +} + +pre code { + padding: 0; + font-size: inherit; + color: inherit; + background-color: transparent; + border-radius: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + padding-right: .9375rem; + padding-left: .9375rem; + margin-right: auto; + margin-left: auto; +} + +.container::after { + display: table; + clear: both; + content: ""; +} + +@media (min-width: 544px) { + .container { + max-width: 576px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container { + max-width: 940px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + padding-right: .9375rem; + padding-left: .9375rem; + margin-right: auto; + margin-left: auto; +} + +.container-fluid::after { + display: table; + clear: both; + content: ""; +} + +.row { + margin-right: -.9375rem; + margin-left: -.9375rem; +} + +.row::after { + display: table; + clear: both; + content: ""; +} + +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + position: relative; + min-height: 1px; + padding-right: .9375rem; + padding-left: .9375rem; +} + +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} + +.col-xs-1 { + width: 8.333333%; +} + +.col-xs-2 { + width: 16.666667%; +} + +.col-xs-3 { + width: 25%; +} + +.col-xs-4 { + width: 33.333333%; +} + +.col-xs-5 { + width: 41.666667%; +} + +.col-xs-6 { + width: 50%; +} + +.col-xs-7 { + width: 58.333333%; +} + +.col-xs-8 { + width: 66.666667%; +} + +.col-xs-9 { + width: 75%; +} + +.col-xs-10 { + width: 83.333333%; +} + +.col-xs-11 { + width: 91.666667%; +} + +.col-xs-12 { + width: 100%; +} + +.col-xs-pull-0 { + right: auto; +} + +.col-xs-pull-1 { + right: 8.333333%; +} + +.col-xs-pull-2 { + right: 16.666667%; +} + +.col-xs-pull-3 { + right: 25%; +} + +.col-xs-pull-4 { + right: 33.333333%; +} + +.col-xs-pull-5 { + right: 41.666667%; +} + +.col-xs-pull-6 { + right: 50%; +} + +.col-xs-pull-7 { + right: 58.333333%; +} + +.col-xs-pull-8 { + right: 66.666667%; +} + +.col-xs-pull-9 { + right: 75%; +} + +.col-xs-pull-10 { + right: 83.333333%; +} + +.col-xs-pull-11 { + right: 91.666667%; +} + +.col-xs-pull-12 { + right: 100%; +} + +.col-xs-push-0 { + left: auto; +} + +.col-xs-push-1 { + left: 8.333333%; +} + +.col-xs-push-2 { + left: 16.666667%; +} + +.col-xs-push-3 { + left: 25%; +} + +.col-xs-push-4 { + left: 33.333333%; +} + +.col-xs-push-5 { + left: 41.666667%; +} + +.col-xs-push-6 { + left: 50%; +} + +.col-xs-push-7 { + left: 58.333333%; +} + +.col-xs-push-8 { + left: 66.666667%; +} + +.col-xs-push-9 { + left: 75%; +} + +.col-xs-push-10 { + left: 83.333333%; +} + +.col-xs-push-11 { + left: 91.666667%; +} + +.col-xs-push-12 { + left: 100%; +} + +.col-xs-offset-0 { + margin-left: 0; +} + +.col-xs-offset-1 { + margin-left: 8.333333%; +} + +.col-xs-offset-2 { + margin-left: 16.666667%; +} + +.col-xs-offset-3 { + margin-left: 25%; +} + +.col-xs-offset-4 { + margin-left: 33.333333%; +} + +.col-xs-offset-5 { + margin-left: 41.666667%; +} + +.col-xs-offset-6 { + margin-left: 50%; +} + +.col-xs-offset-7 { + margin-left: 58.333333%; +} + +.col-xs-offset-8 { + margin-left: 66.666667%; +} + +.col-xs-offset-9 { + margin-left: 75%; +} + +.col-xs-offset-10 { + margin-left: 83.333333%; +} + +.col-xs-offset-11 { + margin-left: 91.666667%; +} + +.col-xs-offset-12 { + margin-left: 100%; +} + +@media (min-width: 544px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-1 { + width: 8.333333%; + } + .col-sm-2 { + width: 16.666667%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-4 { + width: 33.333333%; + } + .col-sm-5 { + width: 41.666667%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-7 { + width: 58.333333%; + } + .col-sm-8 { + width: 66.666667%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-10 { + width: 83.333333%; + } + .col-sm-11 { + width: 91.666667%; + } + .col-sm-12 { + width: 100%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-pull-1 { + right: 8.333333%; + } + .col-sm-pull-2 { + right: 16.666667%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-4 { + right: 33.333333%; + } + .col-sm-pull-5 { + right: 41.666667%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-7 { + right: 58.333333%; + } + .col-sm-pull-8 { + right: 66.666667%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-10 { + right: 83.333333%; + } + .col-sm-pull-11 { + right: 91.666667%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-push-1 { + left: 8.333333%; + } + .col-sm-push-2 { + left: 16.666667%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-4 { + left: 33.333333%; + } + .col-sm-push-5 { + left: 41.666667%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-7 { + left: 58.333333%; + } + .col-sm-push-8 { + left: 66.666667%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-10 { + left: 83.333333%; + } + .col-sm-push-11 { + left: 91.666667%; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-offset-0 { + margin-left: 0; + } + .col-sm-offset-1 { + margin-left: 8.333333%; + } + .col-sm-offset-2 { + margin-left: 16.666667%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-4 { + margin-left: 33.333333%; + } + .col-sm-offset-5 { + margin-left: 41.666667%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-7 { + margin-left: 58.333333%; + } + .col-sm-offset-8 { + margin-left: 66.666667%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-10 { + margin-left: 83.333333%; + } + .col-sm-offset-11 { + margin-left: 91.666667%; + } + .col-sm-offset-12 { + margin-left: 100%; + } +} + +@media (min-width: 768px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-1 { + width: 8.333333%; + } + .col-md-2 { + width: 16.666667%; + } + .col-md-3 { + width: 25%; + } + .col-md-4 { + width: 33.333333%; + } + .col-md-5 { + width: 41.666667%; + } + .col-md-6 { + width: 50%; + } + .col-md-7 { + width: 58.333333%; + } + .col-md-8 { + width: 66.666667%; + } + .col-md-9 { + width: 75%; + } + .col-md-10 { + width: 83.333333%; + } + .col-md-11 { + width: 91.666667%; + } + .col-md-12 { + width: 100%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-pull-1 { + right: 8.333333%; + } + .col-md-pull-2 { + right: 16.666667%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-4 { + right: 33.333333%; + } + .col-md-pull-5 { + right: 41.666667%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-7 { + right: 58.333333%; + } + .col-md-pull-8 { + right: 66.666667%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-10 { + right: 83.333333%; + } + .col-md-pull-11 { + right: 91.666667%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-push-0 { + left: auto; + } + .col-md-push-1 { + left: 8.333333%; + } + .col-md-push-2 { + left: 16.666667%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-4 { + left: 33.333333%; + } + .col-md-push-5 { + left: 41.666667%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-7 { + left: 58.333333%; + } + .col-md-push-8 { + left: 66.666667%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-10 { + left: 83.333333%; + } + .col-md-push-11 { + left: 91.666667%; + } + .col-md-push-12 { + left: 100%; + } + .col-md-offset-0 { + margin-left: 0; + } + .col-md-offset-1 { + margin-left: 8.333333%; + } + .col-md-offset-2 { + margin-left: 16.666667%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-4 { + margin-left: 33.333333%; + } + .col-md-offset-5 { + margin-left: 41.666667%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-7 { + margin-left: 58.333333%; + } + .col-md-offset-8 { + margin-left: 66.666667%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-10 { + margin-left: 83.333333%; + } + .col-md-offset-11 { + margin-left: 91.666667%; + } + .col-md-offset-12 { + margin-left: 100%; + } +} + +@media (min-width: 992px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-1 { + width: 8.333333%; + } + .col-lg-2 { + width: 16.666667%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-4 { + width: 33.333333%; + } + .col-lg-5 { + width: 41.666667%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-7 { + width: 58.333333%; + } + .col-lg-8 { + width: 66.666667%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-10 { + width: 83.333333%; + } + .col-lg-11 { + width: 91.666667%; + } + .col-lg-12 { + width: 100%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-pull-1 { + right: 8.333333%; + } + .col-lg-pull-2 { + right: 16.666667%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-4 { + right: 33.333333%; + } + .col-lg-pull-5 { + right: 41.666667%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-7 { + right: 58.333333%; + } + .col-lg-pull-8 { + right: 66.666667%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-10 { + right: 83.333333%; + } + .col-lg-pull-11 { + right: 91.666667%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-push-1 { + left: 8.333333%; + } + .col-lg-push-2 { + left: 16.666667%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-4 { + left: 33.333333%; + } + .col-lg-push-5 { + left: 41.666667%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-7 { + left: 58.333333%; + } + .col-lg-push-8 { + left: 66.666667%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-10 { + left: 83.333333%; + } + .col-lg-push-11 { + left: 91.666667%; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-offset-0 { + margin-left: 0; + } + .col-lg-offset-1 { + margin-left: 8.333333%; + } + .col-lg-offset-2 { + margin-left: 16.666667%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-4 { + margin-left: 33.333333%; + } + .col-lg-offset-5 { + margin-left: 41.666667%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-7 { + margin-left: 58.333333%; + } + .col-lg-offset-8 { + margin-left: 66.666667%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-10 { + margin-left: 83.333333%; + } + .col-lg-offset-11 { + margin-left: 91.666667%; + } + .col-lg-offset-12 { + margin-left: 100%; + } +} + +@media (min-width: 1200px) { + .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + float: left; + } + .col-xl-1 { + width: 8.333333%; + } + .col-xl-2 { + width: 16.666667%; + } + .col-xl-3 { + width: 25%; + } + .col-xl-4 { + width: 33.333333%; + } + .col-xl-5 { + width: 41.666667%; + } + .col-xl-6 { + width: 50%; + } + .col-xl-7 { + width: 58.333333%; + } + .col-xl-8 { + width: 66.666667%; + } + .col-xl-9 { + width: 75%; + } + .col-xl-10 { + width: 83.333333%; + } + .col-xl-11 { + width: 91.666667%; + } + .col-xl-12 { + width: 100%; + } + .col-xl-pull-0 { + right: auto; + } + .col-xl-pull-1 { + right: 8.333333%; + } + .col-xl-pull-2 { + right: 16.666667%; + } + .col-xl-pull-3 { + right: 25%; + } + .col-xl-pull-4 { + right: 33.333333%; + } + .col-xl-pull-5 { + right: 41.666667%; + } + .col-xl-pull-6 { + right: 50%; + } + .col-xl-pull-7 { + right: 58.333333%; + } + .col-xl-pull-8 { + right: 66.666667%; + } + .col-xl-pull-9 { + right: 75%; + } + .col-xl-pull-10 { + right: 83.333333%; + } + .col-xl-pull-11 { + right: 91.666667%; + } + .col-xl-pull-12 { + right: 100%; + } + .col-xl-push-0 { + left: auto; + } + .col-xl-push-1 { + left: 8.333333%; + } + .col-xl-push-2 { + left: 16.666667%; + } + .col-xl-push-3 { + left: 25%; + } + .col-xl-push-4 { + left: 33.333333%; + } + .col-xl-push-5 { + left: 41.666667%; + } + .col-xl-push-6 { + left: 50%; + } + .col-xl-push-7 { + left: 58.333333%; + } + .col-xl-push-8 { + left: 66.666667%; + } + .col-xl-push-9 { + left: 75%; + } + .col-xl-push-10 { + left: 83.333333%; + } + .col-xl-push-11 { + left: 91.666667%; + } + .col-xl-push-12 { + left: 100%; + } + .col-xl-offset-0 { + margin-left: 0; + } + .col-xl-offset-1 { + margin-left: 8.333333%; + } + .col-xl-offset-2 { + margin-left: 16.666667%; + } + .col-xl-offset-3 { + margin-left: 25%; + } + .col-xl-offset-4 { + margin-left: 33.333333%; + } + .col-xl-offset-5 { + margin-left: 41.666667%; + } + .col-xl-offset-6 { + margin-left: 50%; + } + .col-xl-offset-7 { + margin-left: 58.333333%; + } + .col-xl-offset-8 { + margin-left: 66.666667%; + } + .col-xl-offset-9 { + margin-left: 75%; + } + .col-xl-offset-10 { + margin-left: 83.333333%; + } + .col-xl-offset-11 { + margin-left: 91.666667%; + } + .col-xl-offset-12 { + margin-left: 100%; + } +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; +} + +.table th, +.table td { + padding: .75rem; + line-height: 1.5; + vertical-align: top; + border-top: 1px solid #eceeef; +} + +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #eceeef; +} + +.table tbody + tbody { + border-top: 2px solid #eceeef; +} + +.table .table { + background-color: #fff; +} + +.table-sm th, +.table-sm td { + padding: .3rem; +} + +.table-bordered { + border: 1px solid #eceeef; +} + +.table-bordered th, +.table-bordered td { + border: 1px solid #eceeef; +} + +.table-bordered thead th, +.table-bordered thead td { + border-bottom-width: 2px; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover { + background-color: #f5f5f5; +} + +.table-active, +.table-active > th, +.table-active > td { + background-color: #f5f5f5; +} + +.table-hover .table-active:hover { + background-color: #e8e8e8; +} + +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: #e8e8e8; +} + +.table-success, +.table-success > th, +.table-success > td { + background-color: #dff0d8; +} + +.table-hover .table-success:hover { + background-color: #d0e9c6; +} + +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #d0e9c6; +} + +.table-info, +.table-info > th, +.table-info > td { + background-color: #d9edf7; +} + +.table-hover .table-info:hover { + background-color: #c4e3f3; +} + +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #c4e3f3; +} + +.table-warning, +.table-warning > th, +.table-warning > td { + background-color: #fcf8e3; +} + +.table-hover .table-warning:hover { + background-color: #faf2cc; +} + +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #faf2cc; +} + +.table-danger, +.table-danger > th, +.table-danger > td { + background-color: #f2dede; +} + +.table-hover .table-danger:hover { + background-color: #ebcccc; +} + +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #ebcccc; +} + +.table-responsive { + display: block; + width: 100%; + min-height: .01%; + overflow-x: auto; +} + +.thead-inverse th { + color: #fff; + background-color: #373a3c; +} + +.thead-default th { + color: #55595c; + background-color: #eceeef; +} + +.table-inverse { + color: #eceeef; + background-color: #373a3c; +} + +.table-inverse.table-bordered { + border: 0; +} + +.table-inverse th, +.table-inverse td, +.table-inverse thead th { + border-color: #55595c; +} + +.table-reflow thead { + float: left; +} + +.table-reflow tbody { + display: block; + white-space: nowrap; +} + +.table-reflow th, +.table-reflow td { + border-top: 1px solid #eceeef; + border-left: 1px solid #eceeef; +} + +.table-reflow th:last-child, +.table-reflow td:last-child { + border-right: 1px solid #eceeef; +} + +.table-reflow thead:last-child tr:last-child th, +.table-reflow thead:last-child tr:last-child td, +.table-reflow tbody:last-child tr:last-child th, +.table-reflow tbody:last-child tr:last-child td, +.table-reflow tfoot:last-child tr:last-child th, +.table-reflow tfoot:last-child tr:last-child td { + border-bottom: 1px solid #eceeef; +} + +.table-reflow tr { + float: left; +} + +.table-reflow tr th, +.table-reflow tr td { + display: block !important; + border: 1px solid #eceeef; +} + +.form-control { + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + line-height: 1.5; + color: #55595c; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; +} + +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} + +.form-control:focus { + border-color: #66afe9; + outline: none; +} + +.form-control::-webkit-input-placeholder { + color: #999; + opacity: 1; +} + +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} + +.form-control:-ms-input-placeholder { + color: #999; + opacity: 1; +} + +.form-control::placeholder { + color: #999; + opacity: 1; +} + +.form-control:disabled, .form-control[readonly] { + background-color: #eceeef; + opacity: 1; +} + +.form-control:disabled { + cursor: not-allowed; +} + +.form-control-file, +.form-control-range { + display: block; +} + +.form-control-label { + padding: .375rem .75rem; + margin-bottom: 0; +} + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 2.25rem; + } + input[type="date"].input-sm, + .input-group-sm input[type="date"].form-control, + input[type="time"].input-sm, + .input-group-sm + input[type="time"].form-control, + input[type="datetime-local"].input-sm, + .input-group-sm + input[type="datetime-local"].form-control, + input[type="month"].input-sm, + .input-group-sm + input[type="month"].form-control { + line-height: 1.8625rem; + } + input[type="date"].input-lg, + .input-group-lg input[type="date"].form-control, + input[type="time"].input-lg, + .input-group-lg + input[type="time"].form-control, + input[type="datetime-local"].input-lg, + .input-group-lg + input[type="datetime-local"].form-control, + input[type="month"].input-lg, + .input-group-lg + input[type="month"].form-control { + line-height: 3.166667rem; + } +} + +.form-control-static { + min-height: 2.25rem; + padding-top: .375rem; + padding-bottom: .375rem; + margin-bottom: 0; +} + +.form-control-static.form-control-sm, .input-group-sm > .form-control-static.form-control, +.input-group-sm > .form-control-static.input-group-addon, +.input-group-sm > .input-group-btn > .form-control-static.btn, .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control, +.input-group-lg > .form-control-static.input-group-addon, +.input-group-lg > .input-group-btn > .form-control-static.btn { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm, .input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + padding: .275rem .75rem; + font-size: .875rem; + line-height: 1.5; +} + +.form-control-lg, .input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + padding: .75rem 1.25rem; + font-size: 1.25rem; + line-height: 1.333333; +} + +.form-group { + margin-bottom: 1rem; +} + +.radio, +.checkbox { + position: relative; + display: block; + margin-bottom: .75rem; +} + +.radio label, +.checkbox label { + padding-left: 1.25rem; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} + +.radio label input:only-child, +.checkbox label input:only-child { + position: static; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: .25rem; + margin-left: -1.25rem; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -.25rem; +} + +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 1.25rem; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} + +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: .75rem; +} + +input[type="radio"]:disabled, input[type="radio"].disabled, +input[type="checkbox"]:disabled, +input[type="checkbox"].disabled { + cursor: not-allowed; +} + +.radio-inline.disabled, +.checkbox-inline.disabled { + cursor: not-allowed; +} + +.radio.disabled label, +.checkbox.disabled label { + cursor: not-allowed; +} + +.form-control-success, +.form-control-warning, +.form-control-danger { + padding-right: 2.25rem; + background-repeat: no-repeat; + background-position: center right .5625rem; + -webkit-background-size: 1.4625rem 1.4625rem; + background-size: 1.4625rem 1.4625rem; +} + +.has-success .text-help, +.has-success .form-control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #64de79; +} + +.has-success .form-control { + border-color: #64de79; +} + +.has-success .input-group-addon { + color: #64de79; + background-color: white; + border-color: #64de79; +} + +.has-success .form-control-feedback { + color: #64de79; +} + +.has-success .form-control-success { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjNWNiODVjIiBkPSJNMjMzLjggNjEwYy0xMy4zIDAtMjYtNi0zNC0xNi44TDkwLjUgNDQ4LjhDNzYuMyA0MzAgODAgNDAzLjMgOTguOCAzODljMTguOC0xNC4yIDQ1LjUtMTAuNCA1OS44IDguNGw3MiA5NUw0NTEuMyAyNDJjMTIuNS0yMCAzOC44LTI2LjIgNTguOC0xMy43IDIwIDEyLjQgMjYgMzguNyAxMy43IDU4LjhMMjcwIDU5MGMtNy40IDEyLTIwLjIgMTkuNC0zNC4zIDIwaC0yeiIvPjwvc3ZnPg=="); +} + +.has-warning .text-help, +.has-warning .form-control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #a100fe; +} + +.has-warning .form-control { + border-color: #a100fe; +} + +.has-warning .input-group-addon { + color: #a100fe; + background-color: #eccbff; + border-color: #a100fe; +} + +.has-warning .form-control-feedback { + color: #a100fe; +} + +.has-warning .form-control-warning { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZjBhZDRlIiBkPSJNNjAzIDY0MC4ybC0yNzguNS01MDljLTMuOC02LjYtMTAuOC0xMC42LTE4LjUtMTAuNnMtMTQuNyA0LTE4LjUgMTAuNkw5IDY0MC4yYy0zLjcgNi41LTMuNiAxNC40LjIgMjAuOCAzLjggNi41IDEwLjggMTAuNCAxOC4zIDEwLjRoNTU3YzcuNiAwIDE0LjYtNCAxOC40LTEwLjQgMy41LTYuNCAzLjYtMTQuNCAwLTIwLjh6bS0yNjYuNC0zMGgtNjEuMlY1NDloNjEuMnY2MS4yem0wLTEwN2gtNjEuMlYzMDRoNjEuMnYxOTl6Ii8+PC9zdmc+"); +} + +.has-danger .text-help, +.has-danger .form-control-label, +.has-danger .radio, +.has-danger .checkbox, +.has-danger .radio-inline, +.has-danger .checkbox-inline, +.has-danger.radio label, +.has-danger.checkbox label, +.has-danger.radio-inline label, +.has-danger.checkbox-inline label { + color: #ff0808; +} + +.has-danger .form-control { + border-color: #ff0808; +} + +.has-danger .input-group-addon { + color: #ff0808; + background-color: #ffd4d4; + border-color: #ff0808; +} + +.has-danger .form-control-feedback { + color: #ff0808; +} + +.has-danger .form-control-danger { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZDk1MzRmIiBkPSJNNDQ3IDU0NC40Yy0xNC40IDE0LjQtMzcuNiAxNC40LTUyIDBsLTg5LTkyLjctODkgOTIuN2MtMTQuNSAxNC40LTM3LjcgMTQuNC01MiAwLTE0LjQtMTQuNC0xNC40LTM3LjYgMC01Mmw5Mi40LTk2LjMtOTIuNC05Ni4zYy0xNC40LTE0LjQtMTQuNC0zNy42IDAtNTJzMzcuNi0xNC4zIDUyIDBsODkgOTIuOCA4OS4yLTkyLjdjMTQuNC0xNC40IDM3LjYtMTQuNCA1MiAwIDE0LjMgMTQuNCAxNC4zIDM3LjYgMCA1MkwzNTQuNiAzOTZsOTIuNCA5Ni40YzE0LjQgMTQuNCAxNC40IDM3LjYgMCA1MnoiLz48L3N2Zz4="); +} + +@media (min-width: 544px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .form-control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} + +.btn { + display: inline-block; + padding: .375rem 1rem; + font-size: 1rem; + font-weight: normal; + line-height: 1.5; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid transparent; +} + +.btn:focus, .btn.focus, .btn:active:focus, .btn:active.focus, .btn.active:focus, .btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:focus, .btn:hover { + text-decoration: none; +} + +.btn.focus { + text-decoration: none; +} + +.btn:active, .btn.active { + background-image: none; + outline: 0; +} + +.btn.disabled, .btn:disabled { + cursor: not-allowed; + opacity: .65; +} + +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} + +.btn-primary { + color: #fff; + background-color: #000; + border-color: #000; +} + +.btn-primary:hover { + color: #fff; + background-color: black; + border-color: black; +} + +.btn-primary:focus, .btn-primary.focus { + color: #fff; + background-color: black; + border-color: black; +} + +.btn-primary:active, .btn-primary.active, +.open > .btn-primary.dropdown-toggle { + color: #fff; + background-color: black; + background-image: none; + border-color: black; +} + +.btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, +.open > .btn-primary.dropdown-toggle:hover, +.open > .btn-primary.dropdown-toggle:focus, +.open > .btn-primary.dropdown-toggle.focus { + color: #fff; + background-color: black; + border-color: black; +} + +.btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary:disabled:focus, .btn-primary:disabled.focus { + background-color: #000; + border-color: #000; +} + +.btn-primary.disabled:hover, .btn-primary:disabled:hover { + background-color: #000; + border-color: #000; +} + +.btn-secondary { + color: #373a3c; + background-color: #fff; + border-color: #ccc; +} + +.btn-secondary:hover { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; +} + +.btn-secondary:focus, .btn-secondary.focus { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; +} + +.btn-secondary:active, .btn-secondary.active, +.open > .btn-secondary.dropdown-toggle { + color: #373a3c; + background-color: #e6e6e6; + background-image: none; + border-color: #adadad; +} + +.btn-secondary:active:hover, .btn-secondary:active:focus, .btn-secondary:active.focus, .btn-secondary.active:hover, .btn-secondary.active:focus, .btn-secondary.active.focus, +.open > .btn-secondary.dropdown-toggle:hover, +.open > .btn-secondary.dropdown-toggle:focus, +.open > .btn-secondary.dropdown-toggle.focus { + color: #373a3c; + background-color: #d4d4d4; + border-color: #8c8c8c; +} + +.btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus { + background-color: #fff; + border-color: #ccc; +} + +.btn-secondary.disabled:hover, .btn-secondary:disabled:hover { + background-color: #fff; + border-color: #ccc; +} + +.btn-info { + color: #fff; + background-color: #0500f0; + border-color: #0500f0; +} + +.btn-info:hover { + color: #fff; + background-color: #0400bd; + border-color: #0400b3; +} + +.btn-info:focus, .btn-info.focus { + color: #fff; + background-color: #0400bd; + border-color: #0400b3; +} + +.btn-info:active, .btn-info.active, +.open > .btn-info.dropdown-toggle { + color: #fff; + background-color: #0400bd; + background-image: none; + border-color: #0400b3; +} + +.btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, +.open > .btn-info.dropdown-toggle:hover, +.open > .btn-info.dropdown-toggle:focus, +.open > .btn-info.dropdown-toggle.focus { + color: #fff; + background-color: #030099; + border-color: #020071; +} + +.btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info:disabled:focus, .btn-info:disabled.focus { + background-color: #0500f0; + border-color: #0500f0; +} + +.btn-info.disabled:hover, .btn-info:disabled:hover { + background-color: #0500f0; + border-color: #0500f0; +} + +.btn-success { + color: #fff; + background-color: #64de79; + border-color: #64de79; +} + +.btn-success:hover { + color: #fff; + background-color: #3ad555; + border-color: #32d34d; +} + +.btn-success:focus, .btn-success.focus { + color: #fff; + background-color: #3ad555; + border-color: #32d34d; +} + +.btn-success:active, .btn-success.active, +.open > .btn-success.dropdown-toggle { + color: #fff; + background-color: #3ad555; + background-image: none; + border-color: #32d34d; +} + +.btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, +.open > .btn-success.dropdown-toggle:hover, +.open > .btn-success.dropdown-toggle:focus, +.open > .btn-success.dropdown-toggle.focus { + color: #fff; + background-color: #29c244; + border-color: #22a038; +} + +.btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success:disabled:focus, .btn-success:disabled.focus { + background-color: #64de79; + border-color: #64de79; +} + +.btn-success.disabled:hover, .btn-success:disabled:hover { + background-color: #64de79; + border-color: #64de79; +} + +.btn-warning { + color: #fff; + background-color: #a100fe; + border-color: #a100fe; +} + +.btn-warning:hover { + color: #fff; + background-color: #8100cb; + border-color: #7a00c1; +} + +.btn-warning:focus, .btn-warning.focus { + color: #fff; + background-color: #8100cb; + border-color: #7a00c1; +} + +.btn-warning:active, .btn-warning.active, +.open > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #8100cb; + background-image: none; + border-color: #7a00c1; +} + +.btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, +.open > .btn-warning.dropdown-toggle:hover, +.open > .btn-warning.dropdown-toggle:focus, +.open > .btn-warning.dropdown-toggle.focus { + color: #fff; + background-color: #6a00a7; + border-color: #50007f; +} + +.btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning:disabled:focus, .btn-warning:disabled.focus { + background-color: #a100fe; + border-color: #a100fe; +} + +.btn-warning.disabled:hover, .btn-warning:disabled:hover { + background-color: #a100fe; + border-color: #a100fe; +} + +.btn-danger { + color: #fff; + background-color: #ff0808; + border-color: #ff0808; +} + +.btn-danger:hover { + color: #fff; + background-color: #d40000; + border-color: #ca0000; +} + +.btn-danger:focus, .btn-danger.focus { + color: #fff; + background-color: #d40000; + border-color: #ca0000; +} + +.btn-danger:active, .btn-danger.active, +.open > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #d40000; + background-image: none; + border-color: #ca0000; +} + +.btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, +.open > .btn-danger.dropdown-toggle:hover, +.open > .btn-danger.dropdown-toggle:focus, +.open > .btn-danger.dropdown-toggle.focus { + color: #fff; + background-color: #b00000; + border-color: #800; +} + +.btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger:disabled:focus, .btn-danger:disabled.focus { + background-color: #ff0808; + border-color: #ff0808; +} + +.btn-danger.disabled:hover, .btn-danger:disabled:hover { + background-color: #ff0808; + border-color: #ff0808; +} + +.btn-primary-outline { + color: #000; + background-color: transparent; + background-image: none; + border-color: #000; +} + +.btn-primary-outline:focus, .btn-primary-outline.focus, .btn-primary-outline:active, .btn-primary-outline.active, +.open > .btn-primary-outline.dropdown-toggle { + color: #fff; + background-color: #000; + border-color: #000; +} + +.btn-primary-outline:hover { + color: #fff; + background-color: #000; + border-color: #000; +} + +.btn-primary-outline.disabled:focus, .btn-primary-outline.disabled.focus, .btn-primary-outline:disabled:focus, .btn-primary-outline:disabled.focus { + border-color: #333; +} + +.btn-primary-outline.disabled:hover, .btn-primary-outline:disabled:hover { + border-color: #333; +} + +.btn-secondary-outline { + color: #ccc; + background-color: transparent; + background-image: none; + border-color: #ccc; +} + +.btn-secondary-outline:focus, .btn-secondary-outline.focus, .btn-secondary-outline:active, .btn-secondary-outline.active, +.open > .btn-secondary-outline.dropdown-toggle { + color: #fff; + background-color: #ccc; + border-color: #ccc; +} + +.btn-secondary-outline:hover { + color: #fff; + background-color: #ccc; + border-color: #ccc; +} + +.btn-secondary-outline.disabled:focus, .btn-secondary-outline.disabled.focus, .btn-secondary-outline:disabled:focus, .btn-secondary-outline:disabled.focus { + border-color: white; +} + +.btn-secondary-outline.disabled:hover, .btn-secondary-outline:disabled:hover { + border-color: white; +} + +.btn-info-outline { + color: #0500f0; + background-color: transparent; + background-image: none; + border-color: #0500f0; +} + +.btn-info-outline:focus, .btn-info-outline.focus, .btn-info-outline:active, .btn-info-outline.active, +.open > .btn-info-outline.dropdown-toggle { + color: #fff; + background-color: #0500f0; + border-color: #0500f0; +} + +.btn-info-outline:hover { + color: #fff; + background-color: #0500f0; + border-color: #0500f0; +} + +.btn-info-outline.disabled:focus, .btn-info-outline.disabled.focus, .btn-info-outline:disabled:focus, .btn-info-outline:disabled.focus { + border-color: #5b57ff; +} + +.btn-info-outline.disabled:hover, .btn-info-outline:disabled:hover { + border-color: #5b57ff; +} + +.btn-success-outline { + color: #64de79; + background-color: transparent; + background-image: none; + border-color: #64de79; +} + +.btn-success-outline:focus, .btn-success-outline.focus, .btn-success-outline:active, .btn-success-outline.active, +.open > .btn-success-outline.dropdown-toggle { + color: #fff; + background-color: #64de79; + border-color: #64de79; +} + +.btn-success-outline:hover { + color: #fff; + background-color: #64de79; + border-color: #64de79; +} + +.btn-success-outline.disabled:focus, .btn-success-outline.disabled.focus, .btn-success-outline:disabled:focus, .btn-success-outline:disabled.focus { + border-color: #b8f0c2; +} + +.btn-success-outline.disabled:hover, .btn-success-outline:disabled:hover { + border-color: #b8f0c2; +} + +.btn-warning-outline { + color: #a100fe; + background-color: transparent; + background-image: none; + border-color: #a100fe; +} + +.btn-warning-outline:focus, .btn-warning-outline.focus, .btn-warning-outline:active, .btn-warning-outline.active, +.open > .btn-warning-outline.dropdown-toggle { + color: #fff; + background-color: #a100fe; + border-color: #a100fe; +} + +.btn-warning-outline:hover { + color: #fff; + background-color: #a100fe; + border-color: #a100fe; +} + +.btn-warning-outline.disabled:focus, .btn-warning-outline.disabled.focus, .btn-warning-outline:disabled:focus, .btn-warning-outline:disabled.focus { + border-color: #c765ff; +} + +.btn-warning-outline.disabled:hover, .btn-warning-outline:disabled:hover { + border-color: #c765ff; +} + +.btn-danger-outline { + color: #ff0808; + background-color: transparent; + background-image: none; + border-color: #ff0808; +} + +.btn-danger-outline:focus, .btn-danger-outline.focus, .btn-danger-outline:active, .btn-danger-outline.active, +.open > .btn-danger-outline.dropdown-toggle { + color: #fff; + background-color: #ff0808; + border-color: #ff0808; +} + +.btn-danger-outline:hover { + color: #fff; + background-color: #ff0808; + border-color: #ff0808; +} + +.btn-danger-outline.disabled:focus, .btn-danger-outline.disabled.focus, .btn-danger-outline:disabled:focus, .btn-danger-outline:disabled.focus { + border-color: #ff6e6e; +} + +.btn-danger-outline.disabled:hover, .btn-danger-outline:disabled:hover { + border-color: #ff6e6e; +} + +.btn-link { + font-weight: normal; + color: #000; + border-radius: 0; +} + +.btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled { + background-color: transparent; +} + +.btn-link, .btn-link:focus, .btn-link:active { + border-color: transparent; +} + +.btn-link:hover { + border-color: transparent; +} + +.btn-link:focus, .btn-link:hover { + color: #000; + text-decoration: underline; + background-color: transparent; +} + +.btn-link:disabled:focus, .btn-link:disabled:hover { + color: #b1b7bd; + text-decoration: none; +} + +.btn-lg, .btn-group-lg > .btn { + padding: .75rem 1.25rem; + font-size: 1.25rem; + line-height: 1.333333; +} + +.btn-sm, .btn-group-sm > .btn { + padding: .25rem .75rem; + font-size: .875rem; + line-height: 1.5; +} + +.btn-block { + display: block; + width: 100%; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.in { + display: block; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height; + -o-transition-property: height; + transition-property: height; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-right: .25rem; + margin-left: .25rem; + vertical-align: middle; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-left: .3em solid transparent; +} + +.dropdown-toggle:focus { + outline: 0; +} + +.dropup .dropdown-toggle::after { + border-top: 0; + border-bottom: .3em solid; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 1rem; + color: #373a3c; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .15); +} + +.dropdown-divider { + height: 1px; + margin: .5rem 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.5; + color: #373a3c; + text-align: inherit; + white-space: nowrap; + background: none; + border: 0; +} + +.dropdown-item:focus, .dropdown-item:hover { + color: #2b2d2f; + text-decoration: none; + background-color: #f5f5f5; +} + +.dropdown-item.active, .dropdown-item.active:focus, .dropdown-item.active:hover { + color: #fff; + text-decoration: none; + background-color: #000; + outline: 0; +} + +.dropdown-item.disabled, .dropdown-item.disabled:focus, .dropdown-item.disabled:hover { + color: #b1b7bd; +} + +.dropdown-item.disabled:focus, .dropdown-item.disabled:hover { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)"; +} + +.open > .dropdown-menu { + display: block; +} + +.open > a { + outline: 0; +} + +.dropdown-menu-right { + right: 0; + left: auto; +} + +.dropdown-menu-left { + right: auto; + left: 0; +} + +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: .875rem; + line-height: 1.5; + color: #b1b7bd; + white-space: nowrap; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: .3em solid; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} + +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} + +.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 2; +} + +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover { + z-index: 2; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar { + margin-left: -5px; +} + +.btn-toolbar::after { + display: table; + clear: both; + content: ""; +} + +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} + +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} + +.btn-group > .btn-group { + float: left; +} + +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} + +.btn-group > .btn-lg + .dropdown-toggle, .btn-group-lg.btn-group > .btn + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} + +.btn .caret { + margin-left: 0; +} + +.btn-lg .caret, .btn-group-lg > .btn .caret { + border-width: .3em .3em 0; + border-bottom-width: 0; +} + +.dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret { + border-width: 0 .3em .3em; +} + +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} + +.btn-group-vertical > .btn-group::after { + display: table; + clear: both; + content: ""; +} + +.btn-group-vertical > .btn-group > .btn { + float: none; +} + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} + +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: .25rem; +} + +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: .25rem; +} + +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} + +.input-group { + position: relative; + display: table; + border-collapse: separate; +} + +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} + +.input-group .form-control:focus, .input-group .form-control:active, .input-group .form-control:hover { + z-index: 3; +} + +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} + +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} + +.input-group-addon { + padding: .375rem .75rem; + font-size: 1rem; + font-weight: normal; + line-height: 1; + color: #55595c; + text-align: center; + background-color: #eceeef; + border: 1px solid #ccc; +} + +.input-group-addon.form-control-sm, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .input-group-addon.btn { + padding: .275rem .75rem; + font-size: .875rem; +} + +.input-group-addon.form-control-lg, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .input-group-addon.btn { + padding: .75rem 1.25rem; + font-size: 1.25rem; +} + +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} + +.input-group-addon:first-child { + border-right: 0; +} + +.input-group-addon:last-child { + border-left: 0; +} + +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} + +.input-group-btn > .btn { + position: relative; +} + +.input-group-btn > .btn + .btn { + margin-left: -1px; +} + +.input-group-btn > .btn:focus, .input-group-btn > .btn:active, .input-group-btn > .btn:hover { + z-index: 3; +} + +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} + +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} + +.input-group-btn:last-child > .btn:focus, .input-group-btn:last-child > .btn:active, .input-group-btn:last-child > .btn:hover, +.input-group-btn:last-child > .btn-group:focus, +.input-group-btn:last-child > .btn-group:active, +.input-group-btn:last-child > .btn-group:hover { + z-index: 3; +} + +.c-input { + position: relative; + display: inline; + padding-left: 1.5rem; + color: #555; + cursor: pointer; +} + +.c-input > input { + position: absolute; + z-index: -1; + opacity: 0; +} + +.c-input > input:checked ~ .c-indicator { + color: #fff; + background-color: #0074d9; +} + +.c-input > input:focus ~ .c-indicator { + -webkit-box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9; + box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9; +} + +.c-input > input:active ~ .c-indicator { + color: #fff; + background-color: #84c6ff; +} + +.c-input + .c-input { + margin-left: 1rem; +} + +.c-indicator { + position: absolute; + top: 0; + left: 0; + display: block; + width: 1rem; + height: 1rem; + font-size: 65%; + line-height: 1rem; + color: #eee; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #eee; + background-repeat: no-repeat; + background-position: center center; + -webkit-background-size: 50% 50%; + background-size: 50% 50%; +} + +.c-checkbox .c-indicator { + border-radius: .25rem; +} + +.c-checkbox input:checked ~ .c-indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=); +} + +.c-checkbox input:indeterminate ~ .c-indicator { + background-color: #0074d9; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K); +} + +.c-radio .c-indicator { + border-radius: 50%; +} + +.c-radio input:checked ~ .c-indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==); +} + +.c-inputs-stacked .c-input { + display: inline; +} + +.c-inputs-stacked .c-input::after { + display: block; + margin-bottom: .25rem; + content: ""; +} + +.c-inputs-stacked .c-input + .c-input { + margin-left: 0; +} + +.c-select { + display: inline-block; + max-width: 100%; + -webkit-appearance: none; + padding: .375rem 1.75rem .375rem .75rem; + padding-right: .75rem \9; + color: #55595c; + vertical-align: middle; + background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC) no-repeat right .75rem center; + background-image: none \9; + -webkit-background-size: 8px 10px; + background-size: 8px 10px; + border: 1px solid #ccc; + + -moz-appearance: none; +} + +.c-select:focus { + border-color: #51a7e8; + outline: none; +} + +.c-select::-ms-expand { + opacity: 0; +} + +.c-select-sm { + padding-top: 3px; + padding-bottom: 3px; + font-size: 12px; +} + +.c-select-sm:not([multiple]) { + height: 26px; + min-height: 26px; +} + +.file { + position: relative; + display: inline-block; + height: 2.5rem; + cursor: pointer; +} + +.file input { + min-width: 14rem; + margin: 0; + filter: alpha(opacity=0); + opacity: 0; +} + +.file-custom { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 5; + height: 2.5rem; + padding: .5rem 1rem; + line-height: 1.5; + color: #555; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #fff; + border: 1px solid #ddd; + border-radius: .25rem; +} + +.file-custom::after { + content: "Choose file..."; +} + +.file-custom::before { + position: absolute; + top: -.075rem; + right: -.075rem; + bottom: -.075rem; + z-index: 6; + display: block; + height: 2.5rem; + padding: .5rem 1rem; + line-height: 1.5; + color: #555; + content: "Browse"; + background-color: #eee; + border: 1px solid #ddd; + border-radius: 0 .25rem .25rem 0; +} + +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: inline-block; +} + +.nav-link:focus, .nav-link:hover { + text-decoration: none; +} + +.nav-link.disabled { + color: #b1b7bd; +} + +.nav-link.disabled, .nav-link.disabled:focus, .nav-link.disabled:hover { + color: #b1b7bd; + cursor: not-allowed; + background-color: transparent; +} + +.nav-inline .nav-item { + display: inline-block; +} + +.nav-inline .nav-item + .nav-item, +.nav-inline .nav-link + .nav-link { + margin-left: 1rem; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs::after { + display: table; + clear: both; + content: ""; +} + +.nav-tabs .nav-item { + float: left; + margin-bottom: -1px; +} + +.nav-tabs .nav-item + .nav-item { + margin-left: .2rem; +} + +.nav-tabs .nav-link { + display: block; + padding: .5em 1em; + border: 1px solid transparent; +} + +.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + border-color: #eceeef #eceeef #ddd; +} + +.nav-tabs .nav-link.disabled, .nav-tabs .nav-link.disabled:focus, .nav-tabs .nav-link.disabled:hover { + color: #b1b7bd; + background-color: transparent; + border-color: transparent; +} + +.nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover, +.nav-tabs .nav-item.open .nav-link, +.nav-tabs .nav-item.open .nav-link:focus, +.nav-tabs .nav-item.open .nav-link:hover { + color: #55595c; + background-color: #fff; + border-color: #ddd #ddd transparent; +} + +.nav-pills::after { + display: table; + clear: both; + content: ""; +} + +.nav-pills .nav-item { + float: left; +} + +.nav-pills .nav-item + .nav-item { + margin-left: .2rem; +} + +.nav-pills .nav-link { + display: block; + padding: .5em 1em; +} + +.nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover, +.nav-pills .nav-item.open .nav-link, +.nav-pills .nav-item.open .nav-link:focus, +.nav-pills .nav-item.open .nav-link:hover { + color: #fff; + cursor: default; + background-color: #000; +} + +.nav-stacked .nav-item { + display: block; + float: none; +} + +.nav-stacked .nav-item + .nav-item { + margin-top: .2rem; + margin-left: 0; +} + +.tab-content > .tab-pane { + display: none; +} + +.tab-content > .active { + display: block; +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; +} + +.navbar { + position: relative; + padding: .5rem 1rem; +} + +.navbar::after { + display: table; + clear: both; + content: ""; +} + +.navbar-full { + z-index: 1000; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1030; + width: 100%; +} + +.navbar-brand { + float: left; + padding-top: .25rem; + padding-bottom: .25rem; + margin-right: 1rem; + font-size: 1.25rem; +} + +.navbar-brand:focus, .navbar-brand:hover { + text-decoration: none; +} + +.navbar-brand > img { + display: block; +} + +.navbar-divider { + float: left; + width: 1px; + padding-top: .425rem; + padding-bottom: .425rem; + margin-right: 1rem; + margin-left: 1rem; + overflow: hidden; +} + +.navbar-divider::before { + content: "\00a0"; +} + +.navbar-toggler { + padding: .5rem .75rem; + font-size: 1.25rem; + line-height: 1; + background: none; + border: 1px solid transparent; +} + +.navbar-toggler:focus, .navbar-toggler:hover { + text-decoration: none; +} + +@media (min-width: 544px) { + .navbar-toggleable-xs { + display: block !important; + } +} + +@media (min-width: 768px) { + .navbar-toggleable-sm { + display: block !important; + } +} + +@media (min-width: 992px) { + .navbar-toggleable-md { + display: block !important; + } +} + +.navbar-nav .nav-item { + float: left; +} + +.navbar-nav .nav-link { + display: block; + padding-top: .425rem; + padding-bottom: .425rem; +} + +.navbar-nav .nav-link + .nav-link { + margin-left: 1rem; +} + +.navbar-nav .nav-item + .nav-item { + margin-left: 1rem; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, .8); +} + +.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { + color: rgba(0, 0, 0, .8); +} + +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, .3); +} + +.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { + color: rgba(0, 0, 0, .6); +} + +.navbar-light .navbar-nav .open > .nav-link, .navbar-light .navbar-nav .open > .nav-link:focus, .navbar-light .navbar-nav .open > .nav-link:hover, +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .active > .nav-link:focus, +.navbar-light .navbar-nav .active > .nav-link:hover, +.navbar-light .navbar-nav .nav-link.open, +.navbar-light .navbar-nav .nav-link.open:focus, +.navbar-light .navbar-nav .nav-link.open:hover, +.navbar-light .navbar-nav .nav-link.active, +.navbar-light .navbar-nav .nav-link.active:focus, +.navbar-light .navbar-nav .nav-link.active:hover { + color: rgba(0, 0, 0, .8); +} + +.navbar-light .navbar-divider { + background-color: rgba(0, 0, 0, .075); +} + +.navbar-dark .navbar-brand { + color: white; +} + +.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { + color: white; +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, .5); +} + +.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { + color: rgba(255, 255, 255, .75); +} + +.navbar-dark .navbar-nav .open > .nav-link, .navbar-dark .navbar-nav .open > .nav-link:focus, .navbar-dark .navbar-nav .open > .nav-link:hover, +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .active > .nav-link:focus, +.navbar-dark .navbar-nav .active > .nav-link:hover, +.navbar-dark .navbar-nav .nav-link.open, +.navbar-dark .navbar-nav .nav-link.open:focus, +.navbar-dark .navbar-nav .nav-link.open:hover, +.navbar-dark .navbar-nav .nav-link.active, +.navbar-dark .navbar-nav .nav-link.active:focus, +.navbar-dark .navbar-nav .nav-link.active:hover { + color: white; +} + +.navbar-dark .navbar-divider { + background-color: rgba(255, 255, 255, .075); +} + +.card { + position: relative; + display: block; + margin-bottom: .75rem; + background-color: #fff; + border: 1px solid #e5e5e5; +} + +.card-block { + padding: 1.25rem; +} + +.card-title { + margin-bottom: .75rem; +} + +.card-subtitle { + margin-top: -.375rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} + +.card-link + .card-link { + margin-left: 1.25rem; +} + +.card-header { + padding: .75rem 1.25rem; + background-color: #f5f5f5; + border-bottom: 1px solid #e5e5e5; +} + +.card-footer { + padding: .75rem 1.25rem; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; +} + +.card-primary { + background-color: #000; + border-color: #000; +} + +.card-success { + background-color: #64de79; + border-color: #64de79; +} + +.card-info { + background-color: #0500f0; + border-color: #0500f0; +} + +.card-warning { + background-color: #a100fe; + border-color: #a100fe; +} + +.card-danger { + background-color: #ff0808; + border-color: #ff0808; +} + +.card-primary-outline { + background-color: transparent; + border-color: #000; +} + +.card-secondary-outline { + background-color: transparent; + border-color: #ccc; +} + +.card-info-outline { + background-color: transparent; + border-color: #0500f0; +} + +.card-success-outline { + background-color: transparent; + border-color: #64de79; +} + +.card-warning-outline { + background-color: transparent; + border-color: #a100fe; +} + +.card-danger-outline { + background-color: transparent; + border-color: #ff0808; +} + +.card-inverse .card-header, +.card-inverse .card-footer { + border-bottom: 1px solid rgba(255, 255, 255, .2); +} + +.card-inverse .card-header, +.card-inverse .card-footer, +.card-inverse .card-title, +.card-inverse .card-blockquote { + color: #fff; +} + +.card-inverse .card-link, +.card-inverse .card-text, +.card-inverse .card-blockquote > footer { + color: rgba(255, 255, 255, .65); +} + +.card-inverse .card-link:focus, .card-inverse .card-link:hover { + color: #fff; +} + +.card-blockquote { + padding: 0; + margin-bottom: 0; + border-left: 0; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + +@media (min-width: 544px) { + .card-deck { + display: table; + table-layout: fixed; + border-spacing: 1.25rem 0; + } + .card-deck .card { + display: table-cell; + width: 1%; + vertical-align: top; + } + .card-deck-wrapper { + margin-right: -1.25rem; + margin-left: -1.25rem; + } +} + +@media (min-width: 544px) { + .card-group { + display: table; + width: 100%; + table-layout: fixed; + } + .card-group .card { + display: table-cell; + vertical-align: top; + } + .card-group .card + .card { + margin-left: 0; + border-left: 0; + } +} + +@media (min-width: 544px) { + .card-columns { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + -webkit-column-gap: 1.25rem; + -moz-column-gap: 1.25rem; + column-gap: 1.25rem; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} + +.breadcrumb { + padding: .75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #eceeef; +} + +.breadcrumb::after { + display: table; + clear: both; + content: ""; +} + +.breadcrumb > li { + float: left; +} + +.breadcrumb > li + li::before { + padding-right: .5rem; + padding-left: .5rem; + color: #b1b7bd; + content: "/"; +} + +.breadcrumb > .active { + color: #b1b7bd; +} + +.pagination { + display: inline-block; + padding-left: 0; + margin-top: 1rem; + margin-bottom: 1rem; +} + +.page-item { + display: inline; +} + +.page-item:first-child .page-link { + margin-left: 0; +} + +.page-item.active .page-link, .page-item.active .page-link:focus, .page-item.active .page-link:hover { + z-index: 2; + color: #fff; + cursor: default; + background-color: #000; + border-color: #000; +} + +.page-item.disabled .page-link, .page-item.disabled .page-link:focus, .page-item.disabled .page-link:hover { + color: #b1b7bd; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} + +.page-link { + position: relative; + float: left; + padding: .5rem .75rem; + margin-left: -1px; + line-height: 1.5; + color: #000; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} + +.page-link:focus, .page-link:hover { + color: #000; + background-color: #eceeef; + border-color: #ddd; +} + +.pagination-lg .page-link { + padding: .75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.333333; +} + +.pagination-sm .page-link { + padding: .275rem .75rem; + font-size: .875rem; + line-height: 1.5; +} + +.pager { + padding-left: 0; + margin-top: 1rem; + margin-bottom: 1rem; + text-align: center; + list-style: none; +} + +.pager::after { + display: table; + clear: both; + content: ""; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} + +.pager li > a:focus, .pager li > a:hover { + text-decoration: none; + background-color: #eceeef; +} + +.pager .disabled > a, .pager .disabled > a:focus, .pager .disabled > a:hover { + color: #b1b7bd; + cursor: not-allowed; + background-color: #fff; +} + +.pager .disabled > span { + color: #b1b7bd; + cursor: not-allowed; + background-color: #fff; +} + +.pager-next > a, +.pager-next > span { + float: right; +} + +.pager-prev > a, +.pager-prev > span { + float: left; +} + +.label { + display: inline-block; + padding: .25em .4em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; +} + +.label:empty { + display: none; +} + +.btn .label { + position: relative; + top: -1px; +} + +a.label:focus, a.label:hover { + color: #fff; + text-decoration: none; + cursor: pointer; +} + +.label-pill { + padding-right: .6em; + padding-left: .6em; +} + +.label-default { + background-color: #b1b7bd; +} + +.label-default[href]:focus, .label-default[href]:hover { + background-color: #959ea6; +} + +.label-primary { + background-color: #000; +} + +.label-primary[href]:focus, .label-primary[href]:hover { + background-color: black; +} + +.label-success { + background-color: #64de79; +} + +.label-success[href]:focus, .label-success[href]:hover { + background-color: #3ad555; +} + +.label-info { + background-color: #0500f0; +} + +.label-info[href]:focus, .label-info[href]:hover { + background-color: #0400bd; +} + +.label-warning { + background-color: #a100fe; +} + +.label-warning[href]:focus, .label-warning[href]:hover { + background-color: #8100cb; +} + +.label-danger { + background-color: #ff0808; +} + +.label-danger[href]:focus, .label-danger[href]:hover { + background-color: #d40000; +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #eceeef; +} + +@media (min-width: 544px) { + .jumbotron { + padding: 4rem 2rem; + } +} + +.jumbotron-hr { + border-top-color: #d0d5d8; +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; +} + +.alert { + padding: 15px; + margin-bottom: 1rem; + border: 1px solid transparent; +} + +.alert > p, +.alert > ul { + margin-bottom: 0; +} + +.alert > p + p { + margin-top: 5px; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: bold; +} + +.alert-dismissible { + padding-right: 35px; +} + +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} + +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d0e9c6; +} + +.alert-success hr { + border-top-color: #c1e2b3; +} + +.alert-success .alert-link { + color: #2b542c; +} + +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bcdff1; +} + +.alert-info hr { + border-top-color: #a6d5ec; +} + +.alert-info .alert-link { + color: #245269; +} + +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faf2cc; +} + +.alert-warning hr { + border-top-color: #f7ecb5; +} + +.alert-warning .alert-link { + color: #66512c; +} + +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebcccc; +} + +.alert-danger hr { + border-top-color: #e4b9b9; +} + +.alert-danger .alert-link { + color: #843534; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +.progress { + display: block; + width: 100%; + height: 1rem; + margin-bottom: 1rem; +} + +.progress[value] { + -webkit-appearance: none; + color: #0074d9; + border: 0; + + -moz-appearance: none; + appearance: none; +} + +.progress[value]::-webkit-progress-bar { + background-color: #eee; +} + +.progress[value]::-webkit-progress-value::before { + content: attr(value); +} + +.progress[value]::-webkit-progress-value { + background-color: #0074d9; + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; +} + +.progress[value="100"]::-webkit-progress-value { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; +} + +@media screen and (min-width: 0\0) { + .progress { + background-color: #eee; + } + .progress-bar { + display: inline-block; + height: 1rem; + text-indent: -999rem; + background-color: #0074d9; + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + } + .progress[width^="0"] { + min-width: 2rem; + color: #b1b7bd; + background-color: transparent; + background-image: none; + } + .progress[width="100%"] { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + } +} + +.progress-striped[value]::-webkit-progress-value { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 1rem 1rem; + background-size: 1rem 1rem; +} + +.progress-striped[value]::-moz-progress-bar { + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +@media screen and (min-width: 0\0) { + .progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 1rem 1rem; + background-size: 1rem 1rem; + } +} + +.progress-animated[value]::-webkit-progress-value { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-animated[value]::-moz-progress-bar { + animation: progress-bar-stripes 2s linear infinite; +} + +@media screen and (min-width: 0\0) { + .progress-animated .progress-bar-striped { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; + } +} + +.progress-success[value]::-webkit-progress-value { + background-color: #64de79; +} + +.progress-success[value]::-moz-progress-bar { + background-color: #64de79; +} + +@media screen and (min-width: 0\0) { + .progress-success .progress-bar { + background-color: #64de79; + } +} + +.progress-info[value]::-webkit-progress-value { + background-color: #0500f0; +} + +.progress-info[value]::-moz-progress-bar { + background-color: #0500f0; +} + +@media screen and (min-width: 0\0) { + .progress-info .progress-bar { + background-color: #0500f0; + } +} + +.progress-warning[value]::-webkit-progress-value { + background-color: #a100fe; +} + +.progress-warning[value]::-moz-progress-bar { + background-color: #a100fe; +} + +@media screen and (min-width: 0\0) { + .progress-warning .progress-bar { + background-color: #a100fe; + } +} + +.progress-danger[value]::-webkit-progress-value { + background-color: #ff0808; +} + +.progress-danger[value]::-moz-progress-bar { + background-color: #ff0808; +} + +@media screen and (min-width: 0\0) { + .progress-danger .progress-bar { + background-color: #ff0808; + } +} + +.media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media, +.media-body { + overflow: hidden; + zoom: 1; +} + +.media-body { + width: 10000px; +} + +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} + +.media-middle { + vertical-align: middle; +} + +.media-bottom { + vertical-align: bottom; +} + +.media-object { + display: block; +} + +.media-object.img-thumbnail { + max-width: none; +} + +.media-right { + padding-left: 10px; +} + +.media-left { + padding-right: 10px; +} + +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} + +.media-list { + padding-left: 0; + list-style: none; +} + +.list-group { + padding-left: 0; + margin-bottom: 0; +} + +.list-group-item { + position: relative; + display: block; + padding: .75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} + +.list-group-item:last-child { + margin-bottom: 0; +} + +.list-group-flush .list-group-item { + border-width: 1px 0; + border-radius: 0; +} + +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0; +} + +.list-group-flush:last-child .list-group-item:last-child { + border-bottom: 0; +} + +a.list-group-item, +button.list-group-item { + width: 100%; + color: #555; + text-align: inherit; +} + +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} + +a.list-group-item:focus, a.list-group-item:hover, +button.list-group-item:focus, +button.list-group-item:hover { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} + +.list-group-item.disabled, .list-group-item.disabled:focus, .list-group-item.disabled:hover { + color: #b1b7bd; + cursor: not-allowed; + background-color: #eceeef; +} + +.list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading { + color: inherit; +} + +.list-group-item.disabled .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text { + color: #b1b7bd; +} + +.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover { + z-index: 2; + color: #fff; + background-color: #000; + border-color: #000; +} + +.list-group-item.active .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > .small { + color: inherit; +} + +.list-group-item.active .list-group-item-text, .list-group-item.active:focus .list-group-item-text, .list-group-item.active:hover .list-group-item-text { + color: #666; +} + +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} + +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} + +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} + +a.list-group-item-success:focus, a.list-group-item-success:hover, +button.list-group-item-success:focus, +button.list-group-item-success:hover { + color: #3c763d; + background-color: #d0e9c6; +} + +a.list-group-item-success.active, a.list-group-item-success.active:focus, a.list-group-item-success.active:hover, +button.list-group-item-success.active, +button.list-group-item-success.active:focus, +button.list-group-item-success.active:hover { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} + +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} + +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} + +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} + +a.list-group-item-info:focus, a.list-group-item-info:hover, +button.list-group-item-info:focus, +button.list-group-item-info:hover { + color: #31708f; + background-color: #c4e3f3; +} + +a.list-group-item-info.active, a.list-group-item-info.active:focus, a.list-group-item-info.active:hover, +button.list-group-item-info.active, +button.list-group-item-info.active:focus, +button.list-group-item-info.active:hover { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} + +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} + +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} + +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} + +a.list-group-item-warning:focus, a.list-group-item-warning:hover, +button.list-group-item-warning:focus, +button.list-group-item-warning:hover { + color: #8a6d3b; + background-color: #faf2cc; +} + +a.list-group-item-warning.active, a.list-group-item-warning.active:focus, a.list-group-item-warning.active:hover, +button.list-group-item-warning.active, +button.list-group-item-warning.active:focus, +button.list-group-item-warning.active:hover { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} + +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} + +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} + +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} + +a.list-group-item-danger:focus, a.list-group-item-danger:hover, +button.list-group-item-danger:focus, +button.list-group-item-danger:hover { + color: #a94442; + background-color: #ebcccc; +} + +a.list-group-item-danger.active, a.list-group-item-danger.active:focus, a.list-group-item-danger.active:hover, +button.list-group-item-danger.active, +button.list-group-item-danger.active:focus, +button.list-group-item-danger.active:hover { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} + +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} + +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} + +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} + +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.embed-responsive-21by9 { + padding-bottom: 42.857143%; +} + +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} + +.embed-responsive-4by3 { + padding-bottom: 75%; +} + +.embed-responsive-1by1 { + padding-bottom: 100%; +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .2; +} + +.close:focus, .close:hover { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: .5; +} + +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} + +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: transform .3s ease-out, -o-transform .3s ease-out; + transition: -webkit-transform .3s ease-out; + transition: transform .3s ease-out; + transition: transform .3s ease-out, -webkit-transform .3s ease-out, -o-transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} + +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} + +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: .3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop.in { + opacity: .5; +} + +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} + +.modal-header::after { + display: table; + clear: both; + content: ""; +} + +.modal-header .close { + margin-top: -2px; +} + +.modal-title { + margin: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + padding: 15px; +} + +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} + +.modal-footer::after { + display: table; + clear: both; + content: ""; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +@media (min-width: 544px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-sm { + width: 300px; + } +} + +@media (min-width: 768px) { + .modal-lg { + width: 900px; + } +} + +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "bau", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: .875rem; + font-style: normal; + font-weight: normal; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + opacity: 0; + + line-break: auto; +} + +.tooltip.in { + opacity: .9; +} + +.tooltip.tooltip-top, .tooltip.bs-tether-element-attached-bottom { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.tooltip-top .tooltip-arrow, .tooltip.bs-tether-element-attached-bottom .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} + +.tooltip.tooltip-right, .tooltip.bs-tether-element-attached-left { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.tooltip-right .tooltip-arrow, .tooltip.bs-tether-element-attached-left .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} + +.tooltip.tooltip-bottom, .tooltip.bs-tether-element-attached-top { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.tooltip-bottom .tooltip-arrow, .tooltip.bs-tether-element-attached-top .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} + +.tooltip.tooltip-left, .tooltip.bs-tether-element-attached-right { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip.tooltip-left .tooltip-arrow, .tooltip.bs-tether-element-attached-right .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + padding: 1px; + font-family: "bau", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: .875rem; + font-style: normal; + font-weight: normal; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + + line-break: auto; +} + +.popover.popover-top, .popover.bs-tether-element-attached-bottom { + margin-top: -10px; +} + +.popover.popover-top .popover-arrow, .popover.bs-tether-element-attached-bottom .popover-arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} + +.popover.popover-top .popover-arrow::after, .popover.bs-tether-element-attached-bottom .popover-arrow::after { + bottom: 1px; + margin-left: -10px; + content: ""; + border-top-color: #fff; + border-bottom-width: 0; +} + +.popover.popover-right, .popover.bs-tether-element-attached-left { + margin-left: 10px; +} + +.popover.popover-right .popover-arrow, .popover.bs-tether-element-attached-left .popover-arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} + +.popover.popover-right .popover-arrow::after, .popover.bs-tether-element-attached-left .popover-arrow::after { + bottom: -10px; + left: 1px; + content: ""; + border-right-color: #fff; + border-left-width: 0; +} + +.popover.popover-bottom, .popover.bs-tether-element-attached-top { + margin-top: 10px; +} + +.popover.popover-bottom .popover-arrow, .popover.bs-tether-element-attached-top .popover-arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: rgba(0, 0, 0, .25); +} + +.popover.popover-bottom .popover-arrow::after, .popover.bs-tether-element-attached-top .popover-arrow::after { + top: 1px; + margin-left: -10px; + content: ""; + border-top-width: 0; + border-bottom-color: #fff; +} + +.popover.popover-left, .popover.bs-tether-element-attached-right { + margin-left: -10px; +} + +.popover.popover-left .popover-arrow, .popover.bs-tether-element-attached-right .popover-arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: rgba(0, 0, 0, .25); +} + +.popover.popover-left .popover-arrow::after, .popover.bs-tether-element-attached-right .popover-arrow::after { + right: 1px; + bottom: -10px; + content: ""; + border-right-width: 0; + border-left-color: #fff; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 1rem; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; +} + +.popover-content { + padding: 9px 14px; +} + +.popover-arrow, .popover-arrow::after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover-arrow { + border-width: 11px; +} + +.popover-arrow::after { + content: ""; + border-width: 10px; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .carousel-item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} + +.carousel-inner > .carousel-item > img, +.carousel-inner > .carousel-item > a > img { + line-height: 1; +} + +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .carousel-item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: transform .6s ease-in-out, -o-transform .6s ease-in-out; + transition: -webkit-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + transition: transform .6s ease-in-out, -webkit-transform .6s ease-in-out, -o-transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .carousel-item.next, .carousel-inner > .carousel-item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .carousel-item.prev, .carousel-inner > .carousel-item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .carousel-item.next.left, .carousel-inner > .carousel-item.prev.right, .carousel-inner > .carousel-item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + opacity: .5; +} + +.carousel-control.left { + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} + +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} + +.carousel-control:focus, .carousel-control:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; +} + +.carousel-control .icon-prev, +.carousel-control .icon-next { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; + line-height: 1; +} + +.carousel-control .icon-prev { + left: 50%; + margin-left: -10px; +} + +.carousel-control .icon-next { + right: 50%; + margin-right: -10px; +} + +.carousel-control .icon-prev::before { + content: "\2039"; +} + +.carousel-control .icon-next::before { + content: "\203a"; +} + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} + +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: transparent; + border: 1px solid #fff; + border-radius: 10px; +} + +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} + +.carousel-caption .btn { + text-shadow: none; +} + +@media (min-width: 544px) { + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} + +.clearfix::after { + display: table; + clear: both; + content: ""; +} + +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} + +.pull-xs-left { + float: left !important; +} + +.pull-xs-right { + float: right !important; +} + +.pull-xs-none { + float: none !important; +} + +@media (min-width: 544px) { + .pull-sm-left { + float: left !important; + } + .pull-sm-right { + float: right !important; + } + .pull-sm-none { + float: none !important; + } +} + +@media (min-width: 768px) { + .pull-md-left { + float: left !important; + } + .pull-md-right { + float: right !important; + } + .pull-md-none { + float: none !important; + } +} + +@media (min-width: 992px) { + .pull-lg-left { + float: left !important; + } + .pull-lg-right { + float: right !important; + } + .pull-lg-none { + float: none !important; + } +} + +@media (min-width: 1200px) { + .pull-xl-left { + float: left !important; + } + .pull-xl-right { + float: right !important; + } + .pull-xl-none { + float: none !important; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} + +.invisible { + visibility: hidden !important; +} + +.text-hide { + font: "0/0" a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.text-justify { + text-align: justify !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-xs-left { + text-align: left !important; +} + +.text-xs-right { + text-align: right !important; +} + +.text-xs-center { + text-align: center !important; +} + +@media (min-width: 544px) { + .text-sm-left { + text-align: left !important; + } + .text-sm-right { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} + +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + .text-md-right { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} + +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + .text-lg-right { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} + +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + .text-xl-right { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.font-weight-normal { + font-weight: normal; +} + +.font-weight-bold { + font-weight: bold; +} + +.font-italic { + font-style: italic; +} + +.text-muted { + color: #b1b7bd; +} + +.text-primary { + color: #000 !important; +} + +a.text-primary:focus, a.text-primary:hover { + color: black; +} + +.text-success { + color: #64de79 !important; +} + +a.text-success:focus, a.text-success:hover { + color: #3ad555; +} + +.text-info { + color: #0500f0 !important; +} + +a.text-info:focus, a.text-info:hover { + color: #0400bd; +} + +.text-warning { + color: #a100fe !important; +} + +a.text-warning:focus, a.text-warning:hover { + color: #8100cb; +} + +.text-danger { + color: #ff0808 !important; +} + +a.text-danger:focus, a.text-danger:hover { + color: #d40000; +} + +.bg-inverse { + color: #eceeef; + background-color: #373a3c; +} + +.bg-faded { + background-color: #f7f7f9; +} + +.bg-primary { + color: #fff !important; + background-color: #000 !important; +} + +a.bg-primary:focus, a.bg-primary:hover { + background-color: black; +} + +.bg-success { + color: #fff !important; + background-color: #64de79 !important; +} + +a.bg-success:focus, a.bg-success:hover { + background-color: #3ad555; +} + +.bg-info { + color: #fff !important; + background-color: #0500f0 !important; +} + +a.bg-info:focus, a.bg-info:hover { + background-color: #0400bd; +} + +.bg-warning { + color: #fff !important; + background-color: #a100fe !important; +} + +a.bg-warning:focus, a.bg-warning:hover { + background-color: #8100cb; +} + +.bg-danger { + color: #fff !important; + background-color: #ff0808 !important; +} + +a.bg-danger:focus, a.bg-danger:hover { + background-color: #d40000; +} + +.m-x-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.m-a-0 { + margin: 0 0 !important; +} + +.m-t-0 { + margin-top: 0 !important; +} + +.m-r-0 { + margin-right: 0 !important; +} + +.m-b-0 { + margin-bottom: 0 !important; +} + +.m-l-0 { + margin-left: 0 !important; +} + +.m-x-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.m-y-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.m-a-1 { + margin: 1rem 1rem !important; +} + +.m-t-1 { + margin-top: 1rem !important; +} + +.m-r-1 { + margin-right: 1rem !important; +} + +.m-b-1 { + margin-bottom: 1rem !important; +} + +.m-l-1 { + margin-left: 1rem !important; +} + +.m-x-1 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.m-y-1 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.m-a-2 { + margin: 1.5rem 1.5rem !important; +} + +.m-t-2 { + margin-top: 1.5rem !important; +} + +.m-r-2 { + margin-right: 1.5rem !important; +} + +.m-b-2 { + margin-bottom: 1.5rem !important; +} + +.m-l-2 { + margin-left: 1.5rem !important; +} + +.m-x-2 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.m-y-2 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.m-a-3 { + margin: 3rem 3rem !important; +} + +.m-t-3 { + margin-top: 3rem !important; +} + +.m-r-3 { + margin-right: 3rem !important; +} + +.m-b-3 { + margin-bottom: 3rem !important; +} + +.m-l-3 { + margin-left: 3rem !important; +} + +.m-x-3 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.m-y-3 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.p-a-0 { + padding: 0 0 !important; +} + +.p-t-0 { + padding-top: 0 !important; +} + +.p-r-0 { + padding-right: 0 !important; +} + +.p-b-0 { + padding-bottom: 0 !important; +} + +.p-l-0 { + padding-left: 0 !important; +} + +.p-x-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.p-y-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.p-a-1 { + padding: 1rem 1rem !important; +} + +.p-t-1 { + padding-top: 1rem !important; +} + +.p-r-1 { + padding-right: 1rem !important; +} + +.p-b-1 { + padding-bottom: 1rem !important; +} + +.p-l-1 { + padding-left: 1rem !important; +} + +.p-x-1 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.p-y-1 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.p-a-2 { + padding: 1.5rem 1.5rem !important; +} + +.p-t-2 { + padding-top: 1.5rem !important; +} + +.p-r-2 { + padding-right: 1.5rem !important; +} + +.p-b-2 { + padding-bottom: 1.5rem !important; +} + +.p-l-2 { + padding-left: 1.5rem !important; +} + +.p-x-2 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.p-y-2 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.p-a-3 { + padding: 3rem 3rem !important; +} + +.p-t-3 { + padding-top: 3rem !important; +} + +.p-r-3 { + padding-right: 3rem !important; +} + +.p-b-3 { + padding-bottom: 3rem !important; +} + +.p-l-3 { + padding-left: 3rem !important; +} + +.p-x-3 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.p-y-3 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pos-f-t { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.hidden-xs-up { + display: none !important; +} + +@media (max-width: 543px) { + .hidden-xs-down { + display: none !important; + } +} + +@media (min-width: 544px) { + .hidden-sm-up { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-sm-down { + display: none !important; + } +} + +@media (min-width: 768px) { + .hidden-md-up { + display: none !important; + } +} + +@media (max-width: 991px) { + .hidden-md-down { + display: none !important; + } +} + +@media (min-width: 992px) { + .hidden-lg-up { + display: none !important; + } +} + +@media (max-width: 1199px) { + .hidden-lg-down { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-xl-up { + display: none !important; + } +} + +.hidden-xl-down { + display: none !important; +} + +.visible-print-block { + display: none !important; +} + +@media print { + .visible-print-block { + display: block !important; + } +} + +.visible-print-inline { + display: none !important; +} + +@media print { + .visible-print-inline { + display: inline !important; + } +} + +.visible-print-inline-block { + display: none !important; +} + +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} + +@media print { + .hidden-print { + display: none !important; + } +} + +a { + cursor: pointer; +} + +ul { + padding: 0 1rem; +} + +b, strong { + font-weight: 500; +} + +hr { + width: 66.666667%; + height: 1px; + margin-left: 0; + background-color: #000; + border-top: none; +} + +button:focus { + outline: none; +} + +h1, +h2, +h3 { + padding-top: 2rem; +} + +h4, +h5, +h6 { + padding-top: 1rem; +} + +h3, h4 { + line-height: 3rem; +} + +h5, h6 { + line-height: 2rem; +} + +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + font-weight: 400; +} + +.even, +h1:first-of-type { + padding-top: 0; + padding-bottom: 3rem; + margin-bottom: 0; +} + +h1.first, +h2.first, +h3.first { + padding-top: 0; + padding-bottom: 2rem; +} + +h1.child, +h2.child, +h3.child { + padding-bottom: 0; +} + +blockquote { + padding-left: 1rem; + font-style: italic; + color: #55595c; + border-left: 3px solid #b1b7bd; +} + +.gray { + color: #55595c; +} + +.gray-light { + color: #b1b7bd; +} + +.gray-lighter { + color: #eceeef; +} + +@media (max-width: 767px) { + h1 { + font-size: 2rem; + line-height: 3rem; + } + h2 { + font-size: 1.6rem; + } +} + +code, +pre { + background-color: #f7f7f7; +} + +pre { + padding: .6rem; +} + +p code { + padding: .2rem .1rem; +} + +pre code { + padding-left: 0; + margin-left: 0; + background-color: transparent; +} + +input, +textarea { + border: 0; + border-bottom: .2rem solid #b1b7bd; + outline: none; +} + +input:focus, +textarea:focus { + border-color: #000; +} + +.container.top { + padding-top: 3rem; +} + +.lead { + margin-bottom: 3rem; +} + +@media (max-width: 767px) { + .container { + padding-top: 0; + } + .lead { + margin-bottom: 1rem; + } +} + +.close { + font-size: 1rem; + font-weight: 300; + text-shadow: none; + opacity: 1; +} + +.btn { + font-weight: 500; + text-transform: uppercase; + letter-spacing: .06rem; + background-color: #fff; + border-width: 3px; +} + +.btn-primary { + color: #000; +} + +.red { + color: #ff0808; +} + +.green { + color: #64de79; +} + +.yellow { + color: #fff900; +} + +.blue { + color: #0500f0; +} + +.inverse, +.inverse:focus, +.inverse:hover { + color: #fff; +} + +.inverse.red { + background-color: #ff0808; +} + +.inverse.green { + background-color: #64de79; +} + +.inverse.yellow { + background-color: #fff900; +} + +.inverse.blue { + background-color: #0500f0; +} + +.block { + display: inline-block; + padding: .6rem; + font-weight: 500; +} + +.block:first-of-type { + padding-top: .6rem; +} + +.i-b { + display: inline-block; +} + +.action { + margin-top: 1rem; + font-weight: 500; + letter-spacing: 1px; +} + +.action > label { + margin-right: .9375rem; + line-height: 1rem; +} + +.action.create > label { + width: 16px; + height: 16px; + vertical-align: middle; + background-color: transparent; + border: 3px solid #000; + border-radius: 50%; +} + +.action.add > label:before { + font-size: 1.3rem; + font-weight: 500; + content: "+"; +} + +.mono { + font-family: 'scp'; +} + +h1.sign { + line-height: 2; + color: #a100fe; +} + +h2.advice { + font-size: 2rem; + line-height: 3rem; + color: #b1b7bd; +} + +p.ship { + white-space: nowrap; +} + +input#ship { + width: 66.7%; +} + +.sig, +#ship, +#pass { + font-size: 2rem; +} + +.sig { + margin-right: .3rem; +} + +#pass { + width: 100%; +} + +button#act { + font-size: 1.6rem; + font-weight: 500; + color: #fff; + text-decoration: underline; + background-color: #000; + border: 0; +} + +.lead .logo { + display: inline-block; + width: 3rem; + height: 3rem; + margin-right: 1rem; + text-align: center; + border-radius: 50%; +} + +@media (max-width: 991px) { + .lead .logo { + width: 3rem; + height: 3rem; + margin-right: 1rem; + font-size: 3.3rem; + line-height: 3.3rem; + border-radius: 3rem; + } +} + +@media (max-width: 767px) { + .lead .logo { + display: block; + margin-bottom: 1rem; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/web/tree/~.main_urb.js b/web/tree/~.main_urb.js new file mode 100644 index 0000000000..11160d348f --- /dev/null +++ b/web/tree/~.main_urb.js @@ -0,0 +1,3568 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { + index = keys.indexOf(this.props.curr); + next = index + 1; + if (next === keys.length) { + next = 0; + } + next = keys[next]; + next = this.props.kids[next]; + if (next) { + return div({ + className: "link-next" + }, a({ + href: this.props.path + "/" + next.name + }, "Next: " + next.meta.title)); + } + } + } + return div({}, ""); + } + })), + comments: Comments, + footer: recl({ + displayName: "Footer", + render: function() { + var containerClas, footerClas; + containerClas = clas({ + footer: true, + container: this.props.container === 'false' + }); + footerClas = clas({ + 'col-md-12': this.props.container === 'false' + }); + return div({ + className: containerClas, + key: 'footer-container' + }, [ + div({ + className: footerClas, + key: 'footer-inner' + }, [ + "This page was made by Urbit. ", a({ + href: "urbit.org" + }, "urbit.org"), a({ + href: "mailto:urbit@urbit.org" + }, "contact") + ]) + ]); + } + }) +}; + +module.exports = query({ + body: 'r', + name: 't', + path: 't', + meta: 'j', + sein: 't' +}, recl({ + displayName: "Body", + stateFromStore: function() { + return { + curr: TreeStore.getCurr() + }; + }, + getInitialState: function() { + return this.stateFromStore(); + }, + _onChangeStore: function() { + if (this.isMounted()) { + return this.setState(this.stateFromStore()); + } + }, + componentDidMount: function() { + return TreeStore.addChangeListener(this._onChangeStore); + }, + render: function() { + var bodyClas, extra, innerClas, parts, ref1; + extra = (function(_this) { + return function(name, props) { + if (props == null) { + props = {}; + } + if (_this.props.meta[name] != null) { + if ((_.keys(props)).length === 0) { + props[name] = _this.props.meta[name]; + } + props.key = name; + return React.createElement(extras[name], props); + } + }; + })(this); + innerClas = { + body: true + }; + if (this.props.meta.anchor !== 'none' && this.props.meta.navmode !== 'navbar') { + innerClas['col-md-9'] = true; + innerClas['col-md-offset-3'] = true; + } + if (this.props.meta.navmode === 'navbar' && this.props.meta.container !== 'false') { + innerClas['col-md-9'] = true; + innerClas['col-md-offset-1'] = true; + } + innerClas = clas(innerClas); + bodyClas = clas((ref1 = this.props.meta.layout) != null ? ref1.split(',') : void 0); + if (this.props.meta.type && bodyClas.indexOf(this.props.meta.type) === -1) { + bodyClas += " " + this.props.meta.type; + } + parts = [ + extra('spam'), extra('logo', { + color: this.props.meta.logo + }), reactify(this.props.body, 'body'), extra('next', { + dataPath: this.props.sein, + curr: this.props.name + }), extra('comments'), extra('footer', { + container: this.props.meta.container + }) + ]; + if (this.props.meta.type === "post") { + parts.splice(1, 0, extra('date'), extra('title'), extra('image'), extra('preview'), extra('author')); + } + return div({ + dataPath: this.state.curr, + key: this.state.curr + }, [ + div({ + className: innerClas, + 'data-path': this.props.path, + key: 'body-inner' + }, [ + div({ + key: "body" + this.props.path, + id: 'body', + className: bodyClas + }, parts) + ]) + ]); + } +}), recl({ + render: function() { + return div({ + id: 'body', + className: "col-md-offset-3 col-md-9" + }, rele(load)); + } +})); + + +},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":26,"../utils/util.coffee":28,"./Async.coffee":2,"./CommentsComponent.coffee":5,"./LoadComponent.coffee":12,"./Reactify.coffee":17,"classnames":29}],4:[function(require,module,exports){ +var div, recl, ref, textarea; + +recl = React.createClass; + +ref = React.DOM, div = ref.div, textarea = ref.textarea; + +module.exports = recl({ + render: function() { + return div({}, textarea({ + ref: 'ed', + value: this.props.value + })); + }, + componentDidMount: function() { + return CodeMirror.fromTextArea(ReactDOM.findDOMNode(this.refs.ed), { + readOnly: true, + lineNumbers: true + }); + } +}); + + +},{}],5:[function(require,module,exports){ +var Comment, TreeActions, a, clas, div, form, img, input, load, p, query, reactify, recl, ref, rele, textarea, util; + +clas = require('classnames'); + +load = require('./LoadComponent.coffee'); + +query = require('./Async.coffee'); + +reactify = require('./Reactify.coffee'); + +TreeActions = require('../actions/TreeActions.coffee'); + +util = require('../utils/util.coffee'); + +recl = React.createClass; + +rele = React.createElement; + +ref = React.DOM, div = ref.div, p = ref.p, img = ref.img, a = ref.a, form = ref.form, textarea = ref.textarea, input = ref.input; + +Comment = function(arg) { + var body, time; + time = arg.time, body = arg.body; + return div({ + className: "comment" + }, "" + (window.urb.util.toDate(new Date(time))), reactify(body)); +}; + +module.exports = query({ + comt: 'j', + path: 't' +}, recl({ + displayName: "Comments", + getInitialState: function() { + return { + loading: false, + value: "" + }; + }, + componentDidUpdate: function(_props) { + if (this.props.comt.length > _props.comt.length) { + return this.setState({ + loading: false + }); + } + }, + onSubmit: function(e) { + TreeActions.addComment(this.props.path, this.refs["in"].comment.value); + this.setState({ + loading: true, + value: "" + }); + return e.preventDefault(); + }, + onChange: function(e) { + return this.setState({ + value: e.target.value + }); + }, + render: function() { + var _attr, inputAttr, textareaAttr; + _attr = {}; + if (this.state.loading === true) { + _attr.disabled = "true"; + } + textareaAttr = _.create(_attr, { + type: "text", + name: "comment", + value: this.state.value, + onChange: this.onChange + }); + inputAttr = _.create(_attr, { + type: "submit", + value: "Add comment", + className: "btn btn-primary" + }); + return div({}, div({ + className: "add-comment" + }, form({ + ref: "in", + onSubmit: this.onSubmit + }, textarea(textareaAttr), input(inputAttr))), (this.state.loading === true ? rele(load) : ""), div({ + className: "comments" + }, this.props.comt.map(function(props, key) { + return rele(Comment, _.extend({ + key: key + }, props)); + }))); + } +})); + + +},{"../actions/TreeActions.coffee":1,"../utils/util.coffee":28,"./Async.coffee":2,"./LoadComponent.coffee":12,"./Reactify.coffee":17,"classnames":29}],6:[function(require,module,exports){ +var div, recl; + +recl = React.createClass; + +div = React.DOM.div; + +module.exports = { + codemirror: require('./CodeMirror.coffee'), + search: require('./SearchComponent.coffee'), + list: require('./ListComponent.coffee'), + kids: require('./KidsComponent.coffee'), + toc: require('./TocComponent.coffee'), + email: require('./EmailComponent.coffee'), + module: require('./ModuleComponent.coffee'), + script: require('./ScriptComponent.coffee'), + plan: require('./PlanComponent.coffee'), + panel: require('./PanelComponent.coffee'), + imagepanel: require('./ImagepanelComponent.coffee'), + lost: recl({ + render: function() { + return div({}, ""); + } + }) +}; + + +},{"./CodeMirror.coffee":4,"./EmailComponent.coffee":8,"./ImagepanelComponent.coffee":9,"./KidsComponent.coffee":10,"./ListComponent.coffee":11,"./ModuleComponent.coffee":13,"./PanelComponent.coffee":15,"./PlanComponent.coffee":16,"./ScriptComponent.coffee":18,"./SearchComponent.coffee":19,"./TocComponent.coffee":21}],7:[function(require,module,exports){ +var a, div, recl, ref, util; + +util = require('../utils/util.coffee'); + +recl = React.createClass; + +ref = React.DOM, div = ref.div, a = ref.a; + +module.exports = recl({ + displayName: "Dpad", + renderUp: function() { + if (this.props.sein) { + return this.renderArrow("up", this.props.sein); + } + }, + renderArrow: function(name, path) { + var href; + href = util.basepath(path); + return a({ + href: href, + key: "" + name, + className: "" + name + }, ""); + }, + renderArrows: function() { + var index, keys, next, prev, sein; + keys = util.getKeys(this.props.kids); + if (keys.length > 1) { + index = keys.indexOf(this.props.curr); + prev = index - 1; + next = index + 1; + if (prev < 0) { + prev = keys.length - 1; + } + if (next === keys.length) { + next = 0; + } + prev = keys[prev]; + next = keys[next]; + } + if (this.props.sein) { + sein = this.props.sein; + if (sein === "/") { + sein = ""; + } + return div({}, prev ? this.renderArrow("prev", sein + "/" + prev) : void 0, next ? this.renderArrow("next", sein + "/" + next) : void 0); + } + }, + render: function() { + return div({ + className: 'dpad', + key: 'dpad' + }, this.renderUp(), this.renderArrows()); + } +}); + + +},{"../utils/util.coffee":28}],8:[function(require,module,exports){ +var button, div, input, p, reactify, recl, ref; + +reactify = require('./Reactify.coffee'); + +recl = React.createClass; + +ref = React.DOM, div = ref.div, p = ref.p, button = ref.button, input = ref.input; + +module.exports = recl({ + displayName: "email", + getInitialState: function() { + return { + submit: false, + email: "" + }; + }, + onClick: function() { + return this.submit(); + }, + onChange: function(e) { + var email, valid; + email = e.target.value; + this.setState({ + email: e.target.value + }); + valid = email.indexOf('@') !== -1 && email.indexOf('.') !== -1 && email.length > 7 && email.split(".")[1].length > 1 && email.split("@")[0].length > 0 && email.split("@")[1].length > 4; + this.$email.toggleClass('valid', valid); + this.$email.removeClass('error'); + if (e.keyCode === 13) { + if (valid === true) { + this.submit(); + e.stopPropagation(); + e.preventDefault(); + return false; + } else { + return this.$email.addClass('error'); + } + } + }, + submit: function() { + return $.post(this.props.dataPath, { + email: this.$email.val() + }, (function(_this) { + return function() { + return _this.setState({ + submit: true + }); + }; + })(this)); + }, + componentDidMount: function() { + return this.$email = $('input.email'); + }, + render: function() { + var cont, ref1, submit; + if (this.state.submit === false) { + submit = (ref1 = this.props.submit) != null ? ref1 : "Sign up"; + cont = [ + input({ + key: "field", + className: "email", + placeholder: "your@email.com", + onChange: this.onChange, + value: this.state.email + }), button({ + key: "submit", + className: "submit btn", + onClick: this.onClick + }, submit) + ]; + } else { + cont = [ + div({ + className: "submitted" + }, "Got it. Thanks!") + ]; + } + return p({ + className: "email", + id: "sign-up" + }, cont); + } +}); + + +},{"./Reactify.coffee":17}],9:[function(require,module,exports){ +var div, recl; + +recl = React.createClass; + +div = React.DOM.div; + +module.exports = recl({ + displayName: "ImagePanel", + render: function() { + return div({ + className: "image-container", + style: { + backgroundImage: "url('" + this.props.src + "')" + } + }); + } +}); + + +},{}],10:[function(require,module,exports){ +var a, clas, div, hr, li, query, reactify, recl, ref, ul; + +clas = require('classnames'); + +reactify = require('./Reactify.coffee'); + +query = require('./Async.coffee'); + +recl = React.createClass; + +ref = React.DOM, div = ref.div, a = ref.a, ul = ref.ul, li = ref.li, hr = ref.hr; + +module.exports = query({ + kids: { + body: 'r', + meta: 'j', + path: 't' + } +}, recl({ + displayName: "Kids", + render: function() { + var _k, body, d, elem, k, keyed, keys, kidClas, kidsClas, ref1, ref2, ref3, ref4, sorted, str, v; + sorted = true; + keyed = {}; + ref1 = this.props.kids; + for (k in ref1) { + v = ref1[k]; + if (this.props.sortBy) { + if (this.props.sortBy === 'date') { + if (((ref2 = v.meta) != null ? ref2.date : void 0) == null) { + sorted = false; + continue; + } + d = v.meta.date.slice(1).split("."); + if (d.length < 3) { + sorted = false; + continue; + } + str = d[0] + "-" + d[1] + "-" + d[2]; + if (d.length > 3) { + str += " " + d[3] + ":" + d[4] + ":" + d[5]; + } + _k = Number(new Date(str)); + keyed[_k] = k; + } + } else { + if (((ref3 = v.meta) != null ? ref3.sort : void 0) == null) { + sorted = false; + } + keyed[Number((ref4 = v.meta) != null ? ref4.sort : void 0)] = k; + } + } + if (sorted === false) { + keyed = _.keys(this.props.kids); + } + keys = _.keys(keyed).sort(); + if (this.props.sortBy === 'date') { + keys.reverse(); + } + kidsClas = clas({ + kids: true + }, this.props.className); + kidClas = clas({ + "col-md-4": this.props.grid === 'true' + }); + return div({ + className: kidsClas, + key: "kids" + }, (function() { + var i, len, ref5, results; + results = []; + for (i = 0, len = keys.length; i < len; i++) { + k = keys[i]; + elem = (ref5 = this.props.kids[keyed[k]]) != null ? ref5 : ""; + body = reactify(elem.body, k, { + basePath: elem.path + }); + results.push([ + div({ + key: keyed[k], + id: keyed[k], + className: kidClas + }, body), hr({}) + ]); + } + return results; + }).call(this)); + } +})); + + +},{"./Async.coffee":2,"./Reactify.coffee":17,"classnames":29}],11:[function(require,module,exports){ +var a, clas, div, h1, li, pre, query, reactify, recl, ref, span, ul, util; + +clas = require('classnames'); + +reactify = require('./Reactify.coffee'); + +query = require('./Async.coffee'); + +util = require('../utils/util.coffee'); + +recl = React.createClass; + +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', + kids: { + snip: 'r', + head: 'r', + meta: 'j' + } +}, recl({ + displayName: "List", + render: function() { + var k, kids; + k = clas({ + list: true + }, this.props.dataType, { + "default": this.props['data-source'] === 'default' + }, this.props.className); + kids = this.renderList(); + if (!(kids.length === 0 && (this.props.is404 != null))) { + return ul({ + className: k + }, kids); + } + return div({ + className: k + }, h1({ + className: 'red inverse block error' + }, 'Error: Empty path'), div({}, pre({}, this.props.path), span({}, 'is either empty or does not exist.'))); + }, + renderList: function() { + var _date, _k, _keys, author, date, elem, href, i, image, item, k, len, linked, node, parts, path, preview, ref1, ref2, ref3, ref4, ref5, ref6, results, sorted, title, v; + sorted = true; + _keys = []; + ref1 = this.props.kids; + for (k in ref1) { + v = ref1[k]; + if (this.props.sortBy) { + if (this.props.sortBy === 'date') { + if (((ref2 = v.meta) != null ? ref2.date : void 0) == null) { + sorted = false; + } + _k = Number(v.meta.date.slice(1).replace(/\./g, "")); + _keys[_k] = k; + } + } else { + if (((ref3 = v.meta) != null ? ref3.sort : void 0) == null) { + sorted = false; + } + _keys[Number((ref4 = v.meta) != null ? ref4.sort : void 0)] = k; + } + } + if (this.props.sortBy === 'date') { + _keys.reverse(); + } + if (sorted !== true) { + _keys = _.keys(this.props.kids).sort(); + } + if (this.props.dataType === 'post') { + _keys = _keys.reverse(); + } + ref5 = _.values(_keys); + results = []; + for (i = 0, len = ref5.length; i < len; i++) { + item = ref5[i]; + path = this.props.path + "/" + item; + elem = this.props.kids[item]; + if (elem.meta.hide != null) { + continue; + } + href = util.basepath(path); + if (this.props.linkToFragments != null) { + href = "#" + item; + } + if (this.props.childIsFragment != null) { + href = (util.basepath(this.props.path)) + "#" + item; + } + if (elem.meta.link) { + href = elem.meta.link; + } + parts = []; + title = null; + if ((ref6 = elem.meta) != null ? ref6.title : void 0) { + if (this.props.dataType === 'post') { + title = { + gn: 'a', + ga: { + href: href + }, + c: [ + { + gn: 'h1', + ga: { + className: 'title' + }, + c: [elem.meta.title] + } + ] + }; + } else { + title = { + gn: 'h1', + ga: { + className: 'title' + }, + c: [elem.meta.title] + }; + } + } + if (!title && elem.head.c.length > 0) { + title = elem.head; + } + if (!title) { + title = { + gn: 'h1', + ga: { + className: 'title' + }, + c: [item] + }; + } + if (!this.props.titlesOnly) { + _date = elem.meta.date; + if (!_date || _date.length === 0) { + _date = ""; + } + date = { + gn: 'div', + ga: { + className: 'date' + }, + c: [_date] + }; + parts.push(date); + } + parts.push(title); + if (!this.props.titlesOnly) { + if (this.props.dataType === 'post') { + if (elem.meta.image) { + image = { + gn: 'a', + ga: { + href: href + }, + c: [ + { + gn: 'img', + ga: { + src: elem.meta.image + } + } + ] + }; + parts.push(image); + } + } + if (this.props.dataPreview) { + if (!elem.meta.preview) { + parts.push.apply(parts, elem.snip.c.slice(0, 2)); + } else { + if (elem.meta.preview) { + preview = { + gn: 'p', + ga: { + className: 'preview' + }, + c: [elem.meta.preview] + }; + } else { + preview = elem.snip; + } + parts.push(preview); + } + } + if (this.props.dataType === 'post') { + if (elem.meta.author) { + author = { + gn: 'h3', + ga: { + className: 'author' + }, + c: [elem.meta.author] + }; + parts.push(author); + } + linked = true; + } + } + node = reactify({ + gn: 'div', + c: parts + }); + if (linked == null) { + node = a({ + href: href, + className: clas({ + preview: this.props.dataPreview != null + }) + }, node); + } + results.push(li({ + key: item + }, node)); + } + return results; + } +})); + + +},{"../utils/util.coffee":28,"./Async.coffee":2,"./Reactify.coffee":17,"classnames":29}],12:[function(require,module,exports){ +var div, recl, ref, span; + +recl = React.createClass; + +ref = React.DOM, span = ref.span, div = ref.div; + +module.exports = recl({ + displayName: "Load", + getInitialState: function() { + return { + anim: 0 + }; + }, + componentDidMount: function() { + return this.interval = setInterval(this.setAnim, 100); + }, + componentWillUnmount: function() { + return clearInterval(this.interval); + }, + setAnim: function() { + var anim; + anim = this.state.anim + 1; + if (anim > 3) { + anim = 0; + } + return this.setState({ + anim: anim + }); + }, + render: function() { + return span({ + className: "loading state-" + this.state.anim + }, ''); + } +}); + + +},{}],13:[function(require,module,exports){ +var TreeActions, div, recl; + +recl = React.createClass; + +div = React.DOM.div; + +TreeActions = require('../actions/TreeActions.coffee'); + +module.exports = recl({ + displayName: "Module", + componentDidMount: function() { + return setTimeout((function(_this) { + return function() { + return TreeActions.setNav({ + title: _this.props["nav:title"], + dpad: _this.props["nav:no-dpad"] != null ? false : void 0, + sibs: _this.props["nav:no-sibs"] != null ? false : void 0, + subnav: _this.props["nav:subnav"] + }, 0); + }; + })(this)); + }, + componentWillUnmount: function() { + return TreeActions.clearNav(); + }, + render: function() { + return div({ + className: "module" + }, this.props.children); + } +}); + + +},{"../actions/TreeActions.coffee":1}],14:[function(require,module,exports){ +var BodyComponent, Dpad, Nav, Sibs, TreeActions, TreeStore, a, button, clas, div, li, query, reactify, recl, ref, rend, ul, util; + +clas = require('classnames'); + +BodyComponent = React.createFactory(require('./BodyComponent.coffee')); + +query = require('./Async.coffee'); + +reactify = require('./Reactify.coffee'); + +TreeStore = require('../stores/TreeStore.coffee'); + +TreeActions = require('../actions/TreeActions.coffee'); + +Sibs = React.createFactory(require('./SibsComponent.coffee')); + +Dpad = React.createFactory(require('./DpadComponent.coffee')); + +util = require('../utils/util.coffee'); + +recl = React.createClass; + +rend = ReactDOM.render; + +ref = React.DOM, div = ref.div, a = ref.a, ul = ref.ul, li = ref.li, button = ref.button; + +Nav = React.createFactory(query({ + path: 't', + kids: { + name: 't', + head: 'r', + meta: 'j' + } +}, recl({ + displayName: "Links", + stateFromStore: function() { + return TreeStore.getNav(); + }, + getInitialState: function() { + return this.stateFromStore(); + }, + _onChangeStore: function() { + if (this.isMounted()) { + return this.setState(this.stateFromStore()); + } + }, + componentDidMount: function() { + return TreeStore.addChangeListener(this._onChangeStore); + }, + componentWillUnmount: function() { + return TreeStore.removeChangeListener(this._onChangeStore); + }, + onClick: function() { + return this.toggleFocus(); + }, + onMouseOver: function() { + return this.toggleFocus(true); + }, + onMouseOut: function() { + return this.toggleFocus(false); + }, + onTouchStart: function() { + return this.ts = Number(Date.now()); + }, + onTouchEnd: function() { + var dt; + return dt = this.ts - Number(Date.now()); + }, + _home: function() { + return this.props.goTo(this.props.meta.navhome ? this.props.meta.navhome : "/"); + }, + toggleFocus: function(state) { + return $(ReactDOM.findDOMNode(this)).toggleClass('focus', state); + }, + toggleNav: function() { + return TreeActions.toggleNav(); + }, + closeNav: function() { + return TreeActions.closeNav(); + }, + render: function() { + var attr, dpad, i, iconClass, itemsClass, len, linksClas, navClas, ref1, ref2, ref3, sibs, sub, subprops, title, toggleClas, v; + attr = { + onMouseOver: this.onMouseOver, + onMouseOut: this.onMouseOut, + onClick: this.onClick, + onTouchStart: this.onTouchStart, + onTouchEnd: this.onTouchEnd, + 'data-path': this.props.dataPath + }; + if (_.keys(window).indexOf("ontouchstart") !== -1) { + delete attr.onMouseOver; + delete attr.onMouseOut; + } + linksClas = clas({ + links: true, + subnav: (this.props.meta.navsub != null) + }); + navClas = { + navbar: this.props.meta.navmode === 'navbar', + ctrl: true, + open: this.state.open === true + }; + if (this.props.meta.layout) { + ref1 = this.props.meta.layout.split(","); + for (i = 0, len = ref1.length; i < len; i++) { + v = ref1[i]; + navClas[v.trim()] = true; + } + } + navClas = clas(navClas); + iconClass = clas({ + icon: true, + 'col-md-1': this.props.meta.navmode === 'navbar' + }); + attr = _.extend(attr, { + className: navClas, + key: "nav" + }); + title = this.state.title ? this.state.title : ""; + dpad = this.state.dpad !== false && ((ref2 = this.props.meta) != null ? ref2.navdpad : void 0) !== "false" ? Dpad(this.props, "") : ""; + sibs = this.state.sibs !== false && ((ref3 = this.props.meta) != null ? ref3.navsibs : void 0) !== "false" ? Sibs(_.merge(_.clone(this.props), { + closeNav: this.closeNav + }), "") : ""; + itemsClass = clas({ + items: true, + 'col-md-11': this.props.meta.navmode === 'navbar' + }); + if (this.props.meta.navsub) { + subprops = _.cloneDeep(this.props); + subprops.dataPath = subprops.meta.navsub; + delete subprops.meta.navselect; + subprops.className = 'subnav'; + sub = Sibs(_.merge(subprops, { + toggleNav: this.toggleNav + }), ""); + } + toggleClas = clas({ + 'navbar-toggler': true, + show: this.state.subnav != null + }); + return div(attr, div({ + className: linksClas, + key: "links" + }, div({ + className: iconClass + }, div({ + className: 'home', + onClick: this._home + }, ""), div({ + className: 'app' + }, title), dpad, button({ + className: toggleClas, + type: 'button', + onClick: this.toggleNav + }, "☰")), div({ + className: itemsClass + }, sibs, sub))); + } +}), recl({ + displayName: "Links_loading", + _home: function() { + return this.props.goTo("/"); + }, + render: function() { + return div({ + className: "ctrl", + "data-path": this.props.dataPath, + key: "nav-loading" + }, div({ + className: 'links' + }, div({ + className: 'icon' + }, div({ + className: 'home', + onClick: this._home + }, "")), ul({ + className: "nav" + }, li({ + className: "nav-item selected" + }, a({ + className: "nav-link" + }, this.props.curr))))); + } +}))); + +module.exports = query({ + sein: 't', + path: 't', + name: 't', + meta: 'j' +}, recl({ + displayName: "Nav", + stateFromStore: function() { + return TreeStore.getNav(); + }, + getInitialState: function() { + return _.extend(this.stateFromStore(), { + url: window.location.pathname + }); + }, + _onChangeStore: function() { + if (this.isMounted()) { + return this.setState(this.stateFromStore()); + } + }, + componentWillUnmount: function() { + clearInterval(this.interval); + $('body').off('click', 'a'); + return TreeStore.removeChangeListener(this._onChangeStore); + }, + componentDidUpdate: function() { + this.setTitle(); + return this.checkRedirect(); + }, + componentDidMount: function() { + var _this; + this.setTitle(); + window.onpopstate = this.pullPath; + TreeStore.addChangeListener(this._onChangeStore); + _this = this; + $('body').on('click', 'a', function(e) { + var href, url; + href = $(this).attr('href'); + if ((href != null ? href[0] : void 0) === "#") { + return true; + } + if (href && !/^https?:\/\//i.test(href)) { + e.preventDefault(); + url = new URL(this.href); + if (urb.util.basepath("", url.pathname) !== urb.util.basepath("", document.location.pathname)) { + document.location = this.href; + return; + } + if (url.pathname.substr(-1) !== "/") { + url.pathname += "/"; + } + return _this.goTo(url.pathname + url.search + url.hash); + } + }); + return this.checkRedirect(); + }, + checkRedirect: function() { + if (this.props.meta.redirect) { + return setTimeout(((function(_this) { + return function() { + return _this.goTo(_this.props.meta.redirect); + }; + })(this)), 0); + } + }, + setTitle: function() { + var path, ref1, title; + title = $('#body h1').first().text() || this.props.name; + if ((ref1 = this.props.meta) != null ? ref1.title : void 0) { + title = this.props.meta.title; + } + path = this.props.path; + if (path === "") { + path = "/"; + } + return document.title = title + " - " + path; + }, + pullPath: function() { + var l, path; + l = document.location; + path = l.pathname + l.search + l.hash; + return this.setPath(path, false); + }, + setPath: function(path, hist) { + var next; + if (hist !== false) { + history.pushState({}, "", path); + } + next = util.fragpath(path.split('#')[0]); + if (next !== this.props.path) { + return TreeActions.setCurr(next); + } + }, + reset: function() { + return $("html,body").animate({ + scrollTop: 0 + }); + }, + goTo: function(path) { + this.reset(); + return this.setPath(path); + }, + render: function() { + var kids, kidsPath, navClas; + if (this.props.meta.anchor === 'none') { + return div({}, ""); + } + navClas = clas({ + container: this.props.meta.container === 'false' + }); + kidsPath = this.props.sein; + if (this.props.meta.navpath) { + kidsPath = this.props.meta.navpath; + } + kids = [ + Nav({ + curr: this.props.name, + dataPath: kidsPath, + meta: this.props.meta, + sein: this.props.sein, + goTo: this.goTo, + key: "nav" + }, "div") + ]; + if (this.state.subnav) { + kids.push(reactify({ + gn: this.state.subnav, + ga: { + open: this.state.open, + toggle: TreeActions.toggleNav + }, + c: [] + }, "subnav")); + } + return div({ + id: 'head', + className: navClas + }, kids); + } +})); + + +},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":26,"../utils/util.coffee":28,"./Async.coffee":2,"./BodyComponent.coffee":3,"./DpadComponent.coffee":7,"./Reactify.coffee":17,"./SibsComponent.coffee":20,"classnames":29}],15:[function(require,module,exports){ +var a, li, nav, recl, ref, rele, ul; + +recl = React.createClass; + +rele = React.createElement; + +ref = React.DOM, nav = ref.nav, ul = ref.ul, li = ref.li, a = ref.a; + +module.exports = recl({ + render: function() { + if (urb.user !== urb.ship) { + return nav({ + className: "navbar panel" + }, [ + ul({ + className: "nav navbar-nav" + }, [ + li({ + className: 'nav-item pull-right' + }, a({ + href: "/~~" + }, "Log in")) + ]) + ]); + } else { + return nav({ + className: "navbar panel" + }, [ + ul({ + className: "nav navbar-nav" + }, [ + li({ + className: "nav-item" + }, a({ + href: "/~~/talk" + }, "Talk")), li({ + className: "nav-item" + }, a({ + href: "/~~/dojo" + }, "Dojo")), li({ + className: "nav-item" + }, a({ + href: "/~~/static" + }, "Static")), li({ + className: 'nav-item pull-right' + }, a({ + href: "/~/away" + }, "Log out")) + ]) + ]); + } + } +}); + + +},{}],16:[function(require,module,exports){ +var Grid, TreeActions, a, button, code, div, h6, input, load, query, recl, ref1, ref2, rele, span, table, tbody, td, textarea, tr, + slice = [].slice; + +load = require('./LoadComponent.coffee'); + +query = require('./Async.coffee'); + +TreeActions = require('../actions/TreeActions.coffee'); + +recl = React.createClass; + +rele = React.createElement; + +ref1 = React.DOM, div = ref1.div, textarea = ref1.textarea, button = ref1.button, input = ref1.input, a = ref1.a, h6 = ref1.h6, code = ref1.code, span = ref1.span; + +ref2 = React.DOM, table = ref2.table, tbody = ref2.tbody, tr = ref2.tr, td = ref2.td; + +Grid = function() { + var _td, _tr, props, rows; + props = arguments[0], rows = 2 <= arguments.length ? slice.call(arguments, 1) : []; + _td = function(x) { + return div({ + className: "td" + }, x); + }; + _tr = function(x) { + if (x != null) { + return div.apply(null, [{ + className: "tr" + }].concat(slice.call(x.map(_td)))); + } + }; + return div.apply(null, [props].concat(slice.call(rows.map(_tr)))); +}; + +module.exports = query({ + plan: 'j', + beak: 't', + path: 't' +}, recl({ + displayName: "Plan", + getInitialState: function() { + return { + edit: false, + plan: this.props.plan, + focus: null + }; + }, + componentWillReceiveProps: function(props) { + if (_.isEqual(this.props.plan, this.state.plan)) { + return this.setState({ + plan: props.plan + }); + } + }, + refInput: function(ref) { + return (function(_this) { + return function(node) { + _this[ref] = node; + if (ref === _this.state.focus) { + return node != null ? node.focus() : void 0; + } + }; + })(this); + }, + saveInfo: function() { + var plan, ref3; + plan = { + who: this.who.value, + loc: this.loc.value, + acc: (ref3 = this.props.plan) != null ? ref3.acc : void 0 + }; + if (!_.isEqual(plan, this.state.plan)) { + TreeActions.setPlanInfo(plan); + this.setState({ + plan: plan + }); + } + return this.setState({ + edit: false, + focus: null + }); + }, + render: function() { + var acc, beak, editButton, editable, issuedBy, key, loc, path, ref3, ref4, ref5, url, usr, who; + ref3 = this.props, beak = ref3.beak, path = ref3.path; + ref5 = (ref4 = this.state.plan) != null ? ref4 : {}, acc = ref5.acc, loc = ref5.loc, who = ref5.who; + issuedBy = urb.sein !== urb.ship ? "~" + urb.sein : "self"; + if (urb.user !== urb.ship) { + editButton = null; + editable = function(ref, val, placeholder) { + return val != null ? val : placeholder; + }; + } else if (this.state.edit) { + editButton = button({ + className: 'edit', + onClick: (function(_this) { + return function() { + return _this.saveInfo(); + }; + })(this) + }, "Save"); + editable = (function(_this) { + return function(ref, val, placeholder) { + return input({ + placeholder: placeholder, + defaultValue: val, + ref: _this.refInput(ref), + onKeyDown: function(arg) { + var keyCode; + keyCode = arg.keyCode; + if (keyCode === 13) { + return _this.saveInfo(); + } + } + }); + }; + })(this); + } else { + editButton = button({ + className: 'edit', + onClick: (function(_this) { + return function() { + return _this.setState({ + edit: true + }); + }; + })(this) + }, "Edit"); + editable = (function(_this) { + return function(ref, val, placeholder) { + var ref6, ref7; + return span({ + onClick: function() { + return _this.setState({ + edit: true, + focus: ref + }); + } + }, val != null ? val : placeholder, ((ref6 = _this.props.plan) != null ? ref6[ref] : void 0) !== ((ref7 = _this.state.plan) != null ? ref7[ref] : void 0) ? rele(load, {}) : void 0); + }; + })(this); + } + return div({ + className: "plan" + }, div({ + className: "home" + }, ""), div({ + className: "mono" + }, "~" + urb.ship), (who != null) || this.state.edit ? h6({}, editable('who', who, "Sun Tzu")) : void 0, Grid({ + className: "grid" + }, ["Location:", editable('loc', loc, "Unknown")], ["Issued by:", issuedBy], [ + "Immutable link:", a({ + href: beak + "/web" + path + }, beak) + ], !_.isEmpty(acc) ? [ + "Connected to:", div({}, (function() { + var ref6, results; + results = []; + for (key in acc) { + ref6 = acc[key], usr = ref6.usr, url = ref6.url; + results.push(div({ + key: key, + className: 'service' + }, url == null ? key + "/" + usr : a({ + href: url + }, key + "/" + usr))); + } + return results; + })()) + ] : void 0), editButton); + } +})); + + +},{"../actions/TreeActions.coffee":1,"./Async.coffee":2,"./LoadComponent.coffee":12}],17:[function(require,module,exports){ +var TreeStore, Virtual, div, load, reactify, recl, ref, rele, span, walk; + +recl = React.createClass; + +rele = React.createElement; + +ref = React.DOM, div = ref.div, span = ref.span; + +load = React.createFactory(require('./LoadComponent.coffee')); + +TreeStore = require('../stores/TreeStore.coffee'); + +walk = function(root, _nil, _str, _comp) { + var _walk; + _walk = function(elem, key) { + var c, ga, gn, ref1; + switch (false) { + case !(elem == null): + return _nil(); + case typeof elem !== "string": + return _str(elem); + case elem.gn == null: + gn = elem.gn, ga = elem.ga, c = elem.c; + c = (ref1 = c != null ? c.map(_walk) : void 0) != null ? ref1 : []; + return _comp.call(elem, { + gn: gn, + ga: ga, + c: c + }, key); + default: + throw "Bad react-json " + (JSON.stringify(elem)); + } + }; + return _walk(root); +}; + +Virtual = recl({ + displayName: "Virtual", + getInitialState: function() { + return this.stateFromStore(); + }, + stateFromStore: function() { + return { + components: TreeStore.getVirtualComponents() + }; + }, + _onChangeStore: function() { + if (this.isMounted()) { + return this.setState(this.stateFromStore()); + } + }, + componentDidMount: function() { + return TreeStore.addChangeListener(this._onChangeStore); + }, + componentWillUnmount: function() { + return TreeStore.removeChangeListener(this._onChangeStore); + }, + render: function() { + var basePath, components; + components = this.state.components; + basePath = this.props.basePath; + return walk(this.props.manx, function() { + return load({}, ""); + }, function(str) { + return str; + }, function(arg, key) { + var c, e, error, ga, gn, props, ref1; + gn = arg.gn, ga = arg.ga, c = arg.c; + props = { + key: key + }; + if (ga != null ? ga.style : void 0) { + try { + ga.style = eval("(" + ga.style + ")"); + } catch (error) { + e = error; + ga.style = ga.style; + } + } + if (components[gn]) { + props.basePath = basePath; + } + return rele((ref1 = components[gn]) != null ? ref1 : gn, _.extend(props, ga), c.length ? c : void 0); + }); + } +}); + +reactify = function(manx, key, arg) { + var basePath; + basePath = (arg != null ? arg : {}).basePath; + return rele(Virtual, { + manx: manx, + key: key, + basePath: basePath + }); +}; + +module.exports = _.extend(reactify, { + walk: walk, + Virtual: Virtual +}); + + +},{"../stores/TreeStore.coffee":26,"./LoadComponent.coffee":12}],18:[function(require,module,exports){ +var appendNext, recl, rele, waitingScripts; + +recl = React.createClass; + +rele = React.createElement; + +waitingScripts = null; + +appendNext = function() { + if (waitingScripts == null) { + return; + } + if (waitingScripts.length === 0) { + return waitingScripts = null; + } else { + return document.body.appendChild(waitingScripts.shift()); + } +}; + +module.exports = recl({ + displayName: "Script", + componentDidMount: function() { + var s; + s = document.createElement('script'); + _.assign(s, this.props); + urb.waspElem(s); + s.onload = appendNext; + this.js = s; + if (waitingScripts != null) { + return waitingScripts.push(s); + } else { + waitingScripts = [s]; + return appendNext(); + } + }, + componentWillUnmount: function() { + if (this.js.parentNode === document.body) { + return document.body.removeChild(this.js); + } + }, + render: function() { + return rele("script", this.props); + } +}); + + +},{}],19:[function(require,module,exports){ +var a, div, input, query, reactify, recl, ref, + slice = [].slice; + +query = require('./Async.coffee'); + +reactify = require('./Reactify.coffee'); + +recl = React.createClass; + +ref = React.DOM, a = ref.a, div = ref.div, input = ref.input; + +module.exports = query({ + name: 't', + kids: { + sect: 'j' + } +}, recl({ + hash: null, + displayName: "Search", + getInitialState: function() { + return { + search: 'wut' + }; + }, + onKeyUp: function(e) { + return this.setState({ + search: e.target.value + }); + }, + wrap: function(elem, dir, path) { + var c, ga, gn, href, ref1; + if (path.slice(-1) === "/") { + path = path.slice(0, -1); + } + href = this.props.name + "/" + dir + path; + if (elem != null ? (ref1 = elem.ga) != null ? ref1.id : void 0 : void 0) { + gn = elem.gn, ga = elem.ga, c = elem.c; + ga = _.clone(ga); + href += "#" + ga.id; + delete ga.id; + elem = { + gn: gn, + ga: ga, + c: c + }; + } + return { + gn: 'div', + c: [ + { + gn: 'a', + ga: { + href: href + }, + c: [elem] + } + ] + }; + }, + render: function() { + return div({}, input({ + onKeyUp: this.onKeyUp, + ref: 'inp', + defaultValue: 'wut' + }), _(this.props.kids).map((function(_this) { + return function(arg, dir) { + var h, heds, path, results, sect; + sect = arg.sect; + results = []; + for (path in sect) { + heds = sect[path]; + results.push((function() { + var i, len, results1; + results1 = []; + for (i = 0, len = heds.length; i < len; i++) { + h = heds[i]; + results1.push(this.wrap(h, dir, path)); + } + return results1; + }).call(_this)); + } + return results; + }; + })(this)).flatten().flatten().map(this.highlight).filter().take(50).map(reactify).value()); + }, + highlight: function(e) { + var got, res; + if (!this.state.search) { + return e; + } + got = false; + res = reactify.walk(e, function() { + return null; + }, (function(_this) { + return function(s) { + var lit, m; + m = s.split(_this.state.search); + if (m[1] == null) { + return [s]; + } + lit = { + gn: 'span', + c: [_this.state.search], + ga: { + style: { + background: '#ff6' + } + } + }; + got = true; + return [m[0]].concat(slice.call(_.flatten((function() { + var i, len, ref1, results; + ref1 = m.slice(1); + results = []; + for (i = 0, len = ref1.length; i < len; i++) { + s = ref1[i]; + results.push([lit, s]); + } + return results; + })()))); + }; + })(this), function(arg) { + var c, ga, gn; + gn = arg.gn, ga = arg.ga, c = arg.c; + return { + gn: gn, + ga: ga, + c: _.flatten(c) + }; + }); + if (got) { + return res; + } + } +})); + + +},{"./Async.coffee":2,"./Reactify.coffee":17}],20:[function(require,module,exports){ +var a, clas, li, query, reactify, recl, ref, ul, util; + +util = require('../utils/util.coffee'); + +clas = require('classnames'); + +reactify = require('./Reactify.coffee'); + +query = require('./Async.coffee'); + +recl = React.createClass; + +ref = React.DOM, ul = ref.ul, li = ref.li, a = ref.a; + +module.exports = query({ + path: 't', + kids: { + head: 'r', + meta: 'j' + } +}, recl({ + displayName: "Siblings", + toText: function(elem) { + return reactify.walk(elem, function() { + return ''; + }, function(s) { + return s; + }, function(arg) { + var c; + c = arg.c; + return (c != null ? c : []).join(''); + }); + }, + render: function() { + var keys, navClas; + keys = util.getKeys(this.props.kids); + navClas = { + nav: true, + 'col-md-12': this.props.meta.navmode === 'navbar' + }; + if (this.props.className) { + navClas[this.props.className] = true; + } + navClas = clas(navClas); + return ul({ + className: navClas + }, keys.map((function(_this) { + return function(key) { + var className, data, head, href, selected; + selected = key === _this.props.curr; + if (_this.props.meta.navselect) { + selected = key === _this.props.meta.navselect; + } + href = util.basepath(_this.props.path + "/" + key); + data = _this.props.kids[key]; + if (data.meta) { + head = data.meta.title; + } + if (head == null) { + head = _this.toText(data.head); + } + head || (head = key); + className = clas({ + "nav-item": true, + selected: selected + }); + if (data.meta.sibsclass) { + className += " " + clas(data.meta.sibsclass.split(",")); + } + return li({ + className: className, + key: key + }, a({ + className: "nav-link", + href: href, + onClick: _this.props.closeNav + }, head)); + }; + })(this))); + } +})); + + +},{"../utils/util.coffee":28,"./Async.coffee":2,"./Reactify.coffee":17,"classnames":29}],21:[function(require,module,exports){ +var div, query, reactify, recl, + slice = [].slice; + +query = require('./Async.coffee'); + +reactify = require('./Reactify.coffee'); + +recl = React.createClass; + +div = React.DOM.div; + +module.exports = query({ + body: 'r' +}, recl({ + hash: null, + displayName: "TableOfContents", + _click: function(id) { + return function() { + if (id) { + return document.location.hash = id; + } + }; + }, + componentDidMount: function() { + this.int = setInterval(this.checkHash, 100); + this.st = $(window).scrollTop(); + return this.$headers = $('#toc').children('h1,h2,h3,h4').filter('[id]'); + }, + checkScroll: function() { + var $h, hash, hst, i, len, ref, results, st, v; + st = $(window).scrollTop(); + if (Math.abs(this.st - st) > 10) { + hash = null; + this.st = st; + ref = this.$headers; + results = []; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + if (v.tagName === void 0) { + continue; + } + $h = $(v); + hst = $h.offset().top - $h.outerHeight(true) + 10; + if (hst < st) { + hash = $h.attr('id'); + } + if (hst > st && hash !== this.hash && hash !== null) { + this.hash = "#" + hash; + document.location.hash = hash; + break; + } else { + results.push(void 0); + } + } + return results; + } + }, + checkHash: function() { + var $h, hash, i, len, offset, ref, ref1, results, v; + if (((ref = document.location.hash) != null ? ref.length : void 0) > 0 && document.location.hash !== this.hash) { + hash = document.location.hash.slice(1); + ref1 = this.$headers; + results = []; + for (i = 0, len = ref1.length; i < len; i++) { + v = ref1[i]; + $h = $(v); + if (hash === $h.attr('id')) { + this.hash = document.location.hash; + offset = $h.offset().top - $h.outerHeight(true); + setTimeout(function() { + return $(window).scrollTop(offset, 10); + }); + break; + } else { + results.push(void 0); + } + } + return results; + } + }, + componentWillUnmount: function() { + return clearInterval(this.int); + }, + collectHeader: function(arg) { + var c, comp, ga, gn; + gn = arg.gn, ga = arg.ga, c = arg.c; + if (this.props.match) { + comp = gn === this.props.match; + } else { + comp = gn && gn[0] === 'h' && parseInt(gn[1]) !== NaN; + } + if (comp) { + ga = _.clone(ga); + ga.onClick = this._click(ga.id); + delete ga.id; + return { + gn: gn, + ga: ga, + c: c + }; + } + }, + parseHeaders: function() { + var contents, i, len, ref, ref1, v; + if (this.props.body.c) { + ref = this.props.body.c; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + if (v.gn === 'div' && ((ref1 = v.ga) != null ? ref1.id : void 0) === "toc") { + contents = [{ + gn: "h1", + ga: { + className: "t" + }, + c: ["Table of contents"] + }].concat(slice.call(_.filter(v.c.map(this.collectHeader)))); + if (this.props.noHeader) { + contents.shift(); + } + return { + gn: "div", + ga: { + className: "toc" + }, + c: contents + }; + } + } + } + }, + render: function() { + return reactify(this.parseHeaders()); + } +})); + + +},{"./Async.coffee":2,"./Reactify.coffee":17}],22:[function(require,module,exports){ +var body, clas, div, head, query, recf, recl; + +query = require('./Async.coffee'); + +clas = require('classnames'); + +recf = React.createFactory; + +recl = React.createClass; + +head = recf(require('./NavComponent.coffee')); + +body = recf(require('./BodyComponent.coffee')); + +div = React.DOM.div; + +module.exports = query({ + body: 'r', + name: 't', + path: 't', + meta: 'j', + sein: 't' +}, recl({ + displayName: "Tree", + render: function() { + var treeClas; + treeClas = clas({ + container: this.props.meta.container !== 'false' + }); + return div({ + className: treeClas + }, [ + head({ + key: 'head-container' + }, ""), body({ + key: 'body-container' + }, "") + ]); + } +})); + + +},{"./Async.coffee":2,"./BodyComponent.coffee":3,"./NavComponent.coffee":14,"classnames":29}],23:[function(require,module,exports){ +module.exports = _.extend(new Flux.Dispatcher(), { + handleServerAction: function(action) { + return this.dispatch({ + source: 'server', + action: action + }); + }, + handleViewAction: function(action) { + return this.dispatch({ + source: 'view', + action: action + }); + } +}); + + +},{}],24:[function(require,module,exports){ +var rend; + +rend = ReactDOM.render; + +$(function() { + var frag, main, util; + util = require('./utils/util.coffee'); + require('./utils/scroll.coffee'); + if (document.location.pathname.substr(-1) !== "/") { + history.replaceState({}, "", document.location.pathname + "/" + document.location.search + document.location.hash); + } + window.tree.actions = require('./actions/TreeActions.coffee'); + window.tree.actions.addVirtual(require('./components/Components.coffee')); + frag = util.fragpath(window.location.pathname.replace(/\.[^\/]*$/, '')); + window.tree.actions.setCurr(frag); + window.tree.actions.loadPath(frag, window.tree.data); + if (window.tree.sein != null) { + window.tree.actions.loadSein(frag, window.tree.sein); + } + window.urb.ondataupdate = function(dep) { + var dat; + for (dat in window.urb.datadeps) { + window.urb.dewasp(dat); + } + return window.tree.actions.clearData(); + }; + main = React.createFactory(require('./components/TreeComponent.coffee')); + return rend(main({}, ""), document.getElementById('tree')); +}); + + +},{"./actions/TreeActions.coffee":1,"./components/Components.coffee":6,"./components/TreeComponent.coffee":22,"./utils/scroll.coffee":27,"./utils/util.coffee":28}],25:[function(require,module,exports){ +var dedup, pending, util, waspWait; + +util = require('../utils/util.coffee'); + +dedup = {}; + +pending = {}; + +waspWait = []; + +module.exports = { + refresh: function() { + return dedup = {}; + }, + get: function(path, query, cb) { + var url; + if (query == null) { + query = "no-query"; + } + url = (util.basepath(path)) + ".tree-json?q=" + (this.encode(query)); + if (dedup[url]) { + return; + } + dedup[url] = true; + pending[url] = true; + return $.get(url, {}, function(data, status, xhr) { + var dep; + delete pending[url]; + dep = urb.getXHRWasp(xhr); + urb.sources[dep] = url; + waspWait.push(dep); + if (_.isEmpty(pending)) { + waspWait.map(urb.waspData); + waspWait = []; + } + if (cb) { + return cb(null, data); + } + }); + }, + put: function(data, mark, appl) { + if (appl == null) { + appl = /[a-z]*/.exec(mark)[0]; + } + return urb.send(data, { + mark: mark, + appl: appl + }); + }, + encode: function(obj) { + var _encode, delim; + delim = function(n) { + return Array(n + 1).join('_') || '.'; + }; + _encode = function(obj) { + var _dep, dep, k, res, sub, v; + if (typeof obj !== 'object') { + return [0, obj]; + } + dep = 0; + sub = (function() { + var ref, results; + results = []; + for (k in obj) { + v = obj[k]; + ref = _encode(v), _dep = ref[0], res = ref[1]; + if (_dep > dep) { + dep = _dep; + } + if (res != null) { + results.push(k + (delim(_dep)) + res); + } else { + results.push(void 0); + } + } + return results; + })(); + dep++; + return [dep, sub.join(delim(dep))]; + }; + return (_encode(obj))[1]; + } +}; + + +},{"../utils/util.coffee":28}],26:[function(require,module,exports){ +var EventEmitter, MessageDispatcher, QUERIES, TreeStore, _curr, _data, _nav, _tree, _virt, clog; + +EventEmitter = require('events').EventEmitter.EventEmitter; + +MessageDispatcher = require('../dispatcher/Dispatcher.coffee'); + +clog = console.log.bind(console); + +_virt = {}; + +_tree = {}; + +_data = {}; + +_curr = ""; + +_nav = {}; + +QUERIES = { + body: 'r', + head: 'r', + snip: 'r', + sect: 'j', + meta: 'j', + comt: 'j', + plan: 'j', + beak: 't' +}; + +TreeStore = _.extend((new EventEmitter).setMaxListeners(50), { + addChangeListener: function(cb) { + return this.on('change', cb); + }, + removeChangeListener: function(cb) { + return this.removeListener("change", cb); + }, + emitChange: function() { + return this.emit('change'); + }, + pathToArr: function(_path) { + return _path.split("/"); + }, + fulfill: function(path, query) { + if (path === "/") { + path = ""; + } + return this.fulfillAt(this.getTree(path.split('/')), path, query); + }, + fulfillAt: function(tree, path, query) { + var data, have, k, sub, t; + data = this.fulfillLocal(path, query); + have = _data[path]; + if (have != null) { + for (k in query) { + t = query[k]; + if (!QUERIES[k]) { + continue; + } + if (t !== QUERIES[k]) { + throw TypeError("Wrong query type: " + k + ", '" + t + "'"); + } + data[k] = have[k]; + } + } + if (query.kids) { + if ((have != null ? have.kids : void 0) === false) { + data.kids = {}; + } else { + for (k in tree) { + sub = tree[k]; + if (data.kids == null) { + data.kids = {}; + } + data.kids[k] = this.fulfillAt(sub, path + "/" + k, query.kids); + } + } + } + if (!_.isEmpty(data)) { + return data; + } + }, + fulfillLocal: function(path, query) { + var data; + data = {}; + if (query.path) { + data.path = path; + } + if (query.name) { + data.name = path.split("/").pop(); + } + if (query.sein) { + data.sein = this.getPare(path); + } + if (query.next) { + data.next = this.getNext(path); + } + if (query.prev) { + data.prev = this.getPrev(path); + } + return data; + }, + setCurr: function(arg) { + var path; + path = arg.path; + return _curr = path; + }, + getCurr: function() { + return _curr; + }, + addVirtual: function(arg) { + var components; + components = arg.components; + return _.extend(_virt, components); + }, + getVirtualComponents: function() { + return _virt; + }, + clearData: function() { + _data = {}; + return _tree = {}; + }, + loadSein: function(arg) { + var data, path, sein; + path = arg.path, data = arg.data; + sein = this.getPare(path); + if (sein != null) { + return this.loadPath({ + path: sein, + data: data + }); + } + }, + loadPath: function(arg) { + var data, path; + path = arg.path, data = arg.data; + return this.loadValues(this.getTree(path.split('/'), true), path, data); + }, + loadValues: function(tree, path, data) { + var _path, k, old, ref, ref1, v; + old = (ref = _data[path]) != null ? ref : {}; + for (k in data) { + if (QUERIES[k]) { + old[k] = data[k]; + } + } + ref1 = data.kids; + for (k in ref1) { + v = ref1[k]; + if (tree[k] == null) { + tree[k] = {}; + } + _path = path; + if (_path === "/") { + _path = ""; + } + this.loadValues(tree[k], _path + "/" + k, v); + } + if (data.kids && _.isEmpty(data.kids)) { + old.kids = false; + } + return _data[path] = old; + }, + getSiblings: function(path) { + var curr; + if (path == null) { + path = _curr; + } + curr = path.split("/"); + curr.pop(); + if (curr.length !== 0) { + return this.getTree(curr); + } else { + return {}; + } + }, + getTree: function(_path, make) { + var i, len, sub, tree; + if (make == null) { + make = false; + } + tree = _tree; + for (i = 0, len = _path.length; i < len; i++) { + sub = _path[i]; + if (!sub) { + continue; + } + if (tree[sub] == null) { + if (!make) { + return null; + } + tree[sub] = {}; + } + tree = tree[sub]; + } + return tree; + }, + getPrev: function(path) { + var ind, key, par, sibs, win; + if (path == null) { + path = _curr; + } + sibs = _.keys(this.getSiblings(path)).sort(); + if (sibs.length < 2) { + return null; + } else { + par = path.split("/"); + key = par.pop(); + ind = sibs.indexOf(key); + win = ind - 1 >= 0 ? sibs[ind - 1] : sibs[sibs.length - 1]; + par.push(win); + return par.join("/"); + } + }, + getNext: function(path) { + var ind, key, par, sibs, win; + if (path == null) { + path = _curr; + } + sibs = _.keys(this.getSiblings(path)).sort(); + if (sibs.length < 2) { + return null; + } else { + par = path.split("/"); + key = par.pop(); + ind = sibs.indexOf(key); + win = ind + 1 < sibs.length ? sibs[ind + 1] : sibs[0]; + par.push(win); + return par.join("/"); + } + }, + getPare: function(path) { + var _path; + if (path == null) { + path = _curr; + } + _path = this.pathToArr(path); + if (_path.length > 1) { + _path.pop(); + _path = _path.join("/"); + if (_path === "") { + _path = "/"; + } + return _path; + } else { + return null; + } + }, + setNav: function(arg) { + var dpad, nav, sibs, subnav, title; + title = arg.title, dpad = arg.dpad, sibs = arg.sibs, subnav = arg.subnav; + nav = { + title: title, + dpad: dpad, + sibs: sibs, + subnav: subnav, + open: (_nav.open ? _nav.open : false) + }; + return _nav = nav; + }, + getNav: function() { + return _nav; + }, + toggleNav: function() { + return _nav.open = !_nav.open; + }, + closeNav: function() { + return _nav.open = false; + }, + clearNav: function() { + return _nav = { + title: null, + dpad: null, + sibs: null, + subnav: null, + open: false + }; + } +}); + +TreeStore.dispatchToken = MessageDispatcher.register(function(p) { + var a; + a = p.action; + if (TreeStore[a.type]) { + TreeStore[a.type](a); + return TreeStore.emitChange(); + } +}); + +module.exports = TreeStore; + + +},{"../dispatcher/Dispatcher.coffee":23,"events":30}],27:[function(require,module,exports){ +var scroll; + +scroll = { + w: null, + $d: null, + $n: null, + nh: null, + cs: null, + ls: null, + track: function() { + this.w = $(window).width(); + this.$n = $('#head'); + this.$d = $('#head .ctrl'); + return this.nh = $('#head .ctrl').outerHeight(true); + }, + clearNav: function() { + return this.$n.removeClass('m-up m-down m-fixed'); + }, + resize: function() { + if (this.w > 1170) { + return this.clearNav(); + } + }, + scroll: function() { + var ct, dy, top; + this.cs = $(window).scrollTop(); + if (this.w > 767) { + this.clearNav(); + } + if (this.w < 767) { + dy = this.ls - this.cs; + this.$d.removeClass('focus'); + if (this.cs <= 0) { + this.$n.removeClass('m-up'); + this.$n.addClass('m-down m-fixed'); + return; + } + if (dy > 0) { + if (!this.$n.hasClass('m-down')) { + this.$n.removeClass('m-up').addClass('m-down'); + ct = this.$n.offset().top; + top = this.cs - this.nh; + if (this.cs > ct && this.cs < ct + this.nh) { + top = ct; + } + this.$n.offset({ + top: top + }); + } + if (this.$n.hasClass('m-down') && !this.$n.hasClass('m-fixed') && this.$n.offset().top >= this.cs) { + this.$n.addClass('m-fixed'); + this.$n.attr({ + style: '' + }); + } + } + if (dy < 0) { + if (!this.$n.hasClass('m-up')) { + this.$n.removeClass('m-down m-fixed').addClass('m-up'); + this.$d.removeClass('open'); + $('.menu.open').removeClass('open'); + top = this.cs < 0 ? 0 : this.cs; + ct = this.$n.offset().top; + if (top > ct && top < ct + this.nh) { + top = ct; + } + this.$n.offset({ + top: top + }); + } + if (this.$n.hasClass('m-up') && this.$d.hasClass('open')) { + if (this.cs > this.$n.offset().top + this.$n.height()) { + this.$d.removeClass('open'); + } + } + } + } + return this.ls = this.cs; + }, + init: function() { + setInterval(this.track.bind(this), 200); + this.ls = $(window).scrollTop(); + this.cs = $(window).scrollTop(); + $(window).on('resize', this.resize.bind(this)); + return $(window).on('scroll', this.scroll.bind(this)); + } +}; + +scroll.init(); + +module.exports = scroll; + + +},{}],28:[function(require,module,exports){ +var _basepath; + +_basepath = window.urb.util.basepath("/"); + +_basepath += (window.location.pathname.replace(window.tree._basepath, "")).split("/")[0]; + +module.exports = { + basepath: function(path) { + var _path, prefix; + prefix = _basepath; + if (prefix === "/") { + prefix = ""; + } + if (path[0] !== "/") { + path = "/" + path; + } + _path = prefix + path; + if (_path.slice(-1) === "/" && _path.length > 1) { + _path = _path.slice(0, -1); + } + return _path; + }, + fragpath: function(path) { + return path.replace(/\/$/, '').replace(_basepath, ""); + }, + getKeys: function(kids) { + var k, keys, ref, ref1, ref2, sorted, v; + sorted = true; + keys = []; + for (k in kids) { + v = kids[k]; + if ((ref = v.meta) != null ? ref.hide : void 0) { + continue; + } + if (((ref1 = v.meta) != null ? ref1.sort : void 0) == null) { + sorted = false; + } + keys[Number((ref2 = v.meta) != null ? ref2.sort : void 0)] = k; + } + if (sorted !== true) { + return keys = _.keys(kids).sort(); + } else { + return keys = _.values(keys); + } + } +}; + + +},{}],29:[function(require,module,exports){ +/*! + Copyright (c) 2016 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.push(arg); + } else if (Array.isArray(arg)) { + classes.push(classNames.apply(null, arg)); + } else if (argType === 'object') { + for (var key in arg) { + if (hasOwn.call(arg, key) && arg[key]) { + classes.push(key); + } + } + } + } + + return classes.join(' '); + } + + 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; + } +}()); + +},{}],30:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}]},{},[24]); +window.urb = window.urb || {} +window.urb.appl = window.urb.appl || null + +window.urb.req = function(method,url,params,json,cb) { + var xhr = new XMLHttpRequest() + method = method.toUpperCase() + if(method == "PUT" || method == "DELETE") + xhr.open("POST", url+"?"+method) + else xhr.open(method, url) + + if(json) + xhr.setRequestHeader("content-type", "text/json") + + if(!window.urb.oryx) throw "No CSRF token" // XX fetch auth.json + _data = {oryx: window.urb.oryx} + if(params.xyro) { _data.xyro = params.xyro; } + if(params.ship) { _data.ship = params.ship; } + if(params.path) { _data.path = params.path; } + if(params.appl) { _data.appl = params.appl; } + if(params.mark) { _data.mark = params.mark; } + if(params.wire) { _data.wire = params.wire; } + if(cb) { + xhr.onload = function() { + var err,res + try { + err = null + res = { + status:this.status, + data: JSON.parse(this.responseText) + } + if(res.data.reload) + res.reload = res.data.reload + } catch(e) { + // if(urb.wall !== false) document.write(this.responseText) // XX + err = { + message:"Failed to parse JSON", + raw:this.responseText + } + res = null + } + finally { + cb(err,res) + } + } + xhr.onerror = function() { + cb({ + status:this.status, + data:this.responseText + }) + } + } + xhr.send(JSON.stringify(_data)) +} + +// window.urb.getJSON = function(url,cb){ window.urb.reqJSON("GET",url, null, cb)} +// window.urb.reqJSON = function(method, url, data, cb){ +// var xhr = new XMLHttpRequest() +// xhr.open(method, url) +// xhr.onload = function(){ +// urb.fetchTag.call(xhr) +// if(cb) cb(JSON.parse(xhr.responseText)) +// } +// xhr.send(data === null ? null : JSON.stringify(data)) +// } + +window.urb.reqq = [] +window.urb.qreq = function(method,url,params,json,cb) { + walk = function() { + qobj = {} + qobj.oargs = window.urb.reqq[0] + qobj.nargs = [].slice.call(qobj.oargs,0,4) + qobj.nargs.push(function(){ + if(this.oargs[4]) + this.oargs[4].apply(window.urb,arguments) + window.urb.reqq.shift() + if(window.urb.reqq.length > 0) + walk() + }.bind(qobj)) + window.urb.req.apply(this,qobj.nargs) + } + l = window.urb.reqq.length + window.urb.reqq.push(arguments); + if(l == 0) { walk() } +} + +window.urb.send = function(data,params,cb) { // or send(data, cb) + if(!params || typeof params === "function") + {cb = params; params = {}} + + var url, $send + $send = this.send + + params.data = data + params.ship = params.ship || this.ship + params.appl = params.appl || this.appl + params.mark = params.mark || $send.mark + // params.seqn = params.seqn || $send.seqn + params.wire = params.wire || "/" + params.xyro = (typeof(params.data) === 'undefined') ? null : params.data + + + if(!params.mark) throw new Error("You must specify a mark for urb.send.") + if(!params.appl) throw new Error("You must specify an appl for urb.send.") + + url = ["to",params.appl,params.mark] + url = "/~/"+url.join("/") + + // $send.seqn++ + + this.qreq('post',url,params,true,function(err,data) { + /* if(err) { $send.seqn--; } + else */ if(data && data.data.fail && urb.wall !== false) { + document.location = "#ERROR" + document.write("
"+JSON.stringify(params.xyro)+"\n"
+                            +data.data.mess+"
") // XX + } + if(cb) { cb.apply(this,arguments); } + }) +} +// window.urb.send.seqn = 0 +window.urb.send.mark = "json" + + +window.urb.gsig = function(params) { + var path = params.path + if(!path) path = "" + if(path[0] !== "/") path = "/"+path + return "~"+params.ship+"/"+ + params.appl+ + path.replace(/[^\x00-\x7F]/g, "") +} + +window.urb.puls = false +window.urb.cabs = {} +window.urb.poll = function(params) { + if(!params) throw new Error("You must supply params to urb.poll.") + + var url, $this + + seqn = this.poll.seqn + if(params.seqn) seqn = params.seqn() + + url = "/~/of/"+this.ixor+"?poll="+seqn + + this.puls = true + + $this = this + this.req("get",url,params,true,function(err,res) { + $this.poll.dely = params.dely || $this.poll.dely + if(res){ + if(res.data.beat) + return $this.poll(params) + switch(res.data.type){ + case "news": + return document.location.reload() // XX check autoreload + case "rush": + case "mean": + var err2 = err + if(res.data.type == "mean") + err2 = res.data.data + var fn = $this.gsig(res.data.from) + if($this.cabs[fn]) + $this.cabs[fn].call(this,err2, + {status: res.status, data: res.data.data.json}) // XX non-json + break; + default: + throw new Error("Lost event %"+res.data.type) + } + if(params.incs) + params.incs() + else + $this.poll.seqn++ + $this.poll.dely = 250 + return $this.poll(params) + } + + else if(err){ + setTimeout(function() { + $this.poll(params) + }, $this.poll.dely) + $this.poll.dely += Math.ceil($this.poll.dely*.2) + } + else throw "Neither error nor result on poll" + }) +} +window.urb.poll.seqn = 1 +window.urb.poll.dely = 250 + +window.urb.bind = function(path, params, cb, nicecb){ // or bind(path, cb) + if(!params || typeof params === "function") + {cb = params; params = {}} + + params.path = path + if(params.path[0] !== "/") params.path = "/"+params.path + params.ship = params.ship || this.ship + params.appl = params.appl || this.appl + params.mark = params.mark || this.bind.mark + params.wire = params.wire || params.path + + if(typeof path != "string") + throw new Error("You must specify a string path for urb.bind.") + if(!params.appl) throw new Error("You must specify an appl for urb.bind.") + if(!cb) throw new Error("You must supply a callback to urb.bind.") + + var method, perm, url, $this + + if(params.mark !== "json") + throw new Error("Non-json subscriptions unimplemented.") // XX + url = "/~/is/"+this.gsig(params)+"."+params.mark + + params.path = params.wire + this.cabs[this.gsig(params)] = cb + + $this = this + this.qreq("put",url,params,true,function(err,res) { + if(nicecb) { nicecb.apply(this,[err,{status: res.status, data: res.data}])} + // XX give raw data + // + if(!err && !$this.puls) $this.poll(params) + }) +} +urb.bind.mark = "json" + +window.urb.drop = function(path, params, cb){ // or drop(path,cb) + if(typeof params === "function") + {cb = params; params = {}} + + params.path = path + if(params.path[0] !== "/") params.path = "/"+params.path + params.ship = params.ship || this.ship + params.appl = params.appl || this.appl + params.wire = params.wire || params.path + + if(typeof path != "string") + throw new Error("You must specify a string path for urb.drop.") + if(!params.appl) throw new Error("You must specify an appl for urb.drop.") + + url = "/~/is/"+this.gsig(params)+".json" + method = "delete" + this.req("delete",url,params,true,function(err,res) { + if(cb) cb(err,res) + }) +} + +window.urb.subscribe = function(params,cb) { // legacy interface + if(!params) throw new Error("You must supply params to urb.subscribe") + return window.urb.bind(params.path, params, cb, cb) +} + +window.urb.unsubscribe = function(params,cb) { // legacy intreface + if(!params) throw new Error("You must supply params to urb.unsubscribe.") + return window.urb.drop(params.path, params, cb) +} + +window.urb.util = { + isURL: function(s) { + r = new RegExp('^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$', 'i'); + return s.length < 2083 && r.test(s); + }, + numDot: function(n) { + _n = String(n) + fun = function(s){ + if(s.length <= 3) + return s + return fun(s.slice(0,-3))+"."+s.slice(-3) + } + return fun((_n)) + }, + toDate: function (dat){ + var mils = Math.floor((0x10000 * dat.getUTCMilliseconds()) / 1000).toString(16) + function pad(num, str){ + return ((new Array(num + 1)).join('0') + str).substr(-num,num) + } + return '~' + dat.getUTCFullYear() + + '.' + (dat.getUTCMonth() + 1) + + '.' + dat.getUTCDate() + + '..' + pad(2, dat.getUTCHours()) + + '.' + pad(2, dat.getUTCMinutes()) + + '.' + pad(2, dat.getUTCSeconds()) + + '..' + pad(4, mils) + }, + basepath: function(spur, pathname){ + spur = spur || '' + if(spur === '/') spur = '' + pathname = pathname || window.location.pathname + + base = "" + + if(pathname.indexOf("/~~") == 0) + base = "/~~" + if(pathname.indexOf("/~/as/") == 0) + base = "/~/as/"+pathname.split("/")[3] + if(pathname.indexOf("/~/away") == 0) + base = "/~/away" + + return base+spur + } +}