diff --git a/doc/Using_ActivityPub.md b/doc/Using_ActivityPub.md index b6755eb..b306543 100644 --- a/doc/Using_ActivityPub.md +++ b/doc/Using_ActivityPub.md @@ -1,5 +1,6 @@ # Using ActivityPub +```clojure user=> (require '[clj-activitypub.core :as activitypub]) nil user=> (require '[clj-activitypub.webfinger :as webfinger]) @@ -107,4 +108,5 @@ user=> (pprint sb) [{:type "PropertyValue", :name "Home Page", :value - "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]} \ No newline at end of file + "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]} +``` diff --git a/doc/intro.md b/doc/intro.md index f75e04e..97d9ad0 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -1,3 +1,82 @@ -# Introduction to dog-and-duck +# The Old Dog and Duck -TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) +A Clojure library designed to implement the ActivityPub protocol, obviously. + +## Introduction + +The Old Dog and Duck is clearly a pub, and it's a pub related to an activity; to whit, hunting ducks with dogs. Yes, of course one could also hunt dogs with ducks, but in practice that doesn't work so well. The point isn't whether or not I approve of hunting ducks with dogs (or vice versa); to be clear, I don't. The point is that it's a pub related to an activity, and is therefore an [ActivityPub](https://www.w3.org/TR/activitypub/). + +Are we clear? + +Good. + +Let us proceed. + +**The Old Dog and Duck** is intended to be a set of libraries to enable people to build stuff which interacts with ActivityPub. It isn't intended to be a replacement for, or clone of, Mastodon. I do think I might implement my own ActivityPub server on top of The Old Dog and Duck, that specifically might allow for user-pluggable feed-sorting algorithms and with my own user interface/user experience take, but that project is not (yet, at any rate) this project. + +## Status + +This is a long way pre-alpha. Everything will change. Feel free to play, but do so at your own risk. Contributions welcome. + +## Architecture + +There are a number of separate concerns required to implement ActivityPub. They include + +1. Parsing ActivityStreams messages received from peers and from clients; +2. Persisting ActivityStreams objects; +3. Delivering ActivityStreams objects to peers; +4. Delivering ActivityStreams objects to clients. + +**NOTE THAT** what Mastodon delivers to clients is not actually in ActivityStreams format; this seems to be an ad-hoc hack that's just never been fixed and has therefore become a de-facto standard for communication between ActivityPub hosts and their clients. + +My proposal would be to deliver exactly the same ActivityStreams format to my client as to other servers. There may be a valid reason for not doing this, but if there is I will discover it in due course. + +## Proposed dog-and-duck libraries + +**NOTE THAT** at the present stage all the proposed libraries are in one package, namely this package, but that it is proposed that in future they will form separate libraries in separate packages. + +### Bar + +Where conversations happen. Handle interactions with clients. + +### Cellar + +Where things are stored. Persistance for ActivityStreams objects; I may at least initially simply copy the Mastodon postgres schema, but equally I may not. + +### Pantry + +Where deliveries are ordered and arrive; and from where deliveries onwards are despatched. Handle interactions with peers. + +### Quack + +Duck-typing for ActivityStreams objects. + +As of version 0.1.0, this is substantially the only part that is yet at all useful, and it is still a long way from finished or robust. + +### Scratch + +What the dog does when bored. Essentially, a place where I can learn how to make this stuff work, but perhaps eventually an ActivityPub server in its own right. + +## Usage + +At present, only the duck-typing functions work. To play with them, use + +```clojure +(require '[dog-and-duck.quack.quack :as q]) +``` + +## Testing + +Prior to testing, you should clone [activitystreams-test-documents](https://github.com/w3c-social/activitystreams-test-documents) into the `resources` directory. You can then test with + +```bash +lein test +``` + +## License + +Copyright © Simon Brooke, 2022. + +This program and the accompanying materials are made available under the +terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your +option) any later version. diff --git a/docs/cloverage/clj_activitypub/core.clj.html b/docs/cloverage/clj_activitypub/core.clj.html new file mode 100644 index 0000000..d0e28ea --- /dev/null +++ b/docs/cloverage/clj_activitypub/core.clj.html @@ -0,0 +1,449 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../coverage.css"/> <title> clj_activitypub/core.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns clj-activitypub.core + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 (:require [clj-activitypub.internal.crypto :as crypto] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 [clj-activitypub.internal.thread-cache :as thread-cache] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 [clj-activitypub.internal.http-util :as http] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 [clj-http.client :as client] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 006 [clojure.string :as str])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 007 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 008 (defn config + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 009 "Creates hash of computed data relevant for most ActivityPub utilities." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 010 [{:keys [domain username username-route public-key private-key] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 011 :or {username-route "/users/" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 012 public-key nil + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 013 private-key nil}}] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 014 (let [base-url (str "https://" domain)] + </span><br/> +<span class="not-covered" title="0 out of 8 forms covered"> + 015 {:domain domain + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 016 :base-url base-url + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 017 :username username + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 018 :user-id (str base-url username-route username) + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 019 :public-key public-key + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 020 :private-key (when private-key + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 021 (crypto/private-key private-key))})) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 022 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 023 (defn parse-account + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 024 "Given an ActivityPub handle (e.g. @jahfer@mastodon.social), produces + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 025 a map containing {:domain ... :username ...}." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 026 [handle] + </span><br/> +<span class="covered" title="9 out of 9 forms covered"> + 027 (let [[username domain] (filter #(not (str/blank? %)) + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 028 (str/split handle #"@"))] + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 029 {:domain domain :username username})) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 030 + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 031 (def ^:private user-cache (thread-cache/make)) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 032 (defn fetch-user + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 033 "Fetches the customer account details located at user-id from a remote + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 034 server. Will return cached results if they exist in memory." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 035 [user-id] + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 036 ((:get-v user-cache) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 037 user-id + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 038 #(:body + </span><br/> +<span class="covered" title="11 out of 11 forms covered"> + 039 (client/get user-id {:as :json-string-keys + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 040 :throw-exceptions false + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 041 :ignore-unknown-host? true + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 042 :headers {"Accept" "application/activity+json"}})))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 043 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 044 (defn actor + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 045 "Accepts a config, and returns a map in the form expected by the ActivityPub + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 046 spec. See https://www.w3.org/TR/activitypub/#actor-objects for reference." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 047 [{:keys [user-id username public-key]}] + </span><br/> +<span class="not-covered" title="0 out of 12 forms covered"> + 048 {"@context" ["https://www.w3.org/ns/activitystreams" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 049 "https://w3id.org/security/v1"] + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 050 :id user-id + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 051 :type "Person" + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 052 :preferredUsername username + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 053 :inbox (str user-id "/inbox") + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 054 :outbox (str user-id "/outbox") + </span><br/> +<span class="not-covered" title="0 out of 8 forms covered"> + 055 :publicKey {:id (str user-id "#main-key") + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 056 :owner user-id + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 057 :publicKeyPem (or public-key "")}}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 058 + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 059 (def signature-headers ["(request-target)" "host" "date" "digest"]) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 060 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 061 (defn- str-for-signature [headers] + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 062 (let [headers-xf (reduce-kv + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 063 (fn [m k v] + </span><br/> +<span class="not-covered" title="0 out of 9 forms covered"> + 064 (assoc m (str/lower-case k) v)) {} headers)] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 065 (->> signature-headers + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 066 (select-keys headers-xf) + </span><br/> +<span class="not-covered" title="0 out of 12 forms covered"> + 067 (reduce-kv (fn [coll k v] (conj coll (str k ": " v))) []) + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 068 (interpose "\n") + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 069 (apply str)))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 070 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 071 (defn gen-signature-header + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 072 "Generates a HTTP Signature string based on the provided map of headers." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 073 [config headers] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 074 (let [{:keys [user-id private-key]} config + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 075 string-to-sign (str-for-signature headers) + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 076 signature (crypto/base64-encode (crypto/sign string-to-sign private-key)) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 077 sig-header-keys {"keyId" user-id + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 078 "headers" (str/join " " signature-headers) + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 079 "signature" signature}] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 080 (->> sig-header-keys + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 081 (reduce-kv (fn [m k v] + </span><br/> +<span class="not-covered" title="0 out of 11 forms covered"> + 082 (conj m (str k "=" "\"" v "\""))) []) + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 083 (interpose ",") + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 084 (apply str)))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 085 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 086 (defn auth-headers + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 087 "Given a config and request map of {:body ... :headers ...}, returns the + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 088 original set of headers with Signature and Digest attributes appended." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 089 [config {:keys [body headers]}] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 090 (let [digest (http/digest body) + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 091 h (-> headers + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 092 (assoc "Digest" digest) + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 093 (assoc "(request-target)" "post /inbox"))] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 094 (assoc headers + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 095 "Signature" (gen-signature-header config h) + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 096 "Digest" digest))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 097 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 098 (defmulti obj + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 099 "Produces a map representing an ActivityPub object which can be serialized + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 100 directly to JSON in the form expected by the ActivityStreams 2.0 spec. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 101 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference." + </span><br/> +<span class="partial" title="1 out of 4 forms covered"> + 102 (fn [_config object-data] (:type object-data))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 103 + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 104 (defmethod obj :note + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 105 [{:keys [user-id]} + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 106 {:keys [id published inReplyTo content to] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 107 :or {published (http/date) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 108 inReplyTo "" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 109 to "https://www.w3.org/ns/activitystreams#Public"}}] + </span><br/> +<span class="not-covered" title="0 out of 14 forms covered"> + 110 {"id" (str user-id "/notes/" id) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 111 "type" "Note" + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 112 "published" published + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 113 "attributedTo" user-id + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 114 "inReplyTo" inReplyTo + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 115 "content" content + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 116 "to" to}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 117 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 118 (defmulti activity + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 119 "Produces a map representing an ActivityPub activity which can be serialized + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 120 directly to JSON in the form expected by the ActivityStreams 2.0 spec. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 121 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference." + </span><br/> +<span class="partial" title="1 out of 2 forms covered"> + 122 (fn [_config activity-type _data] activity-type)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 123 + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 124 (defmethod activity :create [{:keys [user-id]} _ data] + </span><br/> +<span class="not-covered" title="0 out of 9 forms covered"> + 125 {"@context" ["https://www.w3.org/ns/activitystreams" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 126 "https://w3id.org/security/v1"] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 127 "type" "Create" + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 128 "actor" user-id + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 129 "object" data}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 130 + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 131 (defmethod activity :delete [{:keys [user-id]} _ data] + </span><br/> +<span class="not-covered" title="0 out of 9 forms covered"> + 132 {"@context" ["https://www.w3.org/ns/activitystreams" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 133 "https://w3id.org/security/v1"] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 134 "type" "Delete" + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 135 "actor" user-id + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 136 "object" data}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 137 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 138 (defn with-config + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 139 "Returns curried forms of the #activity and #obj multimethods in the form + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 140 {:activity ... :obj ...}, with the initial parameter set to config." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 141 [config] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 142 (let [f (juxt + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 143 #(partial activity %) + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 144 #(partial obj %)) + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 145 [activity-fn obj-fn] (f config)] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 146 {:activity activity-fn + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 147 :obj obj-fn})) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/clj_activitypub/internal/crypto.clj.html b/docs/cloverage/clj_activitypub/internal/crypto.clj.html new file mode 100644 index 0000000..dc72564 --- /dev/null +++ b/docs/cloverage/clj_activitypub/internal/crypto.clj.html @@ -0,0 +1,116 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/crypto.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns clj-activitypub.internal.crypto + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 (:require [clojure.java.io :as io]) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 (:import (java.util Base64) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 (java.security MessageDigest SecureRandom Signature))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 005 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 006 (java.security.Security/addProvider + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 007 (org.bouncycastle.jce.provider.BouncyCastleProvider.)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 008 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 009 (defn- keydata [reader] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 010 (->> reader + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 011 (org.bouncycastle.openssl.PEMParser.) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 012 (.readObject))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 013 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 014 (defn- pem-string->key-pair [string] + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 015 (let [kd (keydata (io/reader (.getBytes string)))] + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 016 (.getKeyPair (org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.) kd))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 017 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 018 (defn private-key [private-pem-str] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 019 (-> private-pem-str + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 020 (pem-string->key-pair) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 021 (.getPrivate))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 022 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 023 (defn base64-encode [bytes] + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 024 (.encodeToString (Base64/getEncoder) bytes)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 025 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 026 (defn sha256-base64 [data] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 027 (let [digest (.digest (MessageDigest/getInstance "SHA-256") (.getBytes data))] + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 028 (base64-encode digest))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 029 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 030 (defn sign [data private-key] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 031 (let [bytes (.getBytes data) + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 032 signer (doto (Signature/getInstance "SHA256withRSA") + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 033 (.initSign private-key (SecureRandom.)) + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 034 (.update bytes))] + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 035 (.sign signer))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 036 + </span><br/> + </body> +</html> diff --git a/docs/cloverage/clj_activitypub/internal/http_util.clj.html b/docs/cloverage/clj_activitypub/internal/http_util.clj.html new file mode 100644 index 0000000..16768c7 --- /dev/null +++ b/docs/cloverage/clj_activitypub/internal/http_util.clj.html @@ -0,0 +1,83 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/http_util.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns clj-activitypub.internal.http-util + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 (:require [clj-activitypub.internal.crypto :as crypto]) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 (:import (java.net URLEncoder) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 (java.time OffsetDateTime ZoneOffset) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 (java.time.format DateTimeFormatter))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 006 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 007 (defn encode-url-params [params] + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 008 (->> params + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 009 (reduce-kv + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 010 (fn [coll k v] + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 011 (conj coll + </span><br/> +<span class="covered" title="11 out of 11 forms covered"> + 012 (str (URLEncoder/encode (name k)) "=" (URLEncoder/encode (str v))))) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 013 []) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 014 (interpose "&") + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 015 (apply str))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 016 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 017 (defn date [] + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 018 (-> (OffsetDateTime/now (ZoneOffset/UTC)) + </span><br/> +<span class="not-covered" title="0 out of 1 forms covered"> + 019 (.format DateTimeFormatter/RFC_1123_DATE_TIME))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 020 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 021 (defn digest + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 022 "Accepts body from HTTP request and generates string + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 023 for use in HTTP `Digest` request header." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 024 [body] + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 025 (str "sha-256=" (crypto/sha256-base64 body))) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/clj_activitypub/internal/thread_cache.clj.html b/docs/cloverage/clj_activitypub/internal/thread_cache.clj.html new file mode 100644 index 0000000..5082b7b --- /dev/null +++ b/docs/cloverage/clj_activitypub/internal/thread_cache.clj.html @@ -0,0 +1,140 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/thread_cache.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns clj-activitypub.internal.thread-cache) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 002 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 003 (defn- current-time + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 "Returns current time using UNIX epoch." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 [] + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 006 (System/currentTimeMillis)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 007 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 008 (defn- update-read-at [store k v] + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 009 (dosync + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 010 (commute store assoc k + </span><br/> +<span class="covered" title="7 out of 7 forms covered"> + 011 (merge v {:read-at (current-time)})))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 012 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 013 (defn make + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 014 "Creates a thread-local cache." + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 015 ([] (make false)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 016 ([cache-if-nil] + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 017 (let [store (ref {})] + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 018 (letfn [(cache-kv ([k v] + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 019 (dosync + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 020 (commute store assoc k + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 021 {:write-at (current-time) + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 022 :read-at (current-time) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 023 :value v}) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 024 v))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 025 (get-v ([k] + </span><br/> +<span class="covered" title="11 out of 11 forms covered"> + 026 (when-let [data (get @store k)] + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 027 (update-read-at store k data) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 028 (:value data))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 029 ([k compute-fn] + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 030 (let [storage @store] + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 031 (if (contains? storage k) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 032 (get-v k) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 033 (let [v (compute-fn)] + </span><br/> +<span class="partial" title="11 out of 12 forms covered"> + 034 (when (or (not (nil? v)) cache-if-nil) + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 035 (cache-kv k v) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 036 (get-v k))))))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 037 (lru ([] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 038 (mapv + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 039 (fn [[k v]] [k (:value v)]) + </span><br/> +<span class="not-covered" title="0 out of 12 forms covered"> + 040 (sort-by #(-> % val :read-at) < @store))))] + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 041 {:cache-kv cache-kv + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 042 :get-v get-v + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 043 :cache-if-nil cache-if-nil + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 044 :lru lru})))) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/clj_activitypub/webfinger.clj.html b/docs/cloverage/clj_activitypub/webfinger.clj.html new file mode 100644 index 0000000..a834d7a --- /dev/null +++ b/docs/cloverage/clj_activitypub/webfinger.clj.html @@ -0,0 +1,104 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../coverage.css"/> <title> clj_activitypub/webfinger.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns clj-activitypub.webfinger + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 (:require [clj-http.client :as client] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 [clj-activitypub.internal.http-util :as http] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 [clj-activitypub.internal.thread-cache :as thread-cache])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 005 + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 006 (def remote-uri-path "/.well-known/webfinger") + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 007 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 008 (defn- resource-str [domain username] + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 009 (str "acct:" username "@" domain)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 010 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 011 (defn resource-url + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 012 "Builds a URL pointing to the user's account on the remote server." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 013 [domain username & [params]] + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 014 (let [resource (resource-str domain username) + </span><br/> +<span class="covered" title="8 out of 8 forms covered"> + 015 query-str (http/encode-url-params (merge params {:resource resource}))] + </span><br/> +<span class="covered" title="7 out of 7 forms covered"> + 016 (str "https://" domain remote-uri-path "?" query-str))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 017 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 018 (def ^:private user-id-cache + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 019 (thread-cache/make)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 020 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 021 (defn fetch-user-id + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 022 "Follows the webfinger request to a remote domain, retrieving the ID of the requested + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 023 account. Typically returns a string in the form of a URL." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 024 [domain username] + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 025 ((:get-v user-id-cache) + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 026 (str domain "@" username) ;; cache key + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 027 (fn [] + </span><br/> +<span class="partial" title="15 out of 16 forms covered"> + 028 (let [response (some-> (resource-url domain username {:rel "self"}) + </span><br/> +<span class="covered" title="8 out of 8 forms covered"> + 029 (client/get {:as :json :throw-exceptions false :ignore-unknown-host? true}))] + </span><br/> +<span class="partial" title="27 out of 31 forms covered"> + 030 (some->> response :body :links + </span><br/> +<span class="covered" title="12 out of 12 forms covered"> + 031 (some #(when (= (:type %) "application/activity+json") %)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 032 :href))))) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/codecov.json b/docs/cloverage/codecov.json new file mode 100644 index 0000000..766b60c --- /dev/null +++ b/docs/cloverage/codecov.json @@ -0,0 +1,54 @@ +{"coverage": + {"dog_and_duck/quack/quack.clj": + [null, 1, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, 1, null, + null, null, null, null, null, null, null, null, null, null, null, + 17, null, 1, null, null, null, null, null, true, 5, null, null, 1, + null, 1, null, null, null, null, 1, null, null, null, null, null, 1, + null, null, 4, null, 1, null, null, null, null, 1, null, null, null, + null, 1, null, null, 4, null, 1, null, null, null, null, 1, null, + null, null, null, null, null, true, 10, 9, true, 2, null, null, + null, true, 2, null, 1, null, null, true, 2, 2, 0, 0, 0, null, null, + 1, null, null, 0, 0, 0, 0, 0, 0, 0, null, null, null, 1, null, null, + 0, 0, 0, null, null, 1, null, null, null, null, null, 0, 0, 0, null, + null, 1, null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + null, null, 0, 0, null, 1, null, null, 0, null, 1, null, null, 0, + null, 1, null, null, 0, null, 1, null, null, 0, null, null], + "clj_activitypub/internal/http_util.clj": + [null, 1, null, null, null, null, null, 1, 1, 1, 1, 2, 2, 1, 1, 1, + null, 1, 0, 0, null, 1, null, null, null, 0], + "clj_activitypub/internal/thread_cache.clj": + [null, 1, null, 1, null, null, 8, null, 1, 4, 4, 4, null, 1, null, 2, + null, 2, 2, 2, 2, 2, 2, 2, 2, null, 4, 4, 4, null, 4, 4, 2, 2, true, + 2, 2, null, 0, 0, 0, 2, 2, 2, 2], + "dog_and_duck/scratch/parser.clj": + [null, 1, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, + null, 1, null, null, null, 7, 7, 7, 7, 7, true, 0, null, 1, null, 1, + 0, 0, 0, 0, 0, 0, 1], + "clj_activitypub/core.clj": + [null, 1, null, null, null, null, null, null, 1, null, null, null, + null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, 6, 2, + 2, null, 1, 1, null, null, null, 1, 1, 1, 1, null, null, 1, null, 1, + null, null, null, 0, null, 0, null, 0, 0, 0, 0, 0, 0, null, 1, null, + 1, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, null, 1, null, null, null, 0, 0, 0, 0, 0, 0, 0, null, 1, + null, null, null, true, null, 1, null, null, null, null, null, 0, + null, 0, 0, 0, 0, 0, null, 1, null, null, null, true, null, 1, 0, + null, null, 0, 0, null, 1, 0, null, null, 0, 0, null, 1, null, null, + null, 0, 0, 0, 0, 0, 0], + "clj_activitypub/internal/crypto.clj": + [null, 1, null, null, null, null, 1, 1, null, 1, 0, 0, null, null, 1, + 0, 0, null, 1, 0, 0, null, null, 1, 0, null, 1, 0, 0, null, 1, 0, 0, + 0, 0, 0, null], + "dog_and_duck/scratch/core.clj":[null, 1, null, 1, null, null, 0], + "clj_activitypub/webfinger.clj": + [null, 1, null, null, null, null, 1, null, 1, 1, null, 1, null, null, + 1, 1, 1, null, 1, 1, null, 1, null, null, null, 3, 3, 3, true, 1, + true, 2, null], + "dog_and_duck/scratch/scratch.clj": + [null, 1, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, 1, null, 1, 1, 1, null, null, null, + null, 1, null, 1, 1, 1, 1, null, null, 1, null, null, 1, 1, null, + null, null, null, 1, 1, 1, 1, 1, 1, null]}} diff --git a/docs/cloverage/coverage.css b/docs/cloverage/coverage.css new file mode 100644 index 0000000..2be4e57 --- /dev/null +++ b/docs/cloverage/coverage.css @@ -0,0 +1,40 @@ +.covered { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: #558B55; +} + +.not-covered { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: red; +} + +.partial { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: orange; +} + +.not-tracked { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; +} + +.blank { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; +} + +td { + padding-right: 10px; +} + +td.with-bar { + width: 250px; + text-align: center; +} + +td.with-number { + text-align: right; +} + +td.ns-name { + min-width: 150px; + padding-right: 25px; +} diff --git a/docs/cloverage/coverage.xml b/docs/cloverage/coverage.xml new file mode 100644 index 0000000..f5390a2 --- /dev/null +++ b/docs/cloverage/coverage.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="9"/><methods value="1223"/><srcfiles value="9"/><srclines value="284"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="52% (631/1223)"/><coverage type="line, %" value="54% (153/284)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (75/75)"/><coverage type="line, %" value="100% (19/19)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="44% (199/448)"/><coverage type="line, %" value="46% (31/68)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (34/68)"/><coverage type="line, %" value="56% (10/18)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report> \ No newline at end of file diff --git a/docs/cloverage/dog_and_duck/quack/quack.clj.html b/docs/cloverage/dog_and_duck/quack/quack.clj.html new file mode 100644 index 0000000..30f6484 --- /dev/null +++ b/docs/cloverage/dog_and_duck/quack/quack.clj.html @@ -0,0 +1,569 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/quack/quack.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns dog-and-duck.quack.quack + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 "Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck..." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 ;;(:require [clojure.spec.alpha as s]) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 (:import [java.net URI URISyntaxException])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 005 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 006 ;;; Copyright (C) Simon Brooke, 2022 + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 007 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 008 ;;; This program is free software; you can redistribute it and/or + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 009 ;;; modify it under the terms of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 010 ;;; as published by the Free Software Foundation; either version 2 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 011 ;;; of the License, or (at your option) any later version. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 012 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 013 ;;; This program is distributed in the hope that it will be useful, + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 014 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 015 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 016 ;;; GNU General Public License for more details. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 017 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 018 ;;; You should have received a copy of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 019 ;;; along with this program; if not, write to the Free Software + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 020 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 021 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 022 (defn object? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 023 "Returns `true` iff `x` is recognisably an ActivityStreams object. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 024 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 025 **NOTE THAT** The ActivityStreams spec + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 026 [says](https://www.w3.org/TR/activitystreams-core/#object): + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 027 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 028 > All properties are optional (including the id and type) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 029 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 030 But we are *just not having that*, because otherwise we're flying blind. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 031 We *shall* reject objects lacking at least `:type`. Missing `:id` keys are + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 032 tolerable because they represent transient objects, which we expect to + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 033 handle." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 034 [x] + </span><br/> +<span class="covered" title="15 out of 15 forms covered"> + 035 (and (map? x) (:type x) true)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 036 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 037 (defn persistent-object? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 038 "`true` iff `x` is a persistent object. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 039 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 040 Transient objects in ActivityPub are not required to have an `id` key, but persistent + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 041 ones must have a key, and it must be an IRI (but normally a URI)." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 042 [x] + </span><br/> +<span class="partial" title="1 out of 2 forms covered"> + 043 (try + </span><br/> +<span class="covered" title="13 out of 13 forms covered"> + 044 (and (object? x) (uri? (URI. (:id x)))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 045 (catch URISyntaxException _ false))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 046 + </span><br/> +<span class="covered" title="7 out of 7 forms covered"> + 047 (persistent-object? {:type "test" :id "https://mastodon.scot/@barfilfarm"}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 048 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 049 (def ^:const actor-types + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 050 "The set of types we will accept as actors. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 051 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 052 There's an [explicit set of allowed actor types] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 053 (https://www.w3.org/TR/activitystreams-vocabulary/#actor-types)." + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 054 #{"Application" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 055 "Group" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 056 "Organization" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 057 "Person" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 058 "Service"}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 059 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 060 (defn actor-type? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 061 ;; TODO: better as a macro + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 062 [x] + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 063 (if (actor-types x) true false)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 064 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 065 (def ^:const verb-types + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 066 "The set of types we will accept as verbs. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 067 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 068 There's an [explicit set of allowed verb types] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 069 (https://www.w3.org/TR/activitystreams-vocabulary/#activity-types)." + </span><br/> +<span class="covered" title="29 out of 29 forms covered"> + 070 #{"Accept" "Add" "Announce" "Arrive" "Block" "Create" "Delete" "Dislike" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 071 "Flag" "Follow" "Ignore" "Invite" "Join" "Leave" "Like" "Listen" "Move" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 072 "Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept" + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 073 "TentativeReject" "Travel" "Undo" "Update" "View"}) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 074 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 075 (defn verb-type? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 076 ;; TODO: better as a macro + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 077 [x] + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 078 (if (verb-types x) true false)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 079 + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 080 (def ^:const activitystreams-context-uri + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 081 "The URI of the context of an ActivityStreams object is expected to be this + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 082 literal string." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 083 "https://www.w3.org/ns/activitystreams") + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 084 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 085 (defn context? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 086 "Returns `true` iff `x` quacks like an ActivityStreams context, else false. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 087 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 088 A context is either + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 089 1. the URI (actually an IRI) `activitystreams-context-uri`, or + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 090 2. a collection comprising that URI and a map." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 091 [x] + </span><br/> +<span class="partial" title="4 out of 6 forms covered"> + 092 (cond + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 093 (nil? x) false + </span><br/> +<span class="covered" title="11 out of 11 forms covered"> + 094 (string? x) (and (= x activitystreams-context-uri) true) + </span><br/> +<span class="partial" title="19 out of 20 forms covered"> + 095 (coll? x) (and (context? (first (remove map? x))) + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 096 (= (count x) 2) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 097 true) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 098 :else false)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 099 + </span><br/> +<span class="partial" title="40 out of 42 forms covered"> + 100 (defmacro has-context? [x] + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 101 `(context? ((keyword "@context") ~x))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 102 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 103 (defn actor? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 104 "Returns `true` if `x` quacks like an actor, else false." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 105 [x] + </span><br/> +<span class="partial" title="7 out of 21 forms covered"> + 106 (and + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 107 (object? x) + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 108 (has-context? x) + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 109 (uri? (URI. (:inbox x))) + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 110 (uri? (URI. (:outbox x))) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 111 (actor-type? (:type x)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 112 true)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 113 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 114 (defn activity? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 115 "`true` iff `x` quacks like an activity, else false." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 116 [x] + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 117 (try + </span><br/> +<span class="not-covered" title="0 out of 28 forms covered"> + 118 (and (object? x) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 119 (has-context? x) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 120 (string? (:summary x)) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 121 (actor? (:actor x)) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 122 (verb-type? (:type x)) + </span><br/> +<span class="not-covered" title="0 out of 15 forms covered"> + 123 (or (object? (:object x)) (uri? (URI. (:object x)))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 124 true) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 125 (catch URISyntaxException _ false))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 126 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 127 (defn link? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 128 "`true` iff `x` quacks like a link, else false." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 129 [x] + </span><br/> +<span class="not-covered" title="0 out of 16 forms covered"> + 130 (and (object? x) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 131 (= (:type x) "Link") + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 132 (uri? (URI. (:href x))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 133 true)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 134 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 135 (defn link-or-uri? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 136 "`true` iff `x` is either a URI or a link, else false. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 137 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 138 There are several points in the specification where e.g. the `:image` + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 139 property (if present) may be either a link or a URI." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 140 [x] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 141 (and + </span><br/> +<span class="not-covered" title="0 out of 9 forms covered"> + 142 (cond (string? x) (uri? (URI. x)) + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 143 :else (link? x)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 144 true)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 145 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 146 (defn collection? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 147 "`true` iff `x` quacks like a collection of type `type`, else `false`. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 148 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 149 With one argument, will recognise plain collections and ordered collections, + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 150 but (currently) not collection pages." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 151 ([x type] + </span><br/> +<span class="not-covered" title="0 out of 11 forms covered"> + 152 (let [items (or (:items x) (:orderedItems x))] + </span><br/> +<span class="not-covered" title="0 out of 25 forms covered"> + 153 (and + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 154 (cond + </span><br/> +<span class="not-covered" title="0 out of 8 forms covered"> + 155 (:items x) (nil? (:orderedItems x)) + </span><br/> +<span class="not-covered" title="0 out of 8 forms covered"> + 156 (:orderedItems x) (nil? (:items x))) ;; can't have both properties + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 157 (object? x) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 158 (= (:type x) type) + </span><br/> +<span class="not-covered" title="0 out of 3 forms covered"> + 159 (coll? items) + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 160 (every? object? items) + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 161 (integer? (:totalItems x)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 162 true))) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 163 ([x] + </span><br/> +<span class="not-covered" title="0 out of 10 forms covered"> + 164 (or (collection? x "Collection") + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 165 (collection? x "OrderedCollection")))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 166 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 167 (defn unordered-collection? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 168 "`true` iff `x` quacks like an unordered collection, else `false`." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 169 [x] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 170 (collection? x "Collection")) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 171 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 172 (defn ordered-collection? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 173 "`true` iff `x` quacks like an ordered collection, else `false`." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 174 [x] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 175 (collection? x "OrderedCollection")) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 176 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 177 (defn collection-page? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 178 "`true` iff `x` quacks like a page in a paged collection, else `false`." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 179 [x] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 180 (collection? x "CollectionPage")) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 181 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 182 (defn ordered-collection-page? + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 183 "`true` iff `x` quacks like a page in an ordered paged collection, else `false`." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 184 [x] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 185 (collection? x "OrderedCollectionPage")) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 186 + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 187 + </span><br/> + </body> +</html> diff --git a/docs/cloverage/dog_and_duck/scratch/core.clj.html b/docs/cloverage/dog_and_duck/scratch/core.clj.html new file mode 100644 index 0000000..eb11848 --- /dev/null +++ b/docs/cloverage/dog_and_duck/scratch/core.clj.html @@ -0,0 +1,26 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/core.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns dog-and-duck.scratch.core) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 002 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 003 (defn foo + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 "I don't do a whole lot." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 [x] + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 006 (println x "Hello, World!")) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/dog_and_duck/scratch/parser.clj.html b/docs/cloverage/dog_and_duck/scratch/parser.clj.html new file mode 100644 index 0000000..7f217ac --- /dev/null +++ b/docs/cloverage/dog_and_duck/scratch/parser.clj.html @@ -0,0 +1,143 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/parser.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns dog-and-duck.scratch.parser + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 (:require [clojure.java.io :refer [file]] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 [clojure.string :refer [ends-with?]] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 [clojure.walk :refer [keywordize-keys]] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 [clojure.data.json :as json] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 006 [dog-and-duck.quack.quack :as q])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 007 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 008 ;;; Copyright (C) Simon Brooke, 2022 + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 009 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 010 ;;; This program is free software; you can redistribute it and/or + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 011 ;;; modify it under the terms of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 012 ;;; as published by the Free Software Foundation; either version 2 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 013 ;;; of the License, or (at your option) any later version. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 014 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 015 ;;; This program is distributed in the hope that it will be useful, + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 016 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 017 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 018 ;;; GNU General Public License for more details. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 019 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 020 ;;; You should have received a copy of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 021 ;;; along with this program; if not, write to the Free Software + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 022 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 023 + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 024 (defn clean + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 025 "Take this `json` input, and return a sequence of ActivityPub objects + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 026 represented by it." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 027 [json] + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 028 (let [feed (json/read-str json)] + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 029 (map + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 030 keywordize-keys + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 031 (filter + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 032 q/object? + </span><br/> +<span class="partial" title="9 out of 11 forms covered"> + 033 (cond (map? feed) (list (keywordize-keys feed)) + </span><br/> +<span class="not-covered" title="0 out of 7 forms covered"> + 034 (coll? feed) (map keywordize-keys feed)))))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 035 + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 036 (clean (slurp "resources/activitystreams-test-documents/core-ex1-jsonld.json")) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 037 + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 038 (map + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 039 #(when + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 040 (ends-with? (str %) ".json") + </span><br/> +<span class="not-covered" title="0 out of 6 forms covered"> + 041 (let [objects (clean (slurp %))] + </span><br/> +<span class="not-covered" title="0 out of 5 forms covered"> + 042 (list (str %) + </span><br/> +<span class="not-covered" title="0 out of 2 forms covered"> + 043 (count objects) + </span><br/> +<span class="not-covered" title="0 out of 4 forms covered"> + 044 (map :type objects)))) + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 045 (file-seq (file "resources/activitystreams-test-documents"))) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/dog_and_duck/scratch/scratch.clj.html b/docs/cloverage/dog_and_duck/scratch/scratch.clj.html new file mode 100644 index 0000000..2991e30 --- /dev/null +++ b/docs/cloverage/dog_and_duck/scratch/scratch.clj.html @@ -0,0 +1,188 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/scratch.clj </title> + </head> + <body> +<span class="covered" title="1 out of 1 forms covered"> + 001 (ns dog-and-duck.scratch.scratch + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 002 "Scratchpad where I try to understand how to do this stuff." + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 003 (:require [clj-activitypub.core :as activitypub] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 004 [clj-activitypub.webfinger :as webfinger] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 005 [clj-pgp.core :as pgp] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 006 [clj-pgp.keyring :as keyring] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 007 [clj-pgp.generate :as pgp-gen] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 008 [clojure.walk :refer [keywordize-keys]] + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 009 [clojure.pprint :refer [pprint]])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 010 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 011 ;;; Copyright (C) Simon Brooke, 2022 + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 012 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 013 ;;; This program is free software; you can redistribute it and/or + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 014 ;;; modify it under the terms of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 015 ;;; as published by the Free Software Foundation; either version 2 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 016 ;;; of the License, or (at your option) any later version. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 017 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 018 ;;; This program is distributed in the hope that it will be useful, + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 019 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 020 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 021 ;;; GNU General Public License for more details. + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 022 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 023 ;;; You should have received a copy of the GNU General Public License + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 024 ;;; along with this program; if not, write to the Free Software + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 025 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 026 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 027 ;;; Use any ActivityPub account handle you like - for example, your own + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 028 (def account-handle "@simon_brooke@mastodon.scot") + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 029 + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 030 (def handle (activitypub/parse-account account-handle)) + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 031 (webfinger/fetch-user-id "mastodon.scot" "simon_brooke") + </span><br/> +<span class="covered" title="9 out of 9 forms covered"> + 032 (apply webfinger/fetch-user-id (map handle [:domain :username])) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 033 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 034 ;;; Retrieve the account details from its home server + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 035 ;;; (`keywordize-keys` is not necessary here but produces a more idiomatic clojure + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 036 ;;; data structure) + </span><br/> +<span class="covered" title="1 out of 1 forms covered"> + 037 (def account + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 038 "Fetch my account to mess with" + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 039 (let [handle (activitypub/parse-account account-handle)] + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 040 (keywordize-keys + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 041 (activitypub/fetch-user + </span><br/> +<span class="covered" title="9 out of 9 forms covered"> + 042 (apply webfinger/fetch-user-id (map handle [:domain :username])))))) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 043 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 044 ;;; examine what you got back! + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 045 (:outbox account) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 046 + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 047 + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 048 (def rsa (pgp-gen/rsa-keypair-generator 2048)) + </span><br/> +<span class="covered" title="5 out of 5 forms covered"> + 049 (def kp (pgp-gen/generate-keypair rsa :rsa-general)) + </span><br/> +<span class="blank" title="0 out of 0 forms covered"> + 050 + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 051 ;; how we make a public/private key pair. But this key pair is not the one + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 052 ;; known to mastodon.scot as my key pair, so that doesn't get us very far... + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 053 ;; I think. + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 054 (let [rsa (pgp-gen/rsa-keypair-generator 2048) + </span><br/> +<span class="covered" title="4 out of 4 forms covered"> + 055 kp (pgp-gen/generate-keypair rsa :rsa-general) + </span><br/> +<span class="covered" title="2 out of 2 forms covered"> + 056 public (-> kp .getPublicKey .getEncoded) + </span><br/> +<span class="covered" title="3 out of 3 forms covered"> + 057 private (-> kp .getPrivateKey .getPrivateKeyDataPacket .getEncoded)] + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 058 (println (str "Public key: " public)) + </span><br/> +<span class="covered" title="6 out of 6 forms covered"> + 059 (println (str "Private key: " private)) + </span><br/> +<span class="not-tracked" title="0 out of 0 forms covered"> + 060 ) + </span><br/> + </body> +</html> diff --git a/docs/cloverage/index.html b/docs/cloverage/index.html new file mode 100644 index 0000000..a11f17a --- /dev/null +++ b/docs/cloverage/index.html @@ -0,0 +1,164 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <link rel="stylesheet" href="./coverage.css"/> + <title>Coverage Summary</title> + </head> + <body> + <table> + <thead><tr> + <td class="ns-name"> Namespace </td> + <td class="with-bar"> Forms </td> +<td class="with-number">Forms %</td> + <td class="with-bar"> Lines </td> +<td class="with-number">Lines %</td> +<td class="with-number">Total</td><td class="with-number">Blank</td><td class="with-number">Instrumented</td> + </tr></thead> +<tr> + <td><a href="clj_activitypub/core.clj.html">clj-activitypub.core</a></td><td class="with-bar"><div class="covered" + style="width:23.588039867109636%; + float:left;"> 71 </div><div class="not-covered" + style="width:76.41196013289037%; + float:left;"> 230 </div></td> +<td class="with-number">23.59 %</td> +<td class="with-bar"><div class="covered" + style="width:27.906976744186046%; + float:left;"> 24 </div><div class="partial" + style="width:2.3255813953488373%; + float:left;"> 2 </div><div class="not-covered" + style="width:69.76744186046511%; + float:left;"> 60 </div></td> +<td class="with-number">30.23 %</td> +<td class="with-number">147</td><td class="with-number">14</td><td class="with-number">86</td> +</tr> +<tr> + <td><a href="clj_activitypub/internal/crypto.clj.html">clj-activitypub.internal.crypto</a></td><td class="with-bar"><div class="covered" + style="width:18.75%; + float:left;"> 9 </div><div class="not-covered" + style="width:81.25%; + float:left;"> 39 </div></td> +<td class="with-number">18.75 %</td> +<td class="with-bar"><div class="covered" + style="width:39.130434782608695%; + float:left;"> 9 </div><div class="not-covered" + style="width:60.869565217391305%; + float:left;"> 14 </div></td> +<td class="with-number">39.13 %</td> +<td class="with-number">36</td><td class="with-number">8</td><td class="with-number">23</td> +</tr> +<tr> + <td><a href="clj_activitypub/internal/http_util.clj.html">clj-activitypub.internal.http-util</a></td><td class="with-bar"><div class="covered" + style="width:74.35897435897436%; + float:left;"> 29 </div><div class="not-covered" + style="width:25.641025641025642%; + float:left;"> 10 </div></td> +<td class="with-number">74.36 %</td> +<td class="with-bar"><div class="covered" + style="width:80.0%; + float:left;"> 12 </div><div class="not-covered" + style="width:20.0%; + float:left;"> 3 </div></td> +<td class="with-number">80.00 %</td> +<td class="with-number">25</td><td class="with-number">3</td><td class="with-number">15</td> +</tr> +<tr> + <td><a href="clj_activitypub/internal/thread_cache.clj.html">clj-activitypub.internal.thread-cache</a></td><td class="with-bar"><div class="covered" + style="width:83.33333333333333%; + float:left;"> 105 </div><div class="not-covered" + style="width:16.666666666666668%; + float:left;"> 21 </div></td> +<td class="with-number">83.33 %</td> +<td class="with-bar"><div class="covered" + style="width:88.23529411764706%; + float:left;"> 30 </div><div class="partial" + style="width:2.9411764705882355%; + float:left;"> 1 </div><div class="not-covered" + style="width:8.823529411764707%; + float:left;"> 3 </div></td> +<td class="with-number">91.18 %</td> +<td class="with-number">44</td><td class="with-number">3</td><td class="with-number">34</td> +</tr> +<tr> + <td><a href="clj_activitypub/webfinger.clj.html">clj-activitypub.webfinger</a></td><td class="with-bar"><div class="covered" + style="width:95.53571428571429%; + float:left;"> 107 </div><div class="not-covered" + style="width:4.464285714285714%; + float:left;"> 5 </div></td> +<td class="with-number">95.54 %</td> +<td class="with-bar"><div class="covered" + style="width:88.88888888888889%; + float:left;"> 16 </div><div class="partial" + style="width:11.11111111111111%; + float:left;"> 2 </div></td> +<td class="with-number">100.00 %</td> +<td class="with-number">32</td><td class="with-number">5</td><td class="with-number">18</td> +</tr> +<tr> + <td><a href="dog_and_duck/quack/quack.clj.html">dog-and-duck.quack.quack</a></td><td class="with-bar"><div class="covered" + style="width:44.419642857142854%; + float:left;"> 199 </div><div class="not-covered" + style="width:55.580357142857146%; + float:left;"> 249 </div></td> +<td class="with-number">44.42 %</td> +<td class="with-bar"><div class="covered" + style="width:45.588235294117645%; + float:left;"> 31 </div><div class="partial" + style="width:7.352941176470588%; + float:left;"> 5 </div><div class="not-covered" + style="width:47.05882352941177%; + float:left;"> 32 </div></td> +<td class="with-number">52.94 %</td> +<td class="with-number">187</td><td class="with-number">26</td><td class="with-number">68</td> +</tr> +<tr> + <td><a href="dog_and_duck/scratch/core.clj.html">dog-and-duck.scratch.core</a></td><td class="with-bar"><div class="covered" + style="width:33.333333333333336%; + float:left;"> 2 </div><div class="not-covered" + style="width:66.66666666666667%; + float:left;"> 4 </div></td> +<td class="with-number">33.33 %</td> +<td class="with-bar"><div class="covered" + style="width:66.66666666666667%; + float:left;"> 2 </div><div class="not-covered" + style="width:33.333333333333336%; + float:left;"> 1 </div></td> +<td class="with-number">66.67 %</td> +<td class="with-number">6</td><td class="with-number">1</td><td class="with-number">3</td> +</tr> +<tr> + <td><a href="dog_and_duck/scratch/parser.clj.html">dog-and-duck.scratch.parser</a></td><td class="with-bar"><div class="covered" + style="width:50.0%; + float:left;"> 34 </div><div class="not-covered" + style="width:50.0%; + float:left;"> 34 </div></td> +<td class="with-number">50.00 %</td> +<td class="with-bar"><div class="covered" + style="width:55.55555555555556%; + float:left;"> 10 </div><div class="partial" + style="width:5.555555555555555%; + float:left;"> 1 </div><div class="not-covered" + style="width:38.888888888888886%; + float:left;"> 7 </div></td> +<td class="with-number">61.11 %</td> +<td class="with-number">45</td><td class="with-number">7</td><td class="with-number">18</td> +</tr> +<tr> + <td><a href="dog_and_duck/scratch/scratch.clj.html">dog-and-duck.scratch.scratch</a></td><td class="with-bar"><div class="covered" + style="width:100.0%; + float:left;"> 75 </div></td> +<td class="with-number">100.00 %</td> +<td class="with-bar"><div class="covered" + style="width:100.0%; + float:left;"> 19 </div></td> +<td class="with-number">100.00 %</td> +<td class="with-number">60</td><td class="with-number">9</td><td class="with-number">19</td> +</tr> +<tr><td>Totals:</td> +<td class="with-bar"></td> +<td class="with-number">51.59 %</td> +<td class="with-bar"></td> +<td class="with-number">57.75 %</td> + </tr> + </table> + </body> +</html> diff --git a/docs/codox/Using_ActivityPub.html b/docs/codox/Using_ActivityPub.html new file mode 100644 index 0000000..208f2cb --- /dev/null +++ b/docs/codox/Using_ActivityPub.html @@ -0,0 +1,112 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>Using ActivityPub</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#using-activitypub" name="using-activitypub"></a>Using ActivityPub</h1> +<pre><code class="clojure">user=> (require '[clj-activitypub.core :as activitypub]) +nil +user=> (require '[clj-activitypub.webfinger :as webfinger]) +nil +user=> (require '[clojure.walk :refer [keywordize-keys]]) +nil +user=> (require '[clojure.pprint :refer [pprint]]) +nil +user=> (def base-domain "mastodon.scot") +#'user/base-domain +user=> (def account-handle "@simon_brooke@mastodon.scot") +#'user/account-handle +user=> (in-ns 'user) +#object[clojure.lang.Namespace 0x525575 "user"] +user=> (activitypub/parse-account account-handle ) +{:domain "mastodon.scot", :username "simon_brooke"} +user=> (map *1 [:domain :username]) +("mastodon.scot" "simon_brooke") +user=> (apply webfinger/fetch-user-id *1) +"https://mastodon.scot/users/simon_brooke" +user=> (activitypub/fetch-user *1) +{"followers" "https://mastodon.scot/users/simon_brooke/followers", "inbox" "https://mastodon.scot/users/simon_brooke/inbox", "url" "https://mastodon.scot/@simon_brooke", "@context" ["https://www.w3.org/ns/activitystreams" "https://w3id.org/security/v1" {"identityKey" {"@type" "@id", "@id" "toot:identityKey"}, "EncryptedMessage" "toot:EncryptedMessage", "Ed25519Key" "toot:Ed25519Key", "devices" {"@type" "@id", "@id" "toot:devices"}, "manuallyApprovesFollowers" "as:manuallyApprovesFollowers", "schema" "http://schema.org#", "PropertyValue" "schema:PropertyValue", "Curve25519Key" "toot:Curve25519Key", "claim" {"@type" "@id", "@id" "toot:claim"}, "value" "schema:value", "Hashtag" "as:Hashtag", "movedTo" {"@id" "as:movedTo", "@type" "@id"}, "discoverable" "toot:discoverable", "messageType" "toot:messageType", "messageFranking" "toot:messageFranking", "cipherText" "toot:cipherText", "toot" "http://joinmastodon.org/ns#", "alsoKnownAs" {"@id" "as:alsoKnownAs", "@type" "@id"}, "featured" {"@id" "toot:featured", "@type" "@id"}, "featuredTags" {"@id" "toot:featuredTags", "@type" "@id"}, "Ed25519Signature" "toot:Ed25519Signature", "focalPoint" {"@container" "@list", "@id" "toot:focalPoint"}, "fingerprintKey" {"@type" "@id", "@id" "toot:fingerprintKey"}, "Device" "toot:Device", "publicKeyBase64" "toot:publicKeyBase64", "deviceId" "toot:deviceId", "suspended" "toot:suspended"}], "devices" "https://mastodon.scot/users/simon_brooke/collections/devices", "manuallyApprovesFollowers" false, "image" {"type" "Image", "mediaType" "image/jpeg", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"}, "endpoints" {"sharedInbox" "https://mastodon.scot/inbox"}, "id" "https://mastodon.scot/users/simon_brooke", "publicKey" {"id" "https://mastodon.scot/users/simon_brooke#main-key", "owner" "https://mastodon.scot/users/simon_brooke", "publicKeyPem" "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"}, "summary" "<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics &amp; environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>", "attachment" [{"type" "PropertyValue", "name" "Home Page", "value" "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}], "name" "Simon Brooke", "tag" [{"type" "Hashtag", "href" "https://mastodon.scot/tags/landreform", "name" "#landreform"}], "published" "2022-10-29T00:00:00Z", "preferredUsername" "simon_brooke", "discoverable" true, "alsoKnownAs" ["https://mastodon.social/users/simon_brooke"], "featured" "https://mastodon.scot/users/simon_brooke/collections/featured", "featuredTags" "https://mastodon.scot/users/simon_brooke/collections/tags", "type" "Person", "outbox" "https://mastodon.scot/users/simon_brooke/outbox", "following" "https://mastodon.scot/users/simon_brooke/following", "icon" {"type" "Image", "mediaType" "image/png", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"}} +user=> (def sb (keywordize-keys *1)) +#'user/sb +user=> (:outbox sb) +"https://mastodon.scot/users/simon_brooke/outbox" +user=> (require '[clojure.data.json :as json]) +nil +user=> (slurp (:outbox sb)) +Execution error (IOException) at sun.net.www.protocol.http.HttpURLConnection/getInputStream0 (HttpURLConnection.java:1894). +Server returned HTTP response code: 403 for URL: https://mastodon.scot/users/simon_brooke/outbox +user=> (pprint sb) +{:inbox "https://mastodon.scot/users/simon_brooke/inbox", + :name "Simon Brooke", + :@context + ["https://www.w3.org/ns/activitystreams" + "https://w3id.org/security/v1" + {:schema "http://schema.org#", + :messageType "toot:messageType", + :messageFranking "toot:messageFranking", + :identityKey {:@type "@id", :@id "toot:identityKey"}, + :Hashtag "as:Hashtag", + :deviceId "toot:deviceId", + :publicKeyBase64 "toot:publicKeyBase64", + :value "schema:value", + :Ed25519Key "toot:Ed25519Key", + :featured {:@id "toot:featured", :@type "@id"}, + :Curve25519Key "toot:Curve25519Key", + :discoverable "toot:discoverable", + :focalPoint {:@container "@list", :@id "toot:focalPoint"}, + :suspended "toot:suspended", + :fingerprintKey {:@type "@id", :@id "toot:fingerprintKey"}, + :Ed25519Signature "toot:Ed25519Signature", + :cipherText "toot:cipherText", + :EncryptedMessage "toot:EncryptedMessage", + :alsoKnownAs {:@id "as:alsoKnownAs", :@type "@id"}, + :featuredTags {:@id "toot:featuredTags", :@type "@id"}, + :devices {:@type "@id", :@id "toot:devices"}, + :toot "http://joinmastodon.org/ns#", + :movedTo {:@id "as:movedTo", :@type "@id"}, + :Device "toot:Device", + :PropertyValue "schema:PropertyValue", + :manuallyApprovesFollowers "as:manuallyApprovesFollowers", + :claim {:@type "@id", :@id "toot:claim"}}], + :featured + "https://mastodon.scot/users/simon_brooke/collections/featured", + :type "Person", + :discoverable true, + :icon + {:type "Image", + :mediaType "image/png", + :url + "https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"}, + :following "https://mastodon.scot/users/simon_brooke/following", + :summary + "<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics &amp; environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>", + :publicKey + {:id "https://mastodon.scot/users/simon_brooke#main-key", + :owner "https://mastodon.scot/users/simon_brooke", + :publicKeyPem + "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"}, + :endpoints {:sharedInbox "https://mastodon.scot/inbox"}, + :preferredUsername "simon_brooke", + :id "https://mastodon.scot/users/simon_brooke", + :alsoKnownAs ["https://mastodon.social/users/simon_brooke"], + :outbox "https://mastodon.scot/users/simon_brooke/outbox", + :url "https://mastodon.scot/@simon_brooke", + :featuredTags + "https://mastodon.scot/users/simon_brooke/collections/tags", + :devices + "https://mastodon.scot/users/simon_brooke/collections/devices", + :image + {:type "Image", + :mediaType "image/jpeg", + :url + "https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"}, + :tag + [{:type "Hashtag", + :href "https://mastodon.scot/tags/landreform", + :name "#landreform"}], + :followers "https://mastodon.scot/users/simon_brooke/followers", + :published "2022-10-29T00:00:00Z", + :manuallyApprovesFollowers false, + :attachment + [{:type "PropertyValue", + :name "Home Page", + :value + "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]} +</code></pre></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/clj-activitypub.core.html b/docs/codox/clj-activitypub.core.html new file mode 100644 index 0000000..9e763ef --- /dev/null +++ b/docs/codox/clj-activitypub.core.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>clj-activitypub.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch current"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clj-activitypub.core.html#var-activity"><div class="inner"><span>activity</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-actor"><div class="inner"><span>actor</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-auth-headers"><div class="inner"><span>auth-headers</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-config"><div class="inner"><span>config</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-fetch-user"><div class="inner"><span>fetch-user</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-gen-signature-header"><div class="inner"><span>gen-signature-header</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-obj"><div class="inner"><span>obj</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-parse-account"><div class="inner"><span>parse-account</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-signature-headers"><div class="inner"><span>signature-headers</span></div></a></li><li class="depth-1"><a href="clj-activitypub.core.html#var-with-config"><div class="inner"><span>with-config</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clj-activitypub.core</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-activity"><h3>activity</h3><h4 class="type">multimethod</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>Produces a map representing an ActivityPub activity which can be serialized directly to JSON in the form expected by the ActivityStreams 2.0 spec. See <a href="https://www.w3.org/TR/activitystreams-vocabulary/">https://www.w3.org/TR/activitystreams-vocabulary/</a> for reference.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L118">view source</a></div></div><div class="public anchor" id="var-actor"><h3>actor</h3><div class="usage"><code>(actor {:keys [user-id username public-key]})</code></div><div class="doc"><div class="markdown"><p>Accepts a config, and returns a map in the form expected by the ActivityPub spec. See <a href="https://www.w3.org/TR/activitypub/#actor-objects">https://www.w3.org/TR/activitypub/#actor-objects</a> for reference.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L44">view source</a></div></div><div class="public anchor" id="var-auth-headers"><h3>auth-headers</h3><div class="usage"><code>(auth-headers config {:keys [body headers]})</code></div><div class="doc"><div class="markdown"><p>Given a config and request map of {:body … :headers …}, returns the original set of headers with Signature and Digest attributes appended.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L86">view source</a></div></div><div class="public anchor" id="var-config"><h3>config</h3><div class="usage"><code>(config {:keys [domain username username-route public-key private-key], :or {username-route "/users/", public-key nil, private-key nil}})</code></div><div class="doc"><div class="markdown"><p>Creates hash of computed data relevant for most ActivityPub utilities.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L8">view source</a></div></div><div class="public anchor" id="var-fetch-user"><h3>fetch-user</h3><div class="usage"><code>(fetch-user user-id)</code></div><div class="doc"><div class="markdown"><p>Fetches the customer account details located at user-id from a remote server. Will return cached results if they exist in memory.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L32">view source</a></div></div><div class="public anchor" id="var-gen-signature-header"><h3>gen-signature-header</h3><div class="usage"><code>(gen-signature-header config headers)</code></div><div class="doc"><div class="markdown"><p>Generates a HTTP Signature string based on the provided map of headers.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L71">view source</a></div></div><div class="public anchor" id="var-obj"><h3>obj</h3><h4 class="type">multimethod</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>Produces a map representing an ActivityPub object which can be serialized directly to JSON in the form expected by the ActivityStreams 2.0 spec. See <a href="https://www.w3.org/TR/activitystreams-vocabulary/">https://www.w3.org/TR/activitystreams-vocabulary/</a> for reference.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L98">view source</a></div></div><div class="public anchor" id="var-parse-account"><h3>parse-account</h3><div class="usage"><code>(parse-account handle)</code></div><div class="doc"><div class="markdown"><p>Given an ActivityPub handle (e.g. @jahfer@mastodon.social), produces a map containing {:domain … :username …}.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L23">view source</a></div></div><div class="public anchor" id="var-signature-headers"><h3>signature-headers</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L59">view source</a></div></div><div class="public anchor" id="var-with-config"><h3>with-config</h3><div class="usage"><code>(with-config config)</code></div><div class="doc"><div class="markdown"><p>Returns curried forms of the #activity and #obj multimethods in the form {:activity … :obj …}, with the initial parameter set to config.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/core.clj#L138">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/clj-activitypub.internal.crypto.html b/docs/codox/clj-activitypub.internal.crypto.html new file mode 100644 index 0000000..89605eb --- /dev/null +++ b/docs/codox/clj-activitypub.internal.crypto.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>clj-activitypub.internal.crypto documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch current"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clj-activitypub.internal.crypto.html#var-base64-encode"><div class="inner"><span>base64-encode</span></div></a></li><li class="depth-1"><a href="clj-activitypub.internal.crypto.html#var-private-key"><div class="inner"><span>private-key</span></div></a></li><li class="depth-1"><a href="clj-activitypub.internal.crypto.html#var-sha256-base64"><div class="inner"><span>sha256-base64</span></div></a></li><li class="depth-1"><a href="clj-activitypub.internal.crypto.html#var-sign"><div class="inner"><span>sign</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clj-activitypub.internal.crypto</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-base64-encode"><h3>base64-encode</h3><div class="usage"><code>(base64-encode bytes)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/crypto.clj#L23">view source</a></div></div><div class="public anchor" id="var-private-key"><h3>private-key</h3><div class="usage"><code>(private-key private-pem-str)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/crypto.clj#L18">view source</a></div></div><div class="public anchor" id="var-sha256-base64"><h3>sha256-base64</h3><div class="usage"><code>(sha256-base64 data)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/crypto.clj#L26">view source</a></div></div><div class="public anchor" id="var-sign"><h3>sign</h3><div class="usage"><code>(sign data private-key)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/crypto.clj#L30">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/clj-activitypub.internal.http-util.html b/docs/codox/clj-activitypub.internal.http-util.html new file mode 100644 index 0000000..2726e1a --- /dev/null +++ b/docs/codox/clj-activitypub.internal.http-util.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>clj-activitypub.internal.http-util documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch current"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clj-activitypub.internal.http-util.html#var-date"><div class="inner"><span>date</span></div></a></li><li class="depth-1"><a href="clj-activitypub.internal.http-util.html#var-digest"><div class="inner"><span>digest</span></div></a></li><li class="depth-1"><a href="clj-activitypub.internal.http-util.html#var-encode-url-params"><div class="inner"><span>encode-url-params</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clj-activitypub.internal.http-util</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-date"><h3>date</h3><div class="usage"><code>(date)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/http_util.clj#L17">view source</a></div></div><div class="public anchor" id="var-digest"><h3>digest</h3><div class="usage"><code>(digest body)</code></div><div class="doc"><div class="markdown"><p>Accepts body from HTTP request and generates string for use in HTTP <code>Digest</code> request header.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/http_util.clj#L21">view source</a></div></div><div class="public anchor" id="var-encode-url-params"><h3>encode-url-params</h3><div class="usage"><code>(encode-url-params params)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/http_util.clj#L7">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/clj-activitypub.internal.thread-cache.html b/docs/codox/clj-activitypub.internal.thread-cache.html new file mode 100644 index 0000000..627ef04 --- /dev/null +++ b/docs/codox/clj-activitypub.internal.thread-cache.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>clj-activitypub.internal.thread-cache documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3 current"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clj-activitypub.internal.thread-cache.html#var-make"><div class="inner"><span>make</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clj-activitypub.internal.thread-cache</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-make"><h3>make</h3><div class="usage"><code>(make)</code><code>(make cache-if-nil)</code></div><div class="doc"><div class="markdown"><p>Creates a thread-local cache.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/internal/thread_cache.clj#L13">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/clj-activitypub.webfinger.html b/docs/codox/clj-activitypub.webfinger.html new file mode 100644 index 0000000..bebfcf9 --- /dev/null +++ b/docs/codox/clj-activitypub.webfinger.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>clj-activitypub.webfinger documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2 current"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clj-activitypub.webfinger.html#var-fetch-user-id"><div class="inner"><span>fetch-user-id</span></div></a></li><li class="depth-1"><a href="clj-activitypub.webfinger.html#var-remote-uri-path"><div class="inner"><span>remote-uri-path</span></div></a></li><li class="depth-1"><a href="clj-activitypub.webfinger.html#var-resource-url"><div class="inner"><span>resource-url</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clj-activitypub.webfinger</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-fetch-user-id"><h3>fetch-user-id</h3><div class="usage"><code>(fetch-user-id domain username)</code></div><div class="doc"><div class="markdown"><p>Follows the webfinger request to a remote domain, retrieving the ID of the requested account. Typically returns a string in the form of a URL.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/webfinger.clj#L21">view source</a></div></div><div class="public anchor" id="var-remote-uri-path"><h3>remote-uri-path</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/webfinger.clj#L6">view source</a></div></div><div class="public anchor" id="var-resource-url"><h3>resource-url</h3><div class="usage"><code>(resource-url domain username & [params])</code></div><div class="doc"><div class="markdown"><p>Builds a URL pointing to the user’s account on the remote server.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/clj_activitypub/webfinger.clj#L11">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/css/default.css b/docs/codox/css/default.css new file mode 100644 index 0000000..33f78fe --- /dev/null +++ b/docs/codox/css/default.css @@ -0,0 +1,551 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 15px; +} + +pre, code { + font-family: Monaco, DejaVu Sans Mono, Consolas, monospace; + font-size: 9pt; + margin: 15px 0; +} + +h1 { + font-weight: normal; + font-size: 29px; + margin: 10px 0 2px 0; + padding: 0; +} + +h2 { + font-weight: normal; + font-size: 25px; +} + +h5.license { + margin: 9px 0 22px 0; + color: #555; + font-weight: normal; + font-size: 12px; + font-style: italic; +} + +.document h1, .namespace-index h1 { + font-size: 32px; + margin-top: 12px; +} + +#header, #content, .sidebar { + position: fixed; +} + +#header { + top: 0; + left: 0; + right: 0; + height: 22px; + color: #f5f5f5; + padding: 5px 7px; +} + +#content { + top: 32px; + right: 0; + bottom: 0; + overflow: auto; + background: #fff; + color: #333; + padding: 0 18px; +} + +.sidebar { + position: fixed; + top: 32px; + bottom: 0; + overflow: auto; +} + +.sidebar.primary { + background: #e2e2e2; + border-right: solid 1px #cccccc; + left: 0; + width: 250px; +} + +.sidebar.secondary { + background: #f2f2f2; + border-right: solid 1px #d7d7d7; + left: 251px; + width: 200px; +} + +#content.namespace-index, #content.document { + left: 251px; +} + +#content.namespace-docs { + left: 452px; +} + +#content.document { + padding-bottom: 10%; +} + +#header { + background: #3f3f3f; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); + z-index: 100; +} + +#header h1 { + margin: 0; + padding: 0; + font-size: 18px; + font-weight: lighter; + text-shadow: -1px -1px 0px #333; +} + +#header h1 .project-version { + font-weight: normal; +} + +.project-version { + padding-left: 0.15em; +} + +#header a, .sidebar a { + display: block; + text-decoration: none; +} + +#header a { + color: #f5f5f5; +} + +.sidebar a { + color: #333; +} + +#header h2 { + float: right; + font-size: 9pt; + font-weight: normal; + margin: 4px 3px; + padding: 0; + color: #bbb; +} + +#header h2 a { + display: inline; +} + +.sidebar h3 { + margin: 0; + padding: 10px 13px 0 13px; + font-size: 19px; + font-weight: lighter; +} + +.sidebar h3 a { + color: #444; +} + +.sidebar h3.no-link { + color: #636363; +} + +.sidebar ul { + padding: 7px 0 6px 0; + margin: 0; +} + +.sidebar ul.index-link { + padding-bottom: 4px; +} + +.sidebar li { + display: block; + vertical-align: middle; +} + +.sidebar li a, .sidebar li .no-link { + border-left: 3px solid transparent; + padding: 0 10px; + white-space: nowrap; +} + +.sidebar li .no-link { + display: block; + color: #777; + font-style: italic; +} + +.sidebar li .inner { + display: inline-block; + padding-top: 7px; + height: 24px; +} + +.sidebar li a, .sidebar li .tree { + height: 31px; +} + +.depth-1 .inner { padding-left: 2px; } +.depth-2 .inner { padding-left: 6px; } +.depth-3 .inner { padding-left: 20px; } +.depth-4 .inner { padding-left: 34px; } +.depth-5 .inner { padding-left: 48px; } +.depth-6 .inner { padding-left: 62px; } + +.sidebar li .tree { + display: block; + float: left; + position: relative; + top: -10px; + margin: 0 4px 0 0; + padding: 0; +} + +.sidebar li.depth-1 .tree { + display: none; +} + +.sidebar li .tree .top, .sidebar li .tree .bottom { + display: block; + margin: 0; + padding: 0; + width: 7px; +} + +.sidebar li .tree .top { + border-left: 1px solid #aaa; + border-bottom: 1px solid #aaa; + height: 19px; +} + +.sidebar li .tree .bottom { + height: 22px; +} + +.sidebar li.branch .tree .bottom { + border-left: 1px solid #aaa; +} + +.sidebar.primary li.current a { + border-left: 3px solid #a33; + color: #a33; +} + +.sidebar.secondary li.current a { + border-left: 3px solid #33a; + color: #33a; +} + +.namespace-index h2 { + margin: 30px 0 0 0; +} + +.namespace-index h3 { + font-size: 16px; + font-weight: bold; + margin-bottom: 0; +} + +.namespace-index .topics { + padding-left: 30px; + margin: 11px 0 0 0; +} + +.namespace-index .topics li { + padding: 5px 0; +} + +.namespace-docs h3 { + font-size: 18px; + font-weight: bold; +} + +.public h3 { + margin: 0; + float: left; +} + +.usage { + clear: both; +} + +.public { + margin: 0; + border-top: 1px solid #e0e0e0; + padding-top: 14px; + padding-bottom: 6px; +} + +.public:last-child { + margin-bottom: 20%; +} + +.members .public:last-child { + margin-bottom: 0; +} + +.members { + margin: 15px 0; +} + +.members h4 { + color: #555; + font-weight: normal; + font-variant: small-caps; + margin: 0 0 5px 0; +} + +.members .inner { + padding-top: 5px; + padding-left: 12px; + margin-top: 2px; + margin-left: 7px; + border-left: 1px solid #bbb; +} + +#content .members .inner h3 { + font-size: 12pt; +} + +.members .public { + border-top: none; + margin-top: 0; + padding-top: 6px; + padding-bottom: 0; +} + +.members .public:first-child { + padding-top: 0; +} + +h4.type, +h4.dynamic, +h4.added, +h4.deprecated { + float: left; + margin: 3px 10px 15px 0; + font-size: 15px; + font-weight: bold; + font-variant: small-caps; +} + +.public h4.type, +.public h4.dynamic, +.public h4.added, +.public h4.deprecated { + font-size: 13px; + font-weight: bold; + margin: 3px 0 0 10px; +} + +.members h4.type, +.members h4.added, +.members h4.deprecated { + margin-top: 1px; +} + +h4.type { + color: #717171; +} + +h4.dynamic { + color: #9933aa; +} + +h4.added { + color: #508820; +} + +h4.deprecated { + color: #880000; +} + +.namespace { + margin-bottom: 30px; +} + +.namespace:last-child { + margin-bottom: 10%; +} + +.index { + padding: 0; + font-size: 80%; + margin: 15px 0; + line-height: 16px; +} + +.index * { + display: inline; +} + +.index p { + padding-right: 3px; +} + +.index li { + padding-right: 5px; +} + +.index ul { + padding-left: 0; +} + +.type-sig { + clear: both; + color: #088; +} + +.type-sig pre { + padding-top: 10px; + margin: 0; +} + +.usage code { + display: block; + color: #008; + margin: 2px 0; +} + +.usage code:first-child { + padding-top: 10px; +} + +p { + margin: 15px 0; +} + +.public p:first-child, .public pre.plaintext { + margin-top: 12px; +} + +.doc { + margin: 0 0 26px 0; + clear: both; +} + +.public .doc { + margin: 0; +} + +.namespace-index .doc { + margin-bottom: 20px; +} + +.namespace-index .namespace .doc { + margin-bottom: 10px; +} + +.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td { + line-height: 22px; +} + +.markdown li { + padding: 2px 0; +} + +.markdown h2 { + font-weight: normal; + font-size: 25px; + margin: 30px 0 10px 0; +} + +.markdown h3 { + font-weight: normal; + font-size: 20px; + margin: 30px 0 0 0; +} + +.markdown h4 { + font-size: 15px; + margin: 22px 0 -4px 0; +} + +.doc, .public, .namespace .index { + max-width: 680px; + overflow-x: visible; +} + +.markdown pre > code { + display: block; + padding: 10px; +} + +.markdown pre > code, .src-link a { + border: 1px solid #e4e4e4; + border-radius: 2px; +} + +.markdown code:not(.hljs), .src-link a { + background: #f6f6f6; +} + +pre.deps { + display: inline-block; + margin: 0 10px; + border: 1px solid #e4e4e4; + border-radius: 2px; + padding: 10px; + background-color: #f6f6f6; +} + +.markdown hr { + border-style: solid; + border-top: none; + color: #ccc; +} + +.doc ul, .doc ol { + padding-left: 30px; +} + +.doc table { + border-collapse: collapse; + margin: 0 10px; +} + +.doc table td, .doc table th { + border: 1px solid #dddddd; + padding: 4px 6px; +} + +.doc table th { + background: #f2f2f2; +} + +.doc dl { + margin: 0 10px 20px 10px; +} + +.doc dl dt { + font-weight: bold; + margin: 0; + padding: 3px 0; + border-bottom: 1px solid #ddd; +} + +.doc dl dd { + padding: 5px 0; + margin: 0 0 5px 10px; +} + +.doc abbr { + border-bottom: 1px dotted #333; + font-variant: none; + cursor: help; +} + +.src-link { + margin-bottom: 15px; +} + +.src-link a { + font-size: 70%; + padding: 1px 4px; + text-decoration: none; + color: #5555bb; +} diff --git a/docs/codox/css/highlight.css b/docs/codox/css/highlight.css new file mode 100644 index 0000000..d0cdaa3 --- /dev/null +++ b/docs/codox/css/highlight.css @@ -0,0 +1,97 @@ +/* +github.com style (c) Vasily Polovnyov <vast@whiteants.net> +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/docs/codox/dog-and-duck.quack.quack.html b/docs/codox/dog-and-duck.quack.quack.html new file mode 100644 index 0000000..3382dad --- /dev/null +++ b/docs/codox/dog-and-duck.quack.quack.html @@ -0,0 +1,14 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>dog-and-duck.quack.quack documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3 current"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-activity.3F"><div class="inner"><span>activity?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-activitystreams-context-uri"><div class="inner"><span>activitystreams-context-uri</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-actor-type.3F"><div class="inner"><span>actor-type?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-actor-types"><div class="inner"><span>actor-types</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-actor.3F"><div class="inner"><span>actor?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-collection-page.3F"><div class="inner"><span>collection-page?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-collection.3F"><div class="inner"><span>collection?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-context.3F"><div class="inner"><span>context?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-has-context.3F"><div class="inner"><span>has-context?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-link-or-uri.3F"><div class="inner"><span>link-or-uri?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-link.3F"><div class="inner"><span>link?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-object.3F"><div class="inner"><span>object?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-ordered-collection-page.3F"><div class="inner"><span>ordered-collection-page?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-ordered-collection.3F"><div class="inner"><span>ordered-collection?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-persistent-object.3F"><div class="inner"><span>persistent-object?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-unordered-collection.3F"><div class="inner"><span>unordered-collection?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-verb-type.3F"><div class="inner"><span>verb-type?</span></div></a></li><li class="depth-1"><a href="dog-and-duck.quack.quack.html#var-verb-types"><div class="inner"><span>verb-types</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">dog-and-duck.quack.quack</h1><div class="doc"><div class="markdown"><p>Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck…</p></div></div><div class="public anchor" id="var-activity.3F"><h3>activity?</h3><div class="usage"><code>(activity? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like an activity, else false.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L114">view source</a></div></div><div class="public anchor" id="var-activitystreams-context-uri"><h3>activitystreams-context-uri</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>The URI of the context of an ActivityStreams object is expected to be this literal string.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L80">view source</a></div></div><div class="public anchor" id="var-actor-type.3F"><h3>actor-type?</h3><div class="usage"><code>(actor-type? x)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L60">view source</a></div></div><div class="public anchor" id="var-actor-types"><h3>actor-types</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>The set of types we will accept as actors.</p> +<p>There’s an <a href="https://www.w3.org/TR/activitystreams-vocabulary/#actor-types">explicit set of allowed actor types</a>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L49">view source</a></div></div><div class="public anchor" id="var-actor.3F"><h3>actor?</h3><div class="usage"><code>(actor? x)</code></div><div class="doc"><div class="markdown"><p>Returns <code>true</code> if <code>x</code> quacks like an actor, else false.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L103">view source</a></div></div><div class="public anchor" id="var-collection-page.3F"><h3>collection-page?</h3><div class="usage"><code>(collection-page? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like a page in a paged collection, else <code>false</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L177">view source</a></div></div><div class="public anchor" id="var-collection.3F"><h3>collection?</h3><div class="usage"><code>(collection? x type)</code><code>(collection? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like a collection of type <code>type</code>, else <code>false</code>.</p> +<p>With one argument, will recognise plain collections and ordered collections, but (currently) not collection pages.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L146">view source</a></div></div><div class="public anchor" id="var-context.3F"><h3>context?</h3><div class="usage"><code>(context? x)</code></div><div class="doc"><div class="markdown"><p>Returns <code>true</code> iff <code>x</code> quacks like an ActivityStreams context, else false.</p> +<p>A context is either 1. the URI (actually an IRI) <code>activitystreams-context-uri</code>, or 2. a collection comprising that URI and a map.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L85">view source</a></div></div><div class="public anchor" id="var-has-context.3F"><h3>has-context?</h3><h4 class="type">macro</h4><div class="usage"><code>(has-context? x)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L100">view source</a></div></div><div class="public anchor" id="var-link-or-uri.3F"><h3>link-or-uri?</h3><div class="usage"><code>(link-or-uri? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> is either a URI or a link, else false.</p> +<p>There are several points in the specification where e.g. the <code>:image</code> property (if present) may be either a link or a URI.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L135">view source</a></div></div><div class="public anchor" id="var-link.3F"><h3>link?</h3><div class="usage"><code>(link? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like a link, else false.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L127">view source</a></div></div><div class="public anchor" id="var-object.3F"><h3>object?</h3><div class="usage"><code>(object? x)</code></div><div class="doc"><div class="markdown"><p>Returns <code>true</code> iff <code>x</code> is recognisably an ActivityStreams object.</p> +<p><strong>NOTE THAT</strong> The ActivityStreams spec <a href="https://www.w3.org/TR/activitystreams-core/#object">says</a>:</p> +<blockquote> + <p>All properties are optional (including the id and type)</p> +</blockquote> +<p>But we are <em>just not having that</em>, because otherwise we’re flying blind. We <em>shall</em> reject objects lacking at least <code>:type</code>. Missing <code>:id</code> keys are tolerable because they represent transient objects, which we expect to handle.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L22">view source</a></div></div><div class="public anchor" id="var-ordered-collection-page.3F"><h3>ordered-collection-page?</h3><div class="usage"><code>(ordered-collection-page? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like a page in an ordered paged collection, else <code>false</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L182">view source</a></div></div><div class="public anchor" id="var-ordered-collection.3F"><h3>ordered-collection?</h3><div class="usage"><code>(ordered-collection? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like an ordered collection, else <code>false</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L172">view source</a></div></div><div class="public anchor" id="var-persistent-object.3F"><h3>persistent-object?</h3><div class="usage"><code>(persistent-object? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> is a persistent object.</p> +<p>Transient objects in ActivityPub are not required to have an <code>id</code> key, but persistent ones must have a key, and it must be an IRI (but normally a URI).</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L37">view source</a></div></div><div class="public anchor" id="var-unordered-collection.3F"><h3>unordered-collection?</h3><div class="usage"><code>(unordered-collection? x)</code></div><div class="doc"><div class="markdown"><p><code>true</code> iff <code>x</code> quacks like an unordered collection, else <code>false</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L167">view source</a></div></div><div class="public anchor" id="var-verb-type.3F"><h3>verb-type?</h3><div class="usage"><code>(verb-type? x)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L75">view source</a></div></div><div class="public anchor" id="var-verb-types"><h3>verb-types</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>The set of types we will accept as verbs.</p> +<p>There’s an <a href="https://www.w3.org/TR/activitystreams-vocabulary/#activity-types">explicit set of allowed verb types</a>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/quack/quack.clj#L65">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/dog-and-duck.scratch.core.html b/docs/codox/dog-and-duck.scratch.core.html new file mode 100644 index 0000000..30b1865 --- /dev/null +++ b/docs/codox/dog-and-duck.scratch.core.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>dog-and-duck.scratch.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch current"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="dog-and-duck.scratch.core.html#var-foo"><div class="inner"><span>foo</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">dog-and-duck.scratch.core</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-foo"><h3>foo</h3><div class="usage"><code>(foo x)</code></div><div class="doc"><div class="markdown"><p>I don’t do a whole lot.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/core.clj#L3">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/dog-and-duck.scratch.parser.html b/docs/codox/dog-and-duck.scratch.parser.html new file mode 100644 index 0000000..8f8968c --- /dev/null +++ b/docs/codox/dog-and-duck.scratch.parser.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>dog-and-duck.scratch.parser documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch current"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="dog-and-duck.scratch.parser.html#var-clean"><div class="inner"><span>clean</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">dog-and-duck.scratch.parser</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-clean"><h3>clean</h3><div class="usage"><code>(clean json)</code></div><div class="doc"><div class="markdown"><p>Take this <code>json</code> input, and return a sequence of ActivityPub objects represented by it.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/parser.clj#L24">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/dog-and-duck.scratch.scratch.html b/docs/codox/dog-and-duck.scratch.scratch.html new file mode 100644 index 0000000..be30ecf --- /dev/null +++ b/docs/codox/dog-and-duck.scratch.scratch.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>dog-and-duck.scratch.scratch documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3 current"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="dog-and-duck.scratch.scratch.html#var-account"><div class="inner"><span>account</span></div></a></li><li class="depth-1"><a href="dog-and-duck.scratch.scratch.html#var-account-handle"><div class="inner"><span>account-handle</span></div></a></li><li class="depth-1"><a href="dog-and-duck.scratch.scratch.html#var-handle"><div class="inner"><span>handle</span></div></a></li><li class="depth-1"><a href="dog-and-duck.scratch.scratch.html#var-kp"><div class="inner"><span>kp</span></div></a></li><li class="depth-1"><a href="dog-and-duck.scratch.scratch.html#var-rsa"><div class="inner"><span>rsa</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">dog-and-duck.scratch.scratch</h1><div class="doc"><div class="markdown"><p>Scratchpad where I try to understand how to do this stuff.</p></div></div><div class="public anchor" id="var-account"><h3>account</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Fetch my account to mess with</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/scratch.clj#L37">view source</a></div></div><div class="public anchor" id="var-account-handle"><h3>account-handle</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/scratch.clj#L28">view source</a></div></div><div class="public anchor" id="var-handle"><h3>handle</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/scratch.clj#L30">view source</a></div></div><div class="public anchor" id="var-kp"><h3>kp</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/scratch.clj#L49">view source</a></div></div><div class="public anchor" id="var-rsa"><h3>rsa</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/scratch.clj#L48">view source</a></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/index.html b/docs/codox/index.html new file mode 100644 index 0000000..f194bc9 --- /dev/null +++ b/docs/codox/index.html @@ -0,0 +1,3 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>Dog-and-duck 0.1.0-SNAPSHOT</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 current"><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="namespace-index" id="content"><h1><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></h1><h5 class="license">Released under the <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">GPL-2.0-or-later</a></h5><div class="doc"><p>A Clojure library designed to implement the ActivityPub protocol.</p></div><h2>Installation</h2><p>To install, add the following dependency to your project or build file:</p><pre class="deps">[dog-and-duck "0.1.0-SNAPSHOT"]</pre><h2>Topics</h2><ul class="topics"><li><a href="Using_ActivityPub.html">Using ActivityPub</a></li><li><a href="intro.html">The Old Dog and Duck</a></li></ul><h2>Namespaces</h2><div class="namespace"><h3><a href="clj-activitypub.core.html">clj-activitypub.core</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="clj-activitypub.core.html#var-activity">activity</a> </li><li> <a href="clj-activitypub.core.html#var-actor">actor</a> </li><li> <a href="clj-activitypub.core.html#var-auth-headers">auth-headers</a> </li><li> <a href="clj-activitypub.core.html#var-config">config</a> </li><li> <a href="clj-activitypub.core.html#var-fetch-user">fetch-user</a> </li><li> <a href="clj-activitypub.core.html#var-gen-signature-header">gen-signature-header</a> </li><li> <a href="clj-activitypub.core.html#var-obj">obj</a> </li><li> <a href="clj-activitypub.core.html#var-parse-account">parse-account</a> </li><li> <a href="clj-activitypub.core.html#var-signature-headers">signature-headers</a> </li><li> <a href="clj-activitypub.core.html#var-with-config">with-config</a> </li></ul></div></div><div class="namespace"><h3><a href="clj-activitypub.internal.crypto.html">clj-activitypub.internal.crypto</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="clj-activitypub.internal.crypto.html#var-base64-encode">base64-encode</a> </li><li> <a href="clj-activitypub.internal.crypto.html#var-private-key">private-key</a> </li><li> <a href="clj-activitypub.internal.crypto.html#var-sha256-base64">sha256-base64</a> </li><li> <a href="clj-activitypub.internal.crypto.html#var-sign">sign</a> </li></ul></div></div><div class="namespace"><h3><a href="clj-activitypub.internal.http-util.html">clj-activitypub.internal.http-util</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="clj-activitypub.internal.http-util.html#var-date">date</a> </li><li> <a href="clj-activitypub.internal.http-util.html#var-digest">digest</a> </li><li> <a href="clj-activitypub.internal.http-util.html#var-encode-url-params">encode-url-params</a> </li></ul></div></div><div class="namespace"><h3><a href="clj-activitypub.internal.thread-cache.html">clj-activitypub.internal.thread-cache</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="clj-activitypub.internal.thread-cache.html#var-make">make</a> </li></ul></div></div><div class="namespace"><h3><a href="clj-activitypub.webfinger.html">clj-activitypub.webfinger</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="clj-activitypub.webfinger.html#var-fetch-user-id">fetch-user-id</a> </li><li> <a href="clj-activitypub.webfinger.html#var-remote-uri-path">remote-uri-path</a> </li><li> <a href="clj-activitypub.webfinger.html#var-resource-url">resource-url</a> </li></ul></div></div><div class="namespace"><h3><a href="dog-and-duck.quack.quack.html">dog-and-duck.quack.quack</a></h3><div class="doc"><div class="markdown"><p>Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck…</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="dog-and-duck.quack.quack.html#var-activity.3F">activity?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-activitystreams-context-uri">activitystreams-context-uri</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-actor-type.3F">actor-type?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-actor-types">actor-types</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-actor.3F">actor?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-collection-page.3F">collection-page?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-collection.3F">collection?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-context.3F">context?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-has-context.3F">has-context?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-link-or-uri.3F">link-or-uri?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-link.3F">link?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-object.3F">object?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-ordered-collection-page.3F">ordered-collection-page?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-ordered-collection.3F">ordered-collection?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-persistent-object.3F">persistent-object?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-unordered-collection.3F">unordered-collection?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-verb-type.3F">verb-type?</a> </li><li> <a href="dog-and-duck.quack.quack.html#var-verb-types">verb-types</a> </li></ul></div></div><div class="namespace"><h3><a href="dog-and-duck.scratch.core.html">dog-and-duck.scratch.core</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="dog-and-duck.scratch.core.html#var-foo">foo</a> </li></ul></div></div><div class="namespace"><h3><a href="dog-and-duck.scratch.parser.html">dog-and-duck.scratch.parser</a></h3><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="dog-and-duck.scratch.parser.html#var-clean">clean</a> </li></ul></div></div><div class="namespace"><h3><a href="dog-and-duck.scratch.scratch.html">dog-and-duck.scratch.scratch</a></h3><div class="doc"><div class="markdown"><p>Scratchpad where I try to understand how to do this stuff.</p></div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="dog-and-duck.scratch.scratch.html#var-account">account</a> </li><li> <a href="dog-and-duck.scratch.scratch.html#var-account-handle">account-handle</a> </li><li> <a href="dog-and-duck.scratch.scratch.html#var-handle">handle</a> </li><li> <a href="dog-and-duck.scratch.scratch.html#var-kp">kp</a> </li><li> <a href="dog-and-duck.scratch.scratch.html#var-rsa">rsa</a> </li></ul></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html new file mode 100644 index 0000000..6a5fb84 --- /dev/null +++ b/docs/codox/intro.html @@ -0,0 +1,46 @@ +<!DOCTYPE html PUBLIC "" + ""> +<html><head><meta charset="UTF-8" /><title>The Old Dog and Duck</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#the-old-dog-and-duck" name="the-old-dog-and-duck"></a>The Old Dog and Duck</h1> +<p>A Clojure library designed to implement the ActivityPub protocol, obviously.</p> +<h2><a href="#introduction" name="introduction"></a>Introduction</h2> +<p>The Old Dog and Duck is clearly a pub, and it’s a pub related to an activity; to whit, hunting ducks with dogs. Yes, of course one could also hunt dogs with ducks, but in practice that doesn’t work so well. The point isn’t whether or not I approve of hunting ducks with dogs (or vice versa); to be clear, I don’t. The point is that it’s a pub related to an activity, and is therefore an <a href="https://www.w3.org/TR/activitypub/">ActivityPub</a>.</p> +<p>Are we clear?</p> +<p>Good.</p> +<p>Let us proceed.</p> +<p><strong>The Old Dog and Duck</strong> is intended to be a set of libraries to enable people to build stuff which interacts with ActivityPub. It isn’t intended to be a replacement for, or clone of, Mastodon. I do think I might implement my own ActivityPub server on top of The Old Dog and Duck, that specifically might allow for user-pluggable feed-sorting algorithms and with my own user interface/user experience take, but that project is not (yet, at any rate) this project.</p> +<h2><a href="#status" name="status"></a>Status</h2> +<p>This is a long way pre-alpha. Everything will change. Feel free to play, but do so at your own risk. Contributions welcome.</p> +<h2><a href="#architecture" name="architecture"></a>Architecture</h2> +<p>There are a number of separate concerns required to implement ActivityPub. They include</p> +<ol> + <li>Parsing ActivityStreams messages received from peers and from clients;</li> + <li>Persisting ActivityStreams objects;</li> + <li>Delivering ActivityStreams objects to peers;</li> + <li>Delivering ActivityStreams objects to clients.</li> +</ol> +<p><strong>NOTE THAT</strong> what Mastodon delivers to clients is not actually in ActivityStreams format; this seems to be an ad-hoc hack that’s just never been fixed and has therefore become a de-facto standard for communication between ActivityPub hosts and their clients.</p> +<p>My proposal would be to deliver exactly the same ActivityStreams format to my client as to other servers. There may be a valid reason for not doing this, but if there is I will discover it in due course.</p> +<h2><a href="#proposed-dog-and-duck-libraries" name="proposed-dog-and-duck-libraries"></a>Proposed dog-and-duck libraries</h2> +<p><strong>NOTE THAT</strong> at the present stage all the proposed libraries are in one package, namely this package, but that it is proposed that in future they will form separate libraries in separate packages.</p> +<h3><a href="#bar" name="bar"></a>Bar</h3> +<p>Where conversations happen. Handle interactions with clients.</p> +<h3><a href="#cellar" name="cellar"></a>Cellar</h3> +<p>Where things are stored. Persistance for ActivityStreams objects; I may at least initially simply copy the Mastodon postgres schema, but equally I may not.</p> +<h3><a href="#pantry" name="pantry"></a>Pantry</h3> +<p>Where deliveries are ordered and arrive; and from where deliveries onwards are despatched. Handle interactions with peers.</p> +<h3><a href="#quack" name="quack"></a>Quack</h3> +<p>Duck-typing for ActivityStreams objects.</p> +<p>As of version 0.1.0, this is substantially the only part that is yet at all useful, and it is still a long way from finished or robust.</p> +<h3><a href="#scratch" name="scratch"></a>Scratch</h3> +<p>What the dog does when bored. Essentially, a place where I can learn how to make this stuff work, but perhaps eventually an ActivityPub server in its own right.</p> +<h2><a href="#usage" name="usage"></a>Usage</h2> +<p>At present, only the duck-typing functions work. To play with them, use</p> +<pre><code class="clojure">(require '[dog-and-duck.quack.quack :as q]) +</code></pre> +<h2><a href="#testing" name="testing"></a>Testing</h2> +<p>Prior to testing, you should clone <a href="https://github.com/w3c-social/activitystreams-test-documents">activitystreams-test-documents</a> into the <code>resources</code> directory. You can then test with</p> +<pre><code class="bash">lein test +</code></pre> +<h2><a href="#license" name="license"></a>License</h2> +<p>Copyright © Simon Brooke, 2022.</p> +<p>This program and the accompanying materials are made available under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.</p></div></div></div></body></html> \ No newline at end of file diff --git a/docs/codox/js/highlight.min.js b/docs/codox/js/highlight.min.js new file mode 100644 index 0000000..6486ffd --- /dev/null +++ b/docs/codox/js/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.6.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||R(i))return i}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset<r[0].offset?e:r:"start"===r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}l+="<"+t(e)+w.map.call(e.attributes,r).join("")+">"}function u(e){l+="</"+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):E(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":y.classPrefix,i='<span class="'+a,o=t?"":C;return i+=e+'">',i+n+o}function p(){var e,t,r,a;if(!E.k)return n(B);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)a+=n(B.substr(t,r.index-t)),e=g(E,r),e?(M+=e[1],a+=h(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return a+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?B+=n:(a.rE||a.eE||(B+=n),b(),a.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"<unnamed>")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=i||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substr(O,I.index-O),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},a=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"<br>":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n,t,r,o,s,p=i(e);a(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="</span>",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}}); \ No newline at end of file diff --git a/docs/codox/js/jquery.min.js b/docs/codox/js/jquery.min.js new file mode 100644 index 0000000..73f33fb --- /dev/null +++ b/docs/codox/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b) +},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n}); diff --git a/docs/codox/js/page_effects.js b/docs/codox/js/page_effects.js new file mode 100644 index 0000000..fdacbf8 --- /dev/null +++ b/docs/codox/js/page_effects.js @@ -0,0 +1,112 @@ +function visibleInParent(element) { + var position = $(element).position().top + return position > -50 && position < ($(element).offsetParent().height() - 50) +} + +function hasFragment(link, fragment) { + return $(link).attr("href").indexOf("#" + fragment) != -1 +} + +function findLinkByFragment(elements, fragment) { + return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first() +} + +function scrollToCurrentVarLink(elements) { + var elements = $(elements); + var parent = elements.offsetParent(); + + if (elements.length == 0) return; + + var top = elements.first().position().top; + var bottom = elements.last().position().top + elements.last().height(); + + if (top >= 0 && bottom <= parent.height()) return; + + if (top < 0) { + parent.scrollTop(parent.scrollTop() + top); + } + else if (bottom > parent.height()) { + parent.scrollTop(parent.scrollTop() + bottom - parent.height()); + } +} + +function setCurrentVarLink() { + $('.secondary a').parent().removeClass('current') + $('.anchor'). + filter(function(index) { return visibleInParent(this) }). + each(function(index, element) { + findLinkByFragment(".secondary a", element.id). + parent(). + addClass('current') + }); + scrollToCurrentVarLink('.secondary .current'); +} + +var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }()) + +function scrollPositionId(element) { + var directory = window.location.href.replace(/[^\/]+\.html$/, '') + return 'scroll::' + $(element).attr('id') + '::' + directory +} + +function storeScrollPosition(element) { + if (!hasStorage) return; + localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft()) + localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop()) +} + +function recallScrollPosition(element) { + if (!hasStorage) return; + $(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x")) + $(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y")) +} + +function persistScrollPosition(element) { + recallScrollPosition(element) + $(element).scroll(function() { storeScrollPosition(element) }) +} + +function sidebarContentWidth(element) { + var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() }) + return Math.max.apply(Math, widths) +} + +function calculateSize(width, snap, margin, minimum) { + if (width == 0) { + return 0 + } + else { + return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2)) + } +} + +function resizeSidebars() { + var primaryWidth = sidebarContentWidth('.primary') + var secondaryWidth = 0 + + if ($('.secondary').length != 0) { + secondaryWidth = sidebarContentWidth('.secondary') + } + + // snap to grid + primaryWidth = calculateSize(primaryWidth, 32, 13, 160) + secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160) + + $('.primary').css('width', primaryWidth) + $('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1) + + if (secondaryWidth > 0) { + $('#content').css('left', primaryWidth + secondaryWidth + 2) + } + else { + $('#content').css('left', primaryWidth + 1) + } +} + +$(window).ready(resizeSidebars) +$(window).ready(setCurrentVarLink) +$(window).ready(function() { persistScrollPosition('.primary')}) +$(window).ready(function() { + $('#content').scroll(setCurrentVarLink) + $(window).resize(setCurrentVarLink) +}) diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..31b7968 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,14 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>The Old Dog and Duck: Documentation</title> + <link rel="stylesheet" type="text/css" href="codox/css/default.css" /> + </head> + <body> + <h1>The Old Dog and Duck: Documentation</h1> + <ul> + <li><a href="codox/index.html">Primary documentaion</a></li> + <li><a href="cloverage/index.html">Test coverage</a></li> + </ul> + </body> +</html> diff --git a/project.clj b/project.clj index 14dbd64..4d7fa1f 100644 --- a/project.clj +++ b/project.clj @@ -1,9 +1,14 @@ (defproject dog-and-duck "0.1.0-SNAPSHOT" - :description "FIXME: write description" - :url "http://example.com/FIXME" - :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" - :url "https://www.eclipse.org/legal/epl-2.0/"} - :dependencies [[org.clojure/clojure "1.10.3"] + :cloverage {:output "docs/cloverage" + :codecov? true + :emma-xml? true} + :codox {:metadata {:doc "**TODO**: write docs" + :doc/format :markdown} + :output-path "docs/codox" + :source-uri "https://github.com/simon-brooke/dog-and-duck/blob/master/{filepath}#L{line}"} + + :description "A Clojure library designed to implement the ActivityPub protocol." + :dependencies [[org.clojure/clojure "1.11.1"] [org.clojure/data.json "2.4.0"] [org.clojure/math.numeric-tower "0.0.5"] [org.clojure/spec.alpha "0.3.218"] @@ -12,4 +17,9 @@ [clj-http "3.12.3"] ;; required by clj-activitypub [cheshire "5.11.0"] ;; if this is not present, clj-http/client errors with 'json-enabled?' ] - :repl-options {:init-ns dog-and-duck.scratch.core}) + :license {:name "GPL-2.0-or-later" + :url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"} + :plugins [[lein-cloverage "1.2.2"] + [lein-codox "0.10.7"]] + :repl-options {:init-ns dog-and-duck.scratch.core} + :url "http://example.com/FIXME") diff --git a/resources/public/images/Dog_and_Duck_tavern.jpg b/resources/public/images/Dog_and_Duck_tavern.jpg new file mode 100644 index 0000000..cf15ce7 Binary files /dev/null and b/resources/public/images/Dog_and_Duck_tavern.jpg differ diff --git a/src/clj_activitypub/internal/crypto.clj b/src/clj_activitypub/internal/crypto.clj index 4dfdd22..0de519d 100644 --- a/src/clj_activitypub/internal/crypto.clj +++ b/src/clj_activitypub/internal/crypto.clj @@ -1,4 +1,7 @@ (ns clj-activitypub.internal.crypto + "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub). + If and when Jahfer issues a release of that library, this directory will be deleted and a + dependency on that library will be added to the project." (:require [clojure.java.io :as io]) (:import (java.util Base64) (java.security MessageDigest SecureRandom Signature))) @@ -27,10 +30,10 @@ (let [digest (.digest (MessageDigest/getInstance "SHA-256") (.getBytes data))] (base64-encode digest))) -(defn sign [data private-key] +(defn sign [data private-key] (let [bytes (.getBytes data) signer (doto (Signature/getInstance "SHA256withRSA") - (.initSign private-key (SecureRandom.)) - (.update bytes))] + (.initSign private-key (SecureRandom.)) + (.update bytes))] (.sign signer))) diff --git a/src/clj_activitypub/internal/http_util.clj b/src/clj_activitypub/internal/http_util.clj index d6733ad..5832884 100644 --- a/src/clj_activitypub/internal/http_util.clj +++ b/src/clj_activitypub/internal/http_util.clj @@ -1,4 +1,7 @@ (ns clj-activitypub.internal.http-util + "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub). + If and when Jahfer issues a release of that library, this directory will be deleted and a + dependency on that library will be added to the project." (:require [clj-activitypub.internal.crypto :as crypto]) (:import (java.net URLEncoder) (java.time OffsetDateTime ZoneOffset) diff --git a/src/clj_activitypub/internal/thread_cache.clj b/src/clj_activitypub/internal/thread_cache.clj index 3f23c1c..3f79264 100644 --- a/src/clj_activitypub/internal/thread_cache.clj +++ b/src/clj_activitypub/internal/thread_cache.clj @@ -1,6 +1,9 @@ -(ns clj-activitypub.internal.thread-cache) +(ns clj-activitypub.internal.thread-cache + "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub). + If and when Jahfer issues a release of that library, this directory will be deleted and a + dependency on that library will be added to the project.") -(defn- current-time +(defn- current-time "Returns current time using UNIX epoch." [] (System/currentTimeMillis)) @@ -10,7 +13,7 @@ (commute store assoc k (merge v {:read-at (current-time)})))) -(defn make +(defn make "Creates a thread-local cache." ([] (make false)) ([cache-if-nil] @@ -18,27 +21,27 @@ (letfn [(cache-kv ([k v] (dosync (commute store assoc k - {:write-at (current-time) - :read-at (current-time) + {:write-at (current-time) + :read-at (current-time) :value v}) v))) (get-v ([k] (when-let [data (get @store k)] (update-read-at store k data) (:value data))) - ([k compute-fn] - (let [storage @store] - (if (contains? storage k) - (get-v k) - (let [v (compute-fn)] - (when (or (not (nil? v)) cache-if-nil) - (cache-kv k v) - (get-v k))))))) + ([k compute-fn] + (let [storage @store] + (if (contains? storage k) + (get-v k) + (let [v (compute-fn)] + (when (or (not (nil? v)) cache-if-nil) + (cache-kv k v) + (get-v k))))))) (lru ([] (mapv (fn [[k v]] [k (:value v)]) (sort-by #(-> % val :read-at) < @store))))] - {:cache-kv cache-kv + {:cache-kv cache-kv :get-v get-v :cache-if-nil cache-if-nil :lru lru})))) \ No newline at end of file