refactor data pdf export

refactor data pdf export

--- src/clj/salava/user/data.clj
+++ src/clj/salava/user/data.clj
@@ -16,6 +16,7 @@
     [net.cgrand.enlive-html :as enlive]
     [salava.core.i18n :refer [t translate-text]]
     [salava.user.schemas :refer [contact-fields]]
+    [salava.badge.pdf :refer [replace-nils process-markdown]]
     ))

 (defqueries "sql/badge/main.sql")
@@ -103,427 +104,327 @@
                     :chunk {:size 11
                             :style :bold}}
         pdf-settings  (if (empty? font-path) {:stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers false :align :right}} {:font font :stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers false :align :right}})
-        data-template (pdf/template
-                        (let [template (cons [:paragraph]
-                                             [[:heading.heading-name
-                                               (str (:first_name $user) " " (:last_name $user))]
-                                              [:spacer 2]
-                                              [:paragraph.generic
-                                               [:chunk.chunk (str (t :user/UserID ul)": ")] [:chunk (str (:id $user))]"\n"
-                                               [:chunk.chunk (str (t :user/Role ul) ": ")] [:chunk (if (= "user" (:role $user)) (t :social/User ul) (t :admin/Admin ul))]"\n"
-                                               (when-not (blank? (:first_name $user))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Firstname ul)": ")] [:chunk (capitalize (:first_name $user))]"\n"])
-                                               (when-not (blank? (:last_name $user))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Lastname ul)": ")][:chunk (capitalize (:last_name $user))]"\n"])
-                                               (when-not (blank? (:profile_picture $user))
+        user-info-template (pdf/template
+                             (let [template (cons [:paragraph]
+                                                  [[:heading.heading-name
+                                                    (str (capitalize (:first_name $user)) " " (capitalize (:last_name $user)))]
+                                                   [:spacer 2]
+                                                   [:paragraph.generic
+                                                    [:chunk.chunk (str (t :user/UserID ul)": ")] [:chunk (str (:id $user))]"\n"
+                                                    [:chunk.chunk (str (t :user/Role ul) ": ")] [:chunk (if (= "user" (:role $user)) (t :social/User ul) (t :admin/Admin ul))]"\n"
+                                                    [:chunk.chunk (str (t :user/Firstname ul)": ")] [:chunk (capitalize (:first_name $user))]"\n"
+                                                    [:chunk.chunk (str (t :user/Lastname ul)": ")][:chunk (capitalize (:last_name $user))]"\n"
+                                                    [:chunk.chunk (str (t :user/Profilepicture ul)": ")] [:chunk.link (str site-url "/" (:profile_picture $user))]"\n"
+                                                    [:chunk.chunk (str (t :user/Language ul)": ")][:chunk (str (upper-case (:language $user)) "  ")]
+                                                    [:chunk.chunk (str (t :user/Country ul)": ")][:chunk (str (:country $user))]"\n"
+                                                    [:chunk.chunk (str (t :user/Activated ul) ": ")][:chunk (str (if (true? (:activated $user)) (t :core/Yes ul) (t :core/No ul)) "  ")]
+                                                    [:chunk.chunk (str (t :user/Emailnotifications ul) ": ")][:chunk (str (if (true? (:email_notifications $user)) (t :core/Yes ul) (t :core/No ul)) "  ")]
+                                                    [:chunk.chunk (str (t :user/Profilevisibility ul) ": ")][:chunk (t (keyword (str "core/"(capitalize (:profile_visibility $user)))) ul)]"\n"
+                                                    [:paragraph
+                                                     [:chunk.chunk (str (t :user/Aboutme ul) ":")]"\n"
+                                                     [:paragraph (str (:about $user)) ]]]
+                                                   [:spacer 2]])]
+                               template))
+
+        email-template (pdf/template
+                         [:paragraph.generic
+                          (if (> (count $emails) 1) [:heading.heading-name (t :user/Emailaddresses ul)] [:heading.heading-name (t :user/Emailaddress ul)])
+                          [:spacer 0]
+                          (into [:paragraph]
+                                (for [e $emails
+                                      :let [primary-address (:primary_address e)]]
+                                  [:paragraph
+                                   [:chunk.chunk (str (t :user/Emailaddress ul)": ")] [:chunk  (:email e)]"\n"
+                                   [:chunk.chunk (str (t :social/Created ul) ": ")] [:chunk (if (number? (:ctime e)) (str (date-from-unix-time (long (* 1000 (:ctime e))) "date")"  ") (str (:ctime e) " "))]
+                                   [:chunk.chunk (str (t :user/verified ul)": ")] [:chunk (str (if (true? (:verified e)) (t :core/Yes ul) (t :core/No ul)) "  ")]
+                                   (when (= true primary-address)
+                                     [:phrase
+                                      [:chunk.chunk (str (t :user/Loginaddress ul)": ")] [:chunk (t :core/Yes ul)] "\n"]
+                                     )
+                                   [:chunk.chunk (str (t :user/BackpackID ul) ": ")][:chunk (str (:backpack_id e))]]))])
+
+        profile-template (pdf/template
+                           [:paragraph.generic
+                            (when (not-empty $profile)
+                              [:paragraph.generic
+                               [:heading.heading-name  (t :user/Myprofile ul)]
+                               [:spacer 0]
+                               (into [:paragraph ] (for [p (sort-by :order $profile)
+                                                         :let[ k (->> contact-fields
+                                                                      (filter #(= (:type %) (:field p)))
+                                                                      first
+                                                                      :key)]]
+                                                     [:phrase
+                                                      [:chunk.chunk (str (t k ul)": ")] [:chunk  (str (:value p) "  ")]]
+                                                     ))])])
+        badge-template (pdf/template
+                         [:paragraph.generic
+                          (when-not (empty? $user_badges)
+                            [:spacer 0]
+                            [:heading.heading-name (t :badge/Mybadges ul)]
+                            (into [:paragraph]
+                                  (for [b $user_badges
+                                        :let [more-badge-info (replace-nils (b/get-badge ctx (:id b) user-id))
+                                              content (:content more-badge-info)
+                                              congratulated? (:congratulated? more-badge-info)
+                                              message-count (so/get-badge-message-count ctx (:badge_id b) user-id)
+                                              messages (replace-nils (select-badge-messages {:badge_id (:badge_id b)} (util/get-db ctx)))
+                                              endorsements (replace-nils (select-badge-endorsements {:id (:badge_id b)} (util/get-db ctx)))
+
+                                              template #(cons [:paragraph][[:paragraph
+                                                                            [:chunk.chunk (str (t :badge/BadgeID ul) ": ")][:chunk (str (or (:badge_id b ) "-"))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Name ul) ": ") ][:chunk (or (:name %) "-")]"\n"
+                                                                            [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (:description %))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Imagefile ul) ": ")][:chunk.link (str site-url "/"(:image_file %))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Issuedby ul) ": ")] [:chunk (str (:issuer_content_name %)"  ")]
+                                                                            [:chunk.chunk (str (t :badge/Issuerurl ul) ": ")][:chunk.link (str (:issuer_content_url %))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Issuercontact ul) ": ")] [:chunk.link (str (:issuer_contact %))]"\n"
+                                                                            (when-not (= "-" (:creator_name %))
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (t :badge/Createdby ul) ": ")][:chunk (str (:creator_name %))]"\n"])
+                                                                            (when-not (= "-" (:creator_url %))
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (t :badge/Creatorurl ul) ": ")][:chunk.link (str (:creator_url %))]"\n"])
+                                                                            (when-not (= "-" (:creator_email %))
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (t :badge/Creatorcontact ul) ": ")][:chunk.link (str (:creator_email %))]"\n"])
+                                                                            [:chunk.chunk (str (t :badge/Criteriaurl ul) ": ") ][:chunk.link (str (:criteria_url %))]"\n"
+                                                                            [:paragraph
+                                                                             [:chunk.chunk (str (t :badge/Criteria ul) ": ")][:paragraph (strip-html-tags (:criteria_content %))]"\n"]
+                                                                            [:chunk.chunk (str (t :user/Status ul) ": ")][:chunk  (capitalize (str (t (keyword (str "social/"(:status b))) ul) "  "))]
+
+                                                                            [:chunk.chunk (str (t :badge/Verifiedbyobf ul) ": ")][:chunk (str (if (true? (:verified_by_obf b)) (t :core/Yes ul) (t :core/No ul)) "  ")]
+
+                                                                            [:chunk.chunk (str (t :badge/Issuedbyobf ul) ": ")][:chunk (str (if (true? (:issued_by_obf b)) (t :core/Yes ul) (t :core/No ul)))]"\n"
+                                                                            (when (not-empty (:tags b))
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags b))]"\n"])
+                                                                            [:chunk.chunk (str (t :badge/Issuedon ul) ": ")][:chunk (if (number? (:issued_on b))(str (date-from-unix-time (long (* 1000 (:issued_on b))) "date") "  ") (str (:issued_on b) " "))]
+                                                                            [:chunk.chunk (str (t :badge/Expireson ul) ": ")][:chunk (if (number? (:expires_on b)) (date-from-unix-time (long (* 1000 (:expires_on b))) "date") (:expires_on b))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Issuerverified ul) ": ")] (if (== 0 (:issuer_verified b) ) [:chunk (str (t :core/No ul) " ")] [:chunk (str (t :core/Yes ul) " ")])
+                                                                            [:chunk.chunk (str (t :badge/Revoked ul) ": ")] [:chunk (str (if (true? (:revoked b)) (t :core/Yes ul) (t :core/No ul)) "  ")]
+                                                                            [:chunk.chunk (str (t :badge/Badgevisibility ul) ": ")] [:chunk (t (keyword (str "core/" (capitalize (:visibility b)))) ul)]"\n"
+                                                                            [:chunk.chunk (str (t :badge/OBFurl ul) ": ")] [:chunk.link (:obf_url b)]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Assertionurl ul) ": ")] [:chunk.link (str (:assertion_url more-badge-info))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Assertionjson ul) ": ")][:chunk.link (str (:assertion_json more-badge-info))]"\n"
+                                                                            [:chunk.chunk (str (t :badge/Badgerating ul) ": ") ] [:chunk (str (:rating more-badge-info) "  ")]
+                                                                            [:chunk.chunk (str (t :badge/Evidenceurl ul) ": ")] [:chunk.link (str (:evidence_url more-badge-info) " ")]"\n"
+                                                                            (when (not-empty (:alignment %))
+                                                                              [:paragraph
+                                                                               [:chunk.chunk (str (t :badge/Alignments ul) ": " (count (:alignment %)))]"\n"
+                                                                               (into [:paragraph ]
+                                                                                (for [a (:alignment %)]
+                                                                                [:paragraph
+                                                                                [:chunk (:name a)]"\n"
+                                                                                [:chunk (:description a)]"\n"
+                                                                                [:chunk.link (:url a)]
+                                                                                [:spacer 0]]))])
+                                                                            [:chunk.chunk (str (t :badge/Viewed ul) ": ")] [:chunk (str (:view_count more-badge-info) " " (t :badge/times ul)" ")]", "
+                                                                            [:chunk.chunk (str (t :badge/Recipientcount ul) ": ")][:chunk (str (:recipient_count more-badge-info) " ")]", "
+                                                                            [:chunk.chunk (str (t :badge/Congratulated ul) "?: ")][:chunk (str (if (true? congratulated?) (t :core/Yes ul) (t :core/No ul))" ")]"\n"
+                                                                            (when-not (empty? (:congratulations more-badge-info))
+                                                                              [:paragraph
+                                                                               [:chunk.chunk (str (t :badge/Congratulations ul) ": ")]"\n"
+                                                                               [:paragraph
+                                                                                (into [:paragraph] (for [c (:congratulations more-badge-info)]
+                                                                                [:phrase
+                                                                                [:chunk (str (:first_name c) " " (:last_name c))] "\n"]))]])
+                                                                            (when (> (:endorsement_count %) 0) (blank? (str (:endorsement_count %)))
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (capitalize (t :badge/endorsements ul)) ": ")][:chunk (str (:endorsement_count %))]"\n"])
+                                                                            (when (not-empty endorsements)
+                                                                              (into [:paragraph {:indent 0}]
+                                                                                (for [e endorsements]
+                                                                                [:paragraph {:indent 0}
+                                                                                (:issuer_name e) "\n"
+                                                                                [:anchor {:target (:issuer_url e) :style{:family :times-roman :color [66 100 162]}} (:issuer_url e) ] "\n"
+                                                                                [:chunk (if (number? (:issued_on e)) (date-from-unix-time (long (* 1000 (:issued_on e)))) (:issued_on e))] "\n"
+                                                                                (process-markdown (:content e))])
+                                                                                ))
+                                                                            (when (> (:all-messages message-count) 0)
+                                                                              [:phrase
+                                                                               [:chunk.chunk (str (t :social/Messages ul) ": ")] [:chunk (str (:all-messages message-count))]"\n"])
+                                                                            (when (> (:all-messages message-count) 0)
+                                                                              (into [:paragraph]
+                                                                                (for [m messages]
+                                                                                [:paragraph
+                                                                                [:chunk(:message m)]"\n"
+                                                                                [:chunk (str (:first_name m) " " (:last_name m))]"\n"
+                                                                                [:chunk (if (number? (:ctime m)) (date-from-unix-time (long (* 1000 (:ctime m))) "date") (:ctime m))]
+                                                                                [:spacer 0]])))
+
+                                                                            [:chunk.chunk (str (t :social/Lastmodified ul) ": ")][:chunk (if (number? (:mtime b))(str (date-from-unix-time (long (* 1000 (:mtime b))) "date")"  ") (str (:mtime b) " "))]
+                                                                            [:chunk.chunk (str (t :badge/URL ul) ": ")] [:chunk.link {:style :italic} (str site-url "/badge/info/" (:id b))]
+                                                                            [:spacer 1]]])]
+                                        ]
+                                    (reduce into [:paragraph] (-> (mapv template content)
+                                                                  (conj [[:line {:dotted true}]]))))))])
+
+        pending-badges-template  (pdf/template
+                                   [:paragraph.generic
+                                    (when-not (empty? $pending_badges)
+                                      [:paragraph
+                                       [:heading.heading-name (t :badge/Pendingbadges ul)]
+                                       [:spacer 0]
+                                       (into [:paragraph]
+                                             (for [pb $pending_badges]
+                                               [:paragraph
+                                                [:chunk.chunk (str (t :badge/BadgeID ul) ": ")] [:chunk (str (:badge_id pb))]"\n"
+                                                [:chunk.chunk (str (t :badge/Name ul) ": ")] [:chunk (str (:name pb))]"\n"
+                                                [:chunk.chunk (str (t :page/Description ul) ": ")] [:chunk  (str (:description pb))]"\n"
+                                                [:chunk.chunk (str (t :badge/Imagefile ul) ": ")] [:chunk.link (str site-url "/" (:image_file pb)) ]"\n"
+                                                [:chunk.chunk (str (t :badge/Assertionurl ul) ": ")] [:chunk.link (:assertion_url pb) ]"\n"
+                                                (when (not-empty (:tags pb))
+                                                  [:phrase
+                                                   [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags pb))]"\n"])
+                                                [:chunk.chunk (str (t :badge/Badgevisibility ul) ": ")] [:chunk (t (keyword (str "core/" (capitalize (:visibility pb)))))]"\n"
+                                                [:chunk.chunk (str (t :badge/Issuedon ul) ": ")] [:chunk (if (number? (:issued_on pb)) (str (date-from-unix-time (long (* 1000 (:issued_on pb))) "date") ", ") (str (:issued_on pb) ", "))]
+                                                [:chunk.chunk (str (t :badge/Expireson ul) ": ")] [:chunk (if (number? (:expires_on pb)) (str (date-from-unix-time (long (* 1000 (:expires_on pb))) "date") ", ") (str (:expires_on pb) ", "))]
+                                                ]))])])
+        page-template (pdf/template
+                        [:paragraph.generic
+                         (when-not (empty? $user_pages)
+                           [:paragraph
+                            [:heading.heading-name (t :page/Mypages ul)]
+                            [:spacer 0]
+                            (into [:paragraph]
+                                  (for [p $user_pages
+                                        :let [ page-owner? (p/page-owner? ctx (:id p) user-id)
+                                               page-blocks (p/page-blocks ctx (:id p))]]
+                                    [:paragraph
+                                     [:chunk.chunk (str (t :page/PageID ul) ": ")][:chunk (str (:id p))]"\n"
+                                     [:chunk.chunk (str (t :badge/Name ul) ": ")][:chunk (str (:name p))]"\n"
+                                     [:chunk.chunk (str (t :page/Owner ul) "?: ")][:chunk (if (= true page-owner?) (t :core/Yes ul) (t :core/No ul))] "\n"
+                                     [:chunk.chunk (str (t :page/Pagepassword ul) ": ")][:chunk (str (:password p))]"\n"
+                                     [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (:description p))]"\n"
+                                     [:chunk.chunk (str (t :social/Created ul) ": ")][:chunk (str (if (number? (:ctime p)) (date-from-unix-time (long (* 1000 (:ctime p))) "date") (:ctime p)) "  ")]
+                                     [:chunk.chunk (str (t :social/Lastmodified ul) ": ")][:chunk (str (if (number? (:mtime p))(date-from-unix-time (long (* 1000 (:mtime p))) "date") (:mtime p)))]"\n"
+                                     (when (not-empty (:tags p))
+                                       [:phrase
+                                        [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags p))]"\n"])
+                                     [:chunk.chunk (str (t :page/Theme ul) ": ")][:chunk (str (:theme p) "  ")]
+                                     [:chunk.chunk (str (t :page/Border ul) ": ")][:chunk (str (:border p) "  ")]
+                                     [:chunk.chunk (str (t :page/Padding ul) ": ")][:chunk (str (:padding p))]"\n"
+                                     [:spacer 1]
+                                     (when (not-empty page-blocks)
+                                       (into [:paragraph
+                                              [:phrase.chunk (t :page/Pageblocks ul)]
+                                              [:spacer 0]
+                                              ] (for [pb page-blocks]
+                                                  [:paragraph
+                                                   (when (= "heading"  (:type pb))
+                                                     (case (:size pb)
+                                                       "h1" [:phrase.generic {:align :left }
+                                                             [:chunk.chunk (str (t :page/Heading ul)": ")] [:chunk (str (:content pb))]
+                                                             ]
+                                                       "h2" [:phrase.generic {:align :left}
+                                                             [:chunk.chunk (str (t :page/Subheading ul) ": ")] [:chunk (str (:content pb))]] ))
+                                                   (when (= "badge" (:type pb))
+                                                     [:phrase
+                                                      [:phrase.chunk (str (t :badge/Badge ul) ": ")]
+                                                      [:anchor {:target (str site-url "/badge/info/" (:badge_id pb))} [:chunk.link (str (:name pb))]]"\n"
+                                                      ]
+                                                     )
+                                                   (when (= "html" (:type pb))
+                                                     [:phrase
+                                                      [:spacer 0]
+                                                      [:phrase.chunk (str (t :page/Html ul) ": ")]
+                                                      [:spacer 0]
+                                                      (:content pb)])
+                                                   (when (= "file" (:type pb))
+                                                     [:paragraph
+                                                      [:spacer 0]
+                                                      [:phrase.chunk (str (t :file/Files ul) ": ")]"\n"
+                                                      (into [:paragraph]
+                                                            (for [file (:files pb)]
+                                                              [:phrase
+                                                               [:chunk.bold (str (t :badge/Name ul) ": ")] [:chunk (:name file)]"\n"
+                                                               [:chunk.bold (str (t :badge/URL ul) ": ")][:anchor {:target (str site-url "/"(:path file)) :style{:family :times-roman :color [66 100 162]}} (str site-url "/"(:path file))]]
+                                                              ))])
+                                                   (when (= "tag" (:type pb))
+                                                     [:paragraph
+                                                      [:phrase.chunk (str (t :page/Badgegroup ul) ": ")]
+                                                      [:spacer 0]
+                                                      (into [:phrase ] (for [b (:badges pb)]
+                                                                         [:phrase
+                                                                          [:anchor {:target (str site-url "/badge/info/" (:id b))} [:chunk.link (str (:name b))]]"\n"]))])]
+                                                  )))[:line {:dotted true}] [:spacer 0]]))])])
+        user-connections-template (pdf/template
+                                    [:paragraph.generic
+                                     (when (or (not-empty $user_followers) (not-empty $user_following))
+                                       [:paragraph
+                                        [:heading.heading-name (str (t :user/Socialconnections ul) ": ")]
+                                        [:spacer 0]
+                                        (when-not (empty? $user_followers)
+                                          (into [:paragraph
+                                                 [:phrase.chunk (str (t :social/Followersusers ul) ": ")] [:spacer 0]] (for [follower $user_followers
+                                                                                :let [follower-id (:owner_id follower)
+                                                                                fname (:first_name follower)
+                                                                                lname (:last_name follower)
+                                                                                status (:status follower)]]
+                                                                                [:paragraph
+                                                                                [:anchor {:target (str site-url "/" "user/profile/" follower-id)} [:chunk.link (str fname " " lname ",  ")]]
+                                                                                [:chunk.chunk (str (t :user/Status ul) ": ")] [:chunk (str (t (keyword (str "social/"status)) ul))]])))
+                                        (when-not (empty? $user_following)
+                                          (into [:paragraph
+                                                 [:phrase.chunk (str (t :social/Followedusers ul) ": ")][:spacer 0]] (for [f $user_following
+                                                                                :let [followee-id (:user_id f)
+                                                                                fname (:first_name f)
+                                                                                lname (:last_name f)
+                                                                                status (:status f)]]
+                                                                                [:paragraph
+                                                                                [:anchor {:target (str site-url "/" "user/profile/" followee-id)} [:chunk.link (str fname " " lname ", ")]]
+                                                                                [:chunk.chunk (str (t :user/Status ul) ": ")] [:chunk (str (t (keyword (str "social/"status)) ul))]])))
+                                        ])])
+
+        badge-connections-template (pdf/template
+                                     [:paragraph.generic
+                                      (when-not (empty? $connections)
+                                        [:paragraph
+                                         [:heading.heading-name (str (t :user/Badgeconnections ul) ": ")]
+                                         [:spacer 0]
+                                         (into [:paragraph]
+                                               (for [c $connections]
                                                  [:paragraph
-                                                  [:chunk.chunk (str (t :user/Profilepicture ul)": ")] [:chunk (str site-url "/" (:profile_picture $user))]"\n"]
-                                                 )
-                                               (when-not (blank? (:language $user))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Language ul)": ")][:chunk (str (upper-case (:language $user)) "  ")]])
-                                               (when-not (blank? (:country $user))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Country ul)": ")][:chunk (str (:country $user))]"\n"])
-                                               (when-not (blank? (str (:activated $user)))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Activated ul) ": ")][:chunk (str (if (true? (:activated $user)) (t :core/Yes ul) (t :core/No ul)) "  ")]])
-                                               (when-not (blank? (str (:email_notifications $user)))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Emailnotifications ul) ": ")][:chunk (str (if (true? (:email_notifications $user)) (t :core/Yes ul) (t :core/No ul)) "  ")]])
-                                               (when-not (blank? (:profile_visibility $user))
-                                                 [:phrase
-                                                  [:chunk.chunk (str (t :user/Profilevisibility ul) ": ")][:chunk (t (keyword (str "core/"(capitalize (:profile_visibility $user)))) ul)]"\n"])
-                                               (when-not (blank? (:about $user))
-                                                 [:paragraph
-                                                  [:chunk.chunk (str (t :user/Aboutme ul) ":")]"\n"
-                                                  [:paragraph (str (:about $user)) ]])]
-                                              [:spacer 2]
-                                              [:paragraph.generic
-                                               (if (> (count $emails) 1)
-                                                 [:heading.heading-name (t :user/Emailaddresses ul)]
-                                                 [:heading.heading-name (t :user/Emailaddress ul)]
-                                                 )
-                                               (into [:paragraph ]
-                                                     (for [e $emails
-                                                           :let [primary-address (:primary_address e)]]
-                                                       [:paragraph
-                                                        [:chunk.chunk (str (t :user/Emailaddress ul)": ")] [:chunk (or (:email e) "-")]"\n"
-                                                        (when-not (blank? (str (:ctime e)))
-                                                          [:phrase
-                                                           [:chunk.chunk (str (t :social/Created ul) ": ")] [:chunk (str (date-from-unix-time (long (* 1000 (:ctime e))) "date")"  ")]])
-                                                        (when-not (blank? (str (:verified e)))
-                                                          [:phrase
-                                                           [:chunk.chunk (str (t :user/verified ul)": ")] [:chunk (str (if (true? (:verified e)) (t :core/Yes ul) (t :core/No ul)) "  ")]])
-                                                        (when (= true primary-address)
-                                                          [:phrase
-                                                           [:chunk.chunk (str (t :user/Loginaddress ul)": ")] [:chunk (t :core/Yes ul)] "\n"]
-                                                          )
-                                                        (when-not (blank? (str (:backpack_id e)))
-                                                          [:phrase
-                                                           [:chunk.chunk (str (t :user/BackpackID ul) ": ")][:chunk (str (:backpack_id e))]]
-                                                          )
-
-                                                        ]))]
-
-                                              (when (not-empty $profile)
-                                                [:paragraph.generic
-                                                 [:heading.heading-name  (t :user/Myprofile ul)]
-                                                 (into [:paragraph ] (for [p (sort-by :order $profile)
-                                                                           :let[ k (->> contact-fields
-                                                                                (filter #(= (:type %) (:field p)))
-                                                                                first
-                                                                                :key)]]
-                                                                       [:phrase
-                                                                        [:chunk.chunk (str (t k ul)": ")] [:chunk  (str (:value p) "  ")]]
-                                                                       ))
-
-                                                 ])
-                                              (when-not (empty? $user_badges)
-                                                [:paragraph.generic
-                                                 [:spacer 0]
-                                                 [:heading.heading-name (t :badge/Mybadges ul)]
-                                                 (into [:paragraph ] (for [b $user_badges
-                                                                           :let [more-badge-info (b/get-badge ctx (:id b) user-id)
-                                                                                content (:content more-badge-info)
-                                                                                congratulated? (:congratulated? more-badge-info)
-                                                                                message-count (so/get-badge-message-count ctx (:badge_id b) user-id)
-                                                                                messages (select-badge-messages {:badge_id (:badge_id b)} (util/get-db ctx))
-                                                                                endorsements (select-badge-endorsements {:id (:badge_id b)} (util/get-db ctx))
-                                                                                template #(cons [:paragraph][[:paragraph
-                                                                                [:chunk.chunk (str (t :badge/BadgeID ul) ": ")][:chunk (str (or (:badge_id b ) "-"))]"\n"
-                                                                                [:chunk.chunk (str (t :badge/Name ul) ": ") ][:chunk (or (:name %) "-")]"\n"
-                                                                                (when-not (blank? (str (:description %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (:description %))]"\n"])
-                                                                                (when-not (blank? (str (:image_file %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Imagefile ul) ": ")][:chunk (str site-url "/"(:image_file %))]"\n"])
-                                                                                (when-not (blank? (str (:issuer_content_name %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuedby ul) ": ")] [:chunk (str (:issuer_content_name %)"  ")]])
-                                                                                (when-not (blank? (str (:issuer_content_url %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuerurl ul) ": ")][:chunk (str (:issuer_content_url %))]"\n"])
-                                                                                (when-not (blank? (str (:issuer_contact %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuercontact ul) ": ")] [:chunk (str (:issuer_contact %))]"\n"])
-                                                                                (when-not (blank? (str (:creator_name %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Createdby ul) ": ")][:chunk (str (:creator_name %))]"\n"])
-                                                                                (when-not (blank? (str (:creator_url %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Creatorurl ul) ": ")][:chunk (str (:creator_url %))]"\n"])
-                                                                                (when-not (blank? (str (:creator_email %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Creatorcontact ul) ": ")][:chunk (str (:creator_email %))]"\n"])
-                                                                                (when-not (blank? (str (:criteria_url %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Criteriaurl ul) ": ") ][:chunk.link (str (:criteria_url %))]"\n"])
-                                                                                (when-not (blank? (str (:criteria_content %)))
-                                                                                [:paragraph
-                                                                                [:chunk.chunk (str (t :badge/Criteria ul) ": ")][:paragraph (strip-html-tags (:criteria_content %))]"\n"])
-                                                                                (when-not (blank? (str (:status b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :user/Status ul) ": ")][:chunk  (capitalize (str (t (keyword (str "social/"(:status b))) ul) "  "))]])
-                                                                                (when-not (blank? (str (:verified_by_obf b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Verifiedbyobf ul) ": ")][:chunk (str (if (true? (:verified_by_obf b)) (t :core/Yes ul) (t :core/No ul)) "  ")]])
-                                                                                (when-not (blank? (str (:issued_by_obf b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuedbyobf ul) ": ")][:chunk (str (if (true? (:issued_by_obf b)) (t :core/Yes ul) (t :core/No ul)))]"\n"])
-                                                                                (when (not-empty (:tags b))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags b))]"\n"])
-                                                                                (when-not (blank? (str (:issued_on b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuedon ul) ": ")][:chunk (str (date-from-unix-time (long (* 1000 (:issued_on b))) "date") "  ")]])
-                                                                                (when-not (blank? (str (:expires_on b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Expireson ul) ": ")][:chunk (date-from-unix-time (long (* 1000 (:expires_on b))) "date")]"\n"])
-                                                                                (when-not (blank? (str (:expires_on b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Issuerverified ul) ": ")] (if (== 0 (:issuer_verified b) ) [:chunk (str (t :core/No ul) " ")] [:chunk (str (t :core/Yes ul) " ")])])
-                                                                                (when-not (blank? (str (:revoked b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Revoked ul) ": ")] [:chunk (str (if (true? (:revoked b)) (t :core/Yes ul) (t :core/No ul)) "  ")]])
-                                                                                (when-not (blank? (str (:visibility b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Badgevisibility ul) ": ")] [:chunk (t (keyword (str "core/" (capitalize (:visibility b)))) ul)]"\n"])
-
-                                                                                (when-not (blank? (str (:obf_url b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/OBFurl ul) ": ")] [:chunk (:obf_url b)]"\n"])
-                                                                                (when-not (blank? (str (:assertion_url more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Assertionurl ul) ": ")] [:chunk.link (str (:assertion_url more-badge-info))]"\n"])
-                                                                                (when-not (blank? (str (:assertion_json more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Assertionjson ul) ": ")][:chunk.link (str (:assertion_json more-badge-info))]"\n"])
-
-                                                                                (when-not (blank? (str (:rating more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Badgerating ul) ": ") ] [:chunk (str (:rating more-badge-info) "  ")]])
-                                                                                (when-not (blank? (str (:evidence_url more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Evidenceurl ul) ": ")] [:chunk (str (:evidence_url more-badge-info) " ")]]"\n"
-                                                                                )
-                                                                                (when (not-empty (:alignment %))
-                                                                                [:paragraph
-                                                                                [:chunk.chunk (str (t :badge/Alignments ul) ": " (count (:alignment %)))]"\n"
-                                                                                (into [:paragraph ]
-                                                                                (for [a (:alignment %)]
-                                                                                [:paragraph
-                                                                                [:chunk (or (:name a) "-")]"\n"
-                                                                                [:chunk (or (:description a) "-")]"\n"
-                                                                                [:chunk.link (or (:url a) "")]
-                                                                                [:spacer 0]]))
-                                                                                ])
-
-                                                                                (when-not (blank? (str (:view_count more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Viewed ul) ": ")] [:chunk (str (:view_count more-badge-info) " " (t :badge/times ul)" ")]", "])
-                                                                                (when-not (blank? (str (:recipient_count more-badge-info)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Recipientcount ul) ": ")][:chunk (str (:recipient_count more-badge-info) " ")]", "])
-                                                                                (when-not (blank? (str congratulated?))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :badge/Congratulated ul) "?: ")][:chunk (str (if (true? congratulated?) (t :core/Yes ul) (t :core/No ul))" ")]"\n"])
-                                                                                (when-not (empty? (:congratulations more-badge-info))
-                                                                                [:paragraph
-                                                                                [:chunk.chunk (str (t :badge/Congratulations ul) ": ")]"\n"
-                                                                                [:paragraph
-                                                                                (into [:paragraph] (for [c (:congratulations more-badge-info)]
-                                                                                [:phrase
-                                                                                [:chunk (str c)] "\n"]))]])
-                                                                                (when-not (blank? (str (:endorsement_count %)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (capitalize (t :badge/endorsements ul)) ": ")][:chunk (str (:endorsement_count %))]"\n"])
-                                                                                (when (not-empty endorsements)
-                                                                                (into [:paragraph {:indent 0}]
-                                                                                (for [e endorsements]
-                                                                                [:paragraph {:indent 0}
-                                                                                #_[:chunk.chunk "Endorser: " ] (or (:issuer_name e) "-") "\n"
-                                                                                #_[:chunk.chunk "Issuer url: "] [:anchor {:target (:issuer_url e) :style{:family :times-roman :color [66 100 162]}} (or (:issuer_url e) "-")] "\n"
-                                                                                (when-not (blank? (str (:issued_on e)))
-                                                                                [:phrase [:chunk (date-from-unix-time (long (* 1000 (:issued_on e))))] "\n"])
-                                                                                (when-not (blank? (str (:content e)))
-                                                                                (markdown->clj-pdf (:content e)))])
-                                                                                ))
-                                                                                (when-not (blank? (str (:all-messages message-count)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :social/Messages ul) ": ")] [:chunk (str (:all-messages message-count))]"\n"])
-                                                                                (when (> (:all-messages message-count) 0)
-                                                                                (into [:paragraph]
-                                                                                (for [m messages]
-                                                                                [:paragraph
-                                                                                [:chunk (or (:message m) "-")]"\n"
-                                                                                [:chunk (str (:first_name m) " " (:last_name m))]"\n"
-                                                                                (when-not (blank? (str (:ctime m)))
-                                                                                [:chunk (date-from-unix-time (long (* 1000 (:ctime m))) "date")])
-                                                                                [:spacer 0]])))
-                                                                                (when-not (blank? (str (:mtime b)))
-                                                                                [:phrase
-                                                                                [:chunk.chunk (str (t :social/Lastmodified ul) ": ")][:chunk (str (date-from-unix-time (long (* 1000 (:mtime b))) "date")"  ")]])
-                                                                                [:chunk.chunk (str (t :badge/URL ul) ": ")] [:chunk.link {:style :italic} (str site-url "/badge/info/" (:id b))]
-                                                                                [:spacer 1]]])]
-                                                                           ]
-                                                                       (reduce into [:paragraph] (-> (mapv template content)
-                                                                                (conj [[:line {:dotted true}]])))
-                                                                       ))])
-
-                                              (when (not-empty $pending_badges)
-                                                [:paragraph.generic
-                                                 [:heading.heading-name (t :badge/Pendingbadges ul)]
-                                                 (into [:paragraph] (for [pb $pending_badges]
-                                                                      [:paragraph
-                                                                       (when-not (blank? (str (:badge_id pb)))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/BadgeID ul) ": ")] [:chunk (str (:badge_id pb))]"\n"])
-                                                                       (when-not (blank? (str (:name pb)))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Name ul) ": ")] [:chunk (str (:name pb))]"\n"])
-                                                                       (when-not (blank? (str (:description pb)))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :page/Description ul) ": ")] [:chunk  (str (:description pb))]"\n"])
-                                                                       (when-not (blank? (:image_file pb))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Imagefile ul) ": ")] [:chunk.link (str site-url "/" (:image_file pb)) ]"\n"])
-                                                                       (when-not (blank? (:assertion_url pb))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Assertionurl ul) ": ")] [:chunk.link (:assertion_url pb) ]"\n"])
-                                                                       (when (not-empty (:tags pb))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags pb))]"\n"])
-                                                                       (when-not (blank? (:visibility pb))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Badgevisibility ul) ": ")] [:chunk (t (keyword (str "core/" (capitalize (:visibility pb)))))]"\n"])
-
-                                                                       (when-not (blank? (str (:issued_on pb)))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Issuedon ul) ": ")] [:chunk (str (date-from-unix-time (long (* 1000 (:issued_on pb))) "date") ", ")]])
-
-                                                                       (when-not (blank? (str (:expires_on pb)))
-                                                                         [:phrase
-                                                                          [:chunk.chunk (str (t :badge/Expireson ul) ": ")] [:chunk (str (date-from-unix-time (long (* 1000 (:expires_on pb))) "date") "")]])
-                                                                       [:spacer 0]]))])
-
-                                              (when (not-empty $user_pages)
-                                                [:paragraph.generic
-                                                 [:heading.heading-name (t :page/Mypages ul)]
-                                                 (into [:paragraph ] (for [p $user_pages
-                                                                           :let [ page-owner? (p/page-owner? ctx (:id p) user-id)
-                                                                                page-blocks (p/page-blocks ctx (:id p))]]
-                                                                       [:paragraph
-                                                                        (when-not (blank? (str (:id p)))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :page/PageID ul) ": ")][:chunk (str (:id p))]"\n"])
-                                                                        (when-not (blank? (str (:name p)))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :badge/Name ul) ": ")][:chunk (str (:name p))]"\n"])
-                                                                        (when-not (blank? (str page-owner?))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :page/Owner ul) "?: ")][:chunk (if (= true page-owner?) (t :core/Yes ul) (t :core/No ul))] "\n"])
-                                                                        (when-not (blank? (:password p))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :page/Pagepassword ul) ": ")][:chunk (str (:password p))]"\n"])
-                                                                        (when-not (blank? (str (:description p)))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (:description p))]"\n"])
-                                                                        (when-not (blank? (str (:ctime p)))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :social/Created ul) ": ")][:chunk (str (date-from-unix-time (long (* 1000 (:ctime p))) "date") "  ")]])
-                                                                        (when-not (blank? (str (:mtime p)))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :social/Lastmodified ul) ": ")][:chunk (str (date-from-unix-time (long (* 1000 (:mtime p))) "date"))]"\n"])
-                                                                        (when (not-empty (:tags p))
-                                                                          [:phrase
-                                                                           [:chunk.chunk (str (t :badge/Tags ul) ": ")] [:chunk (join ", " (:tags p))]"\n"])
-                                                                        [:chunk.chunk (str (t :page/Theme ul) ": ")][:chunk (str (or (:theme p) "-")"  ")]
-                                                                        [:chunk.chunk (str (t :page/Border ul) ": ")][:chunk (str (or (:border p) "-")"  ")]
-                                                                        [:chunk.chunk (str (t :page/Padding ul) ": ")][:chunk (str (or (:padding p) "-"))]"\n"
-                                                                        [:spacer 1]
-                                                                        (when (not-empty page-blocks)
-                                                                          (into [:paragraph
-                                                                                [:phrase.chunk (t :page/Pageblocks ul)]
-                                                                                [:spacer 0]
-                                                                                ] (for [pb page-blocks]
-                                                                                [:paragraph
-                                                                                (when (= "heading"  (:type pb))
-                                                                                (case (:size pb)
-                                                                                "h1" [:phrase.generic {:align :left }
-                                                                                #_[:spacer 0]
-                                                                                [:chunk.chunk (str (t :page/Heading ul)": ")] [:chunk (str (or (:content pb) "-"))]
-                                                                                ]
-                                                                                "h2" [:phrase.generic {:align :left}
-                                                                                #_[:spacer 0]
-                                                                                [:chunk.chunk (str (t :page/Subheading ul) ": ")] [:chunk (str (or (:content pb) "-"))]] ))
-                                                                                (when (= "badge" (:type pb))
-                                                                                [:phrase
-                                                                                [:phrase.chunk (str (t :badge/Badge ul) ": ")]
-                                                                                [:anchor {:target (str site-url "/badge/info/" (:badge_id pb))} [:chunk.link (str (or (:name pb) "-"))]]"\n"
-                                                                                ]
-                                                                                )
-                                                                                (when (= "html" (:type pb))
-                                                                                [:phrase
-                                                                                [:spacer 0]
-                                                                                [:phrase.chunk (str (t :page/Html ul) ": ")]
-                                                                                [:spacer 0]
-                                                                                (or (:content pb) "-")])
-                                                                                (when (= "file" (:type pb))
-                                                                                [:paragraph
-                                                                                [:spacer 0]
-                                                                                [:phrase.chunk (str (t :file/Files ul) ": ")]"\n"
-                                                                                (into [:paragraph]
-                                                                                (for [file (:files pb)]
-                                                                                [:phrase
-                                                                                [:chunk.bold (str (t :badge/Name ul) ": ")] [:chunk (or (:name file) "-")]"\n"
-                                                                                [:chunk.bold (str (t :badge/URL ul) ": ")][:anchor {:target (str site-url "/"(:path file)) :style{:family :times-roman :color [66 100 162]}} (str site-url "/"(:path file))]]
-                                                                                ))])
-                                                                                (when (= "tag" (:type pb))
-                                                                                [:paragraph
-                                                                                [:phrase.chunk (str (t :page/Badgegroup ul) ": ")]
-                                                                                [:spacer 0]
-                                                                                (into [:phrase ] (for [b (:badges pb)]
-                                                                                [:phrase
-                                                                                [:anchor {:target (str site-url "/badge/info/" (:id b))} [:chunk.link (str (or (:name b) "-"))]]"\n"]))
-                                                                                ]
-                                                                                )
-                                                                                ]
-                                                                                )))]))])
-
-                                              (when (or (not-empty $user_followers) (not-empty $user_following))
-                                                [:paragraph.generic
-                                                 [:heading.heading-name (str (t :user/Socialconnections ul) ": ")]
-                                                 [:spacer 0]
-                                                 (when-not (empty? $user_followers)
-                                                   (into [:paragraph
-                                                          [:phrase.chunk (str (t :social/Followersusers ul) ": ")] [:spacer 0]] (for [follower $user_followers
-                                                                                :let [follower-id (:owner_id follower)
-                                                                                fname (:first_name follower)
-                                                                                lname (:last_name follower)
-                                                                                status (:status follower)]]
-                                                                                [:paragraph
-                                                                                [:anchor {:target (str site-url "/" "user/profile/" follower-id)} [:chunk.link (str fname " " lname ",  ")]]
-                                                                                [:chunk.chunk (str (t :user/Status ul) ": ")] [:chunk (str (t (keyword (str "social/"status)) ul))]])))
-                                                 (when-not (empty? $user_following)
-                                                   (into [:paragraph
-                                                          [:phrase.chunk (str (t :social/Followedusers ul) ": ")][:spacer 0]] (for [f $user_following
-                                                                                :let [followee-id (:user_id f)
-                                                                                fname (:first_name f)
-                                                                                lname (:last_name f)
-                                                                                status (:status f)]]
-                                                                                [:paragraph
-                                                                                [:anchor {:target (str site-url "/" "user/profile/" followee-id)} [:chunk.link (str fname " " lname ", ")]]
-                                                                                [:chunk.chunk (str (t :user/Status ul) ": ")] [:chunk (str (t (keyword (str "social/"status)) ul))]])))
-                                                 ])
-
-                                              (when-not (empty? $connections)
-                                                [:paragraph.generic
-                                                 [:heading.heading-name (str (t :user/Badgeconnections ul) ": ")]
-                                                 [:spacer 0]
-                                                 (into [:paragraph]
-                                                       (for [c $connections]
-                                                         [:paragraph
-                                                          [:chunk.chunk (str (t :badge/BadgeID ul) ": ")] [:chunk (str (or (:id c) "-"))]"\n"
-                                                          [:chunk.chunk (str (t :badge/Name ul) ": ")][:chunk (str (or (:name c) "-"))]"\n"
-                                                          [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (or (:description c) "-"))]"\n"
-                                                          (when-not (blank? (str (:image_file c)))
-                                                            [:phrase
-                                                             [:chunk.chunk (str (t :badge/Imagefile ul) ": ")] [:chunk.link (str site-url "/" (:image_file c))]"\n"])
-                                                          ]))])
-
-                                              (when-not (empty? $events)
-                                                [:paragraph.generic
-                                                 [:heading.heading-name (t :user/Activityhistory ul)]
-                                                 ])
-
-                                              (when-not (empty? $events)
-                                                (into [:table.generic {:header [(t :social/Action ul) (t :social/Object ul) (t :social/Objecttype ul) (t :social/Created ul)]}]
-                                                      (for [e (reverse $events)]
-                                                        [[:cell (if-not (blank? (:verb e)) (t (keyword (str "social/"(:verb e))) ul) "-")]
-                                                         [:cell  [:phrase
-                                                                  [:chunk (or (get-in e [:info :object_name]) "-")]"\n"
-                                                                  (if (contains? (:info e) :message)
-                                                                    [:chunk {:style :italic}(or (get-in e [:info :message :message]) "-")])]]
-                                                         [:cell
-                                                          (when-not (blank? (str (:type e)))
-                                                            (cond
-                                                              (= "page" (:type e)) (t :social/Emailpage ul)
-                                                              (= "badge" (:type e)) (t :social/Emailbadge ul)
-                                                              (= "user" (:type e)) (lower-case (t :social/User ul))
-                                                              (= "admin" (:type e)) (lower-case (t :admin/Admin ul))
-                                                              :else "-"))]
-                                                         [:cell (when-not (blank? (str (:ctime e)))
-                                                                  (date-from-unix-time (long (* 1000 (:ctime e))) "date"))]
-                                                         ])))
-                                              ])]
-                          (into [] template)))]
-    (dump (:user_badges user-data))
+                                                  [:chunk.chunk (str (t :badge/BadgeID ul) ": ")] [:chunk (str (:id c))]"\n"
+                                                  [:chunk.chunk (str (t :badge/Name ul) ": ")][:chunk (str (:name c))]"\n"
+                                                  [:chunk.chunk (str (t :page/Description ul) ": ")][:chunk (str (:description c))]"\n"
+                                                  [:chunk.chunk (str (t :badge/Imagefile ul) ": ")] [:chunk.link (str site-url "/" (:image_file c))]"\n"
+                                                  ]))])])
+        events-template (pdf/template
+                          (let [template (cons [:paragraph]
+                                               [[:paragraph.generic
+                                                 (when-not (empty? $events)
+                                                   [:heading.heading-name (t :user/Activityhistory ul)])]
+                                                (when-not (empty? $events)
+                                                  (into [:table.generic {:header [(t :social/Action ul) (t :social/Object ul) (t :social/Objecttype ul) (t :social/Created ul)]}]
+                                                        (for [e (reverse $events)]
+                                                          [[:cell (if-not (= "-" (:verb e)) (t (keyword (str "social/"(:verb e))) ul) "-")]
+                                                           [:cell  [:phrase
+                                                                    [:chunk (get-in e [:info :object_name])]"\n"
+                                                                    (if (contains? (:info e) :message)
+                                                                      [:chunk {:style :italic} (get-in e [:info :message :message])])]]
+                                                           [:cell
+                                                            (when-not (blank? (str (:type e)))
+                                                              (cond
+                                                                (= "page" (:type e)) (t :social/Emailpage ul)
+                                                                (= "badge" (:type e)) (t :social/Emailbadge ul)
+                                                                (= "user" (:type e)) (lower-case (t :social/User ul))
+                                                                (= "admin" (:type e)) (lower-case (t :admin/Admin ul))
+                                                                :else "-"))]
+                                                           [:cell (if (number? (:ctime e))(date-from-unix-time (long (* 1000 (:ctime e))) "date") (:ctime e))]
+                                                           ])))])]
+                            template))]
     (fn [output-stream]
-      (pdf/pdf (into [pdf-settings] (data-template user-data)) output-stream)
+      (pdf/pdf (into [pdf-settings] (concat (user-info-template user-data)
+                                            (email-template user-data)
+                                            (profile-template user-data)
+                                            (badge-template user-data)
+                                            (pending-badges-template user-data)
+                                            (page-template user-data)
+                                            (user-connections-template user-data)
+                                            (badge-connections-template user-data)
+                                            (events-template user-data))) output-stream)
       )))


refactored raml loading and validation logic

--- src/clj_raml_tester/core.clj
+++ src/clj_raml_tester/core.clj
@@ -83,6 +83,25 @@
     .getValidationViolations
     .asList))

+(defn- throw-raml-violations
+  [raml-violations]
+  (throw
+    (IllegalArgumentException.
+      (str "The RAML file has validation errors: \n"
+           (str/join "\n" raml-violations)))))
+
+(defn- load-and-validate-raml
+  [server-options]
+  (let [raml-definition (Util/fetchRamlDefinition
+                          server-options)
+        raml-violations (validate-raml
+                          server-options
+                          raml-definition)]
+    (if (empty? raml-violations)
+      raml-definition
+      (throw-raml-violations
+        raml-violations))))
+
 (defn start-proxy
   "TODO document"
   [port target-url raml-url
@@ -109,14 +128,8 @@
                          0                ; min-delay
                          0                ; max-delay
                          ValidatorConfigurator/NONE)
-        raml-definition (Util/fetchRamlDefinition server-options)
-        raml-violations (validate-raml
-                          server-options
-                          raml-definition)]
-    (if-not (empty? raml-violations)
-      (throw (IllegalArgumentException.
-               (str "The RAML file has validation errors: \n"
-                    (str/join "\n" raml-violations)))))
+        raml-definition (load-and-validate-raml
+                          server-options)]
     (RamlTesterProxyRecord.
       (JettyRamlProxyServer.
         server-options


Clamp function for vec2

Clamp function for vec2

But I really need to tune up the macros to generate this

--- src/cljs/cloj/math/vec2.cljs
+++ src/cljs/cloj/math/vec2.cljs
@@ -15,6 +15,9 @@
 (defn applyv [{fx :x fy :y} {x :x y :y}]
   (vec2 (fx x) (fy y)))

+(defn clamp [ {xlo :x ylo :y} {xhi :x yhi :y}{x :x y :y} ]
+  (vec2 (min xhi (max xlo x))
+        (min yhi (max ylo y))))

 (def left  (vec2 -1  0))
 (def right (vec2  1  0))


clojure.string.reverse: Use a native/idiomatic JavaScript implementation. Refs #CLJS-8

--- src/cljs/clojure/string.cljs
+++ src/cljs/clojure/string.cljs
@@ -18,14 +18,7 @@
 (defn reverse
   "Returns s with its characters reversed."
   [s]
-  (if (= (.length s) 0)
-    ""
-    (let [sb (gstring/StringBuffer.)]
-      (loop [coll (seq-reverse (seq (.split s "")))]
-        (when coll
-          (.append sb (first coll))
-          (recur (next coll))))
-      (. sb (toString)))))
+  (.. s (split "") (reverse) (join "")))

 (defn replace
   "Replaces all instance of match with replacement in s.


download every 5 minutes and actually catch the errors

--- src/cljs/uberblick/core.cljs
+++ src/cljs/uberblick/core.cljs
@@ -1,6 +1,6 @@
 (ns uberblick.core
   (:require [accountant.core :as accountant]
-            [cljs.core.async :as async :refer [<! >! chan take!]]
+            [cljs.core.async :as async :refer [<! >! chan take! timeout]]
             [cljs-http.client :as http]
             [genome-cljs.core :as genome]
             [goog.events :as events]
@@ -14,7 +14,7 @@

             [cljs.tools.reader :refer [read-string]]
             [cljs.js :refer [empty-state eval js-eval]])
-  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
   (:import goog.History))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -40,10 +40,14 @@
   ;; WorkTeam: Your actual team

-(go
-  (as-> (<! (genome/<get-all-active-klickster-profiles)) $
-    (reset! people-atom $)
-    ))
+(defn set-people-to-all-active-klicksters [atm interval]
+  (go-loop []
+    (reset! atm (<! (genome/<get-all-active-klickster-profiles)))
+    (println "Downloaded" (count @atm) "Klicksters")
+    (<! (timeout interval))
+    (recur)))
+
+(set-people-to-all-active-klicksters people-atom (* 5 60 1000))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; filter macro test
@@ -108,9 +112,9 @@
                            (println "Error while filtering")
                            (prn e)))
         nil->Out (fn [by-floors]
-                 (into {}
-                       (for [[k v] by-floors]
-                         [(if (nil? k) "Out" k) v])))]
+                   (into {}
+                         (for [[k v] by-floors]
+                           [(if (nil? k) "Out" k) v])))]
     (some->> all-the-people
              (group-by :KeyscanStatus)
              (nil->Out)  ; mark the OUT ones for better processing!
@@ -164,13 +168,17 @@
   ]])

 (defn home-page []
-  [:div
-   (let [people (filter-people @people-atom)]
-     (cond
-       (nil? people) [:h2 "There has been an error while applying your filters!"]
-       (= 0 (count people)) [:h2 "No one that fits your filters is in!"]
-       :else (for [[floor people] people]
-               ^{:key floor} [Floor floor people])))])
+  (try
+    [:div
+     (let [people (filter-people @people-atom)]
+       (cond
+         (nil? people) [:h2 "There has been an error while applying your filters!"]
+         (= 0 (count people)) [:h2 "No one that fits your filters is in!"]
+         :else (for [[floor people] people]
+                 ^{:key floor} [Floor floor people])))]
+    (catch :default e
+      (prn e)
+      [:h2 "There has been an error while applying your filters!"])))

 (defn About
 "Take the readme, render it to HTML, and set it as the element!"
@@ -247,6 +255,8 @@
                   "(startsWith? :FirstName \"M\")"
                   "(= :LaborRoleID \"APPLDEVL\")"
                   "(substring? :Title \"Quality\")"
+                  "(= :KeyscanStatus \"In 4th Flr N\")"
+                  "(or (startsWith? :FirstName \"M\") (substring? :Title \"Edit\"))"
                   ]]
        [:hr]
        [:h3 "References"]


don't elide whitespace from logged data; otherwise, (println " ") yields no output

--- ccw.core/src/clj/ccw/repl/view_helpers.clj
+++ ccw.core/src/clj/ccw/repl/view_helpers.clj
@@ -53,8 +53,7 @@
 (defn log
   [^StyledText log ^String s type]
   (ui-sync
-    (let [s (.replaceAll s "\\s+\\Z" "")
-          charcnt (.getCharCount log)
+    (let [charcnt (.getCharCount log)
           [log-style line-background-color-name] (get log-styles type [default-log-style nil])
           linecnt (.getLineCount log)]
       (.append log s)


Give a useful error if there's no else clause

--- src/icfp2014/compiler.clj
+++ src/icfp2014/compiler.clj
@@ -139,7 +139,9 @@
             fn-name (:name (last fns))
             pred-codes (compile-form vars fns pred)
             then-codes (compile-form vars fns then)
-            else-codes (compile-form vars fns else)
+            else-codes (if else-codes
+                         (compile-form vars fns else)
+                         (throw (IllegalArgumentException. (format "No else clause specified for %s" form))))
             pred-label (gensym (str fn-name "-pred"))
             then-label (gensym (str fn-name "-then"))
             else-label (gensym (str fn-name "-else"))]


Remove flatten flatters

Remove flatten flatters

--- src/cyanite_fetcher/core.clj
+++ src/cyanite_fetcher/core.clj
@@ -296,8 +296,6 @@
           data (c-get-data chost paths tenant rollup period from to)
           reduce-fdata (flatter data (fn [data] (reduce into data)) "reduce")]
       (flatter data (fn [data] (r/reduce into [] data)) "r/reduce")
-      (flatter data (fn [data] (flatten data)) "flatten")
-      (flatter data (fn [data] (into [] (r/flatten data))) "r/flatten")
       (cleaner reduce-fdata (fn [data] (remove nil? data))  "remove")
       (cleaner reduce-fdata (fn [data] (into [] (r/remove nil? data))) "r/remove")
       (r-flatter-cleaner data)))


Set default thumbnail format to webp.

Set default thumbnail format to webp.

--- src/uxbox/frontend/images.clj
+++ src/uxbox/frontend/images.clj
@@ -29,7 +29,7 @@
                           :dst :thumbnail
                           :size [300 110]
                           :quality 92
-                          :format "jpg"})
+                          :format "webp"})

 (def populate-thumbnails
   #(images/populate-thumbnails % +thumbnail-options+))


Add retrieve image service.

Add retrieve image service.

--- src/uxbox/services/images.clj
+++ src/uxbox/services/images.clj
@@ -100,6 +100,23 @@
   (with-open [conn (db/connection)]
     (delete-collection conn params)))

+;; --- Retrieve Image
+
+(defn retrieve-image
+  [conn {:keys [user id]}]
+  (let [sqlv (sql/get-image {:user user :id id})]
+    (->> (sc/fetch-one conn sqlv)
+         (data/normalize-attrs))))
+
+(s/def ::retrieve-image
+  (s/keys :req-un [::user ::us/id]))
+
+(defmethod core/query :retrieve-image
+  [params]
+  (s/assert ::retrieve-image params)
+  (with-open [conn (db/connection)]
+    (retrieve-image conn params)))
+
 ;; --- Create Image (Upload)

 (defn create-image


fix for issue #24 - any tests for problem nuances should be public


Order is important... don't re-introduce a bug you already fixed :)

--- desktop/src-common/ds3/main_screen.clj
+++ desktop/src-common/ds3/main_screen.clj
@@ -63,9 +63,9 @@
                  (step! screen)
                  (check-for-input screen)
                  (handle-all-entities screen)
-                 (check-game-status screen)
                  (enemy/handle-attack screen)
                  (flatten);This is here because when an enemy shoots for one frame it's not a map where :enemy? is true
+                 (check-game-status screen)
                  (sort-by :render-layer)
                  (render! screen))]
         ;(.render debug-renderer world (.combined camera))


Added shot frequency limit

Added shot frequency limit

--- desktop/src-common/ds3/main_screen.clj
+++ desktop/src-common/ds3/main_screen.clj
@@ -54,6 +54,19 @@
             (mark-for-removal entity2 entities)))
         ;:else entities
       )))
+
+  :on-timer
+  (fn [screen entities]
+    (case (:id screen)
+      :refresh-shot (update! screen :fire-when-ready true)
+      nil)
+    nil)
+
+  :on-key-up
+  (fn [screen entities]
+    (cond (= (:key screen) (key-code :x))
+          (update! screen :fire-when-ready true))
+    entities)
   )

@@ -66,12 +79,14 @@

 (defn check-for-input [screen entities]
    (cond
-     (key-pressed? :x) (let [ship (first (filter #(:ship? %) entities))
-                                 x (:x ship)
+     (and (get screen :fire-when-ready true)
+          (key-pressed? :x)) (let [ship (first (filter #(:ship? %) entities))
+                               x (:x ship)
                                  y (:y ship)]
                            ;(prn :x x :y y)
-                         (conj entities (bullet/create-bullet! screen x (+ 0.1 y)))
-                             )
+                         (update! screen :fire-when-ready false)
+                         (add-timer! screen :refresh-shot 0.2)
+                         (conj entities (bullet/create-bullet! screen x (+ 0.1 y))))
      :else entities
      ))

@@ -92,18 +107,15 @@
           0 0]
          float-array
          (chain-shape :create-chain)
-         (fixture-def :density 1 :restitution 1 :shape )
+         (fixture-def :is-sensor true :density 1 :restitution 1 :shape )
          (body! body :create-fixture))
 body))

 (defn mark-for-removal [entity entities]
   (do
-    (body! (:body entity) :set-linear-velocity 0 0)
     (remove #(= entity %) entities)
     ))

 (-> main-screen :entities deref)

-;(use 'ds3.core.desktop-launcher)
-
-;(-main)
+;(do (use 'ds3.core.desktop-launcher)(-main))


Cleaned up :attract-mode after game over

--- desktop/src-common/ds3/main_screen.clj
+++ desktop/src-common/ds3/main_screen.clj
@@ -33,7 +33,7 @@
                           :ticks 0
                           :p1-level-score 0
                           :high-score 0
-                          :p1-lives 3
+                          :p1-lives 0;3
                           :game-state :attract-mode
                           :formation-expand? false
                           :wave-respawning? false
@@ -42,12 +42,10 @@
                     (body-position! 0 (c/screen-to-world c/game-height) 0))
           bottom-oob (doto (create-oob-entity! screen (c/screen-to-world (+ c/game-width 20)) (c/screen-to-world 20))
                     (body-position! (c/screen-to-world (- 10)) (c/screen-to-world (- 20)) 0))
-          pixel-ship (ship/create-ship-entity! screen)
           space (sp/create-space)]
       [(assoc top-oob :id :top-oob :oob? true :render-layer 0)
        (assoc bottom-oob :id :bottom-oob :oob? true :render-layer 0)
-       space
-       pixel-ship]))
+       space]))

   :on-render
   (fn [screen entities]
@@ -98,9 +96,8 @@
                     (conj entities (enemy/create-enemies screen)))
       :post-game-over (do
                         (update! screen :p1-level-score 0
-                                 :p1-lives 3
                                  :game-state :attract-mode)
-                        (conj entities (ship/create-ship-entity! screen)))
+                        entities)
       ;default
       nil))

@@ -126,15 +123,15 @@
     ))

 (defn on-new-game [screen entities]
-  (do (update! screen
-               :ticks 0
-               :p1-level-score 0
-               :p1-lives 3
-               :game-state :in-game
-               :formation-expand? false
-               :wave-respawning? false)
-    (prn :on-new-game)
-    (remove #(:enemy? %) entities)))
+  (update! screen
+           :ticks 0
+           :p1-level-score 0
+           :p1-lives 3
+           :game-state :in-game
+           :formation-expand? false
+           :wave-respawning? false)
+  (prn :on-new-game)
+  (remove #(:enemy? %) (conj entities (ship/create-ship-entity! screen))))

 (defn handle-all-entities [screen entities]
   (->> entities


Actually, pipe standalone install through deps, not regular install.

--- src/leiningen/install.clj
+++ src/leiningen/install.clj
@@ -2,6 +2,7 @@
   "Install the project and its dependencies in your local repository."
   (:use [leiningen.core :only [home-dir default-repos read-project]]
         [leiningen.jar :only [jar manifest-map local-repo-path extract-jar]]
+        [leiningen.deps :only [deps copy-dependencies]]
         [leiningen.util.maven :only [container make-model make-remote-artifact
                                      make-remote-repo make-local-repo
                                      make-artifact add-metadata]]
@@ -50,11 +51,12 @@
      (let [[name group] ((juxt name namespace) (symbol project-name))
            _ (standalone-download name (or group name) version)
            temp-project (format "/tmp/lein-%s" (java.util.UUID/randomUUID))
-           jar-file (-> (local-repo-path name (or group name) version)
+           jarfile (-> (local-repo-path name (or group name) version)
                         (.replace "$HOME" (System/getenv "HOME")))]
-       (try (extract-jar (file jar-file) temp-project)
-            (binding [jar (constantly jar-file)
-                      *ns* (the-ns 'leiningen.core)]
-              (install (read-project (format "%s/project.clj" temp-project))))
+       (install-shell-wrapper (JarFile. jarfile))
+       (try (extract-jar (file jarfile) temp-project)
+            (binding [*ns* (the-ns 'leiningen.core)
+                      copy-dependencies (constantly nil)]
+              (deps (read-project (format "%s/project.clj" temp-project)) true))
             (finally
              (delete-file-recursively temp-project :silently))))))


avoids complete domain names for tokens created in tests (#1101)

--- waiter/integration/waiter/token_request_test.clj
+++ waiter/integration/waiter/token_request_test.clj
@@ -104,7 +104,7 @@

 (defn- create-token-name
   [waiter-url service-id-prefix]
-  (str service-id-prefix "." (subs waiter-url 0 (str/index-of waiter-url ":"))))
+  (str service-id-prefix "." (subs waiter-url 0 (str/index-of waiter-url "."))))

 (defn- list-tokens
   [waiter-url owner cookies query-params]
@@ -340,8 +340,8 @@
 (deftest ^:parallel ^:integration-fast ^:resource-heavy test-service-list-filtering
   (testing-using-waiter-url
     (let [service-name (rand-name)
-          token-1 (create-token-name waiter-url (str "www." service-name ".t1"))
-          token-2 (create-token-name waiter-url (str "www." service-name ".t2"))
+          token-1 (create-token-name waiter-url (str service-name ".t1"))
+          token-2 (create-token-name waiter-url (str service-name ".t2"))
           service-ids-atom (atom #{})
           token->version->etag-atom (atom {})
           all-tokens [token-1 token-2]
@@ -385,7 +385,7 @@

         (testing "star in token filter"
           (doseq [[_ router-url] (routers waiter-url)]
-            (let [query-params {"token" (str "www." service-name ".t*")}
+            (let [query-params {"token" (str service-name ".t*")}
                   _ (log/info query-params)
                   {:keys [body] :as response} (make-request router-url "/apps" :cookies cookies :query-params query-params)
                   services (json/read-str body)


Namespaces are not INamed

Namespaces are not INamed

--- src/main/cljs/cljs/core.cljs
+++ src/main/cljs/cljs/core.cljs
@@ -9856,11 +9856,7 @@
       false))
   IHash
   (-hash [_]
-    (hash name))
-  INamed
-  (-name [_] name)
-  (-namespace [_]
-    (throw (js/Error. "Cannot call -namespace on Namespace"))))
+    (hash name)))

 (defn find-ns-obj [ns]
   (letfn [(find-ns* [ctxt xs]