         (error-message
             (concat "weight " (number-to-string v) " is outside of range (0, 1]"))))
 
-(defun tn-set-target-weight (expr)
+
+;; API FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun exo-atom-info (atom-selector)
+    (lexical-let ((as atom-selector))
+        (lambda () (interactive)
+            (let ((atom (funcall as)))
+                (if atom
+                    (show-info atom)
+                    (no-target))))))
+
+(defun exo-choose-depth (expr)
+    (interactive)
+    (let ((depth (number-shorthand-to-number expr)))
+        (if (< depth 1) (error-message (concat "depth of " (number-to-string depth) " is too low (must be >= 1)"))
+            (if (> depth 5) (error-message (concat "depth of " (number-to-string depth) " is too high (must be <= 5)"))
+                (request-view nil exo-mode exo-root-id depth exo-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))))
+
+;; note: for some reason, the id doesn't stay invisible when you paste it, although it stays light gray
+(defun exo-copy-target-reference-to-clipboard ()
+    (interactive)
+    (let ((id (current-target-id)))
+        (if id
+            (copy-to-clipboard (concat "*" (create-id-infix id)))
+            (no-target))))
+
+(defun exo-copy-target-value-to-clipboard ()
+    (interactive)
+    (let ((value (current-target-value)))
+        (if value
+            (copy-to-clipboard value)
+            (no-target))))
+
+(defun exo-duplicates ()
+    (interactive)
+    (request-duplicates
+        exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight))
+
+;; evaluates a function call from emacsclient as if a user had typed it into the current buffer
+(defun exo-emacsclient-eval (f)
+    (set-buffer (window-buffer (selected-window)))
+    (funcall f))
+
+(defun exo-enter-edit-view ()
+    (interactive)
+    (if (and (in-view) (equal exo-mode exo-readonly-mode))
+        (request-view t exo-edit-mode exo-root-id exo-depth exo-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))
+
+(defun exo-enter-readonly-view ()
+    (interactive)
+    (if (and (in-view) (equal exo-mode exo-edit-mode))
+        (request-view t exo-readonly-mode exo-root-id exo-depth exo-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))
+
+(defun exo-events ()
+    (interactive)
+    (request-events 2))
+
+(defun exo-export ()
+    (interactive)
+    (message "exporting")
+    (do-export))
+
+(defun exo-find-roots ()
+    (interactive)
+        (request-find-roots-results
+            exo-style
+            exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight))
+
+(defun exo-goto-line (address)
+    (interactive)
+    (let ((line (address-to-lineno (handle-changewindow address))))
+        (if line
+            (goto-line line)
+            (error-message "invalid line address"))))
+
+(defun exo-history ()
+    (interactive)
+    (request-history
+        exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight))
+
+(defun exo-infer-types ()
+    (interactive)
+    (message "performing type inference")
+    (do-infer-types))
+
+(defun exo-insert-attr-priority (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (insert (concat "\n                @priority " (number-to-string (/ n 4.0)) "\n")))))
+
+(defun exo-insert-attr-sharability (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (insert (concat "\n                @sharability " (number-to-string (/ n 4.0)) "\n")))))
+
+(defun exo-insert-attr-weight (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (insert (concat "\n                @weight " (number-to-string (/ n 4.0)) "\n")))))
+
+(defun exo-insert-current-date ()
+  "insert the current date into the current buffer."
+       (interactive)
+       (insert (format-time-string exo-date-format (current-time))))
+
+(defun exo-insert-current-time ()
+  "insert the current time into the current buffer."
+       (interactive)
+       (insert (format-time-string exo-time-format (current-time))))
+
+(defun exo-insert-current-time-with-seconds ()
+  "insert the current time into the current buffer."
+       (interactive)
+       (insert (format-time-string exo-time-with-seconds-format (current-time))))
+
+(defun exo-preview-target-latex-math ()
+    (interactive)
+    (end-of-line)
+    (backward-word)
+    (latex-math-preview-expression))
+
+(defun exo-priorities ()
+    (interactive)
+    (request-priorities-results
+        exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight))
+
+(defun exo-push-view ()
+    (interactive)
+    (if (in-edit-view)
+    (let (
+        (entity (buffer-string)))
+        ;; The received view may very well differ from the pushed view in terms of line numbering,
+        ;; but we'll try to stay on the same line anyway.
+        (setq exo-current-line (line-number-at-pos))
+        (setq exo-future-sharability exo-default-sharability)
+        (http-post
+            (concat (base-url) "update")
+            (list
+                (list "request" (json-encode (list
+                    :root exo-root-id
+                    :depth (number-to-string exo-depth)
+                    :style exo-style
+                    :view entity
+                    :filter (filter-json exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))))
+            (receive-view exo-edit-mode)))))
+
+(defun exo-ripple-query (query)
+    (interactive)
+    (if (> (length query) 0)
+        (request-ripple-results
+            query
+            exo-style
+            exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight)))
+
+(defun exo-search (query)
+    (interactive)
+    (if (> (length query) 0)
+        (request-search-results
+            query
+            exo-style
+            exo-min-sharability exo-max-sharability exo-min-weight exo-max-weight)))
+
+(defun exo-set-default-sharability (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-default-sharability (/ n 4.0)))))
+
+(defun exo-set-default-weight (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-default-weight (/ n 4.0)))))
+
+(defun exo-set-min-sharability (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-min-sharability (/ n 4.0)))))
+
+(defun exo-set-min-weight (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-min-weight (/ n 4.0)))))
+
+(defun exo-set-target-priority (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-target-priority (/ n 4.0)))))
+
+(defun exo-set-target-sharability (expr)
+    (interactive)
+    (let ((n (number-shorthand-to-number expr)))
+        (if n (set-target-sharability (/ n 4.0)))))
+
+(defun exo-set-target-weight (expr)
     (interactive)
     (let ((n (number-shorthand-to-number expr)))
         (if n (set-target-weight (/ n 4.0)))))
 
-
-;; INTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun info-message (msg)
-    (message (concat "Info: " msg)))
-
-(defun error-message (msg)
-    (message (concat "Error: " msg)))
-
-(defun tn-visit-url-at-point ()
-    (interactive)
-    (goto-address-at-point))  ;; defined in Emacs goto-addr.el
-
-(defun browse-target-value (value-selector value-to-url)
-    (lexical-let ((vs value-selector) (vu value-to-url))
-        (lambda () (interactive)
-            (let ((value (funcall vs)))
-                (if value
-                    (browse-url (funcall vu value))
-                    (no-target))))))
-
-(defun tn-visit-as-url (value-selector)
-    (browse-target-value value-selector (lambda (value) value)))
-
-(defun tn-browse-target-alias ()
+(defun exo-set-value-truncation-length (length-str)
+    (interactive)
+    (let ((n (string-to-number length-str)))
+        (setq exo-value-truncation-length n)))
+
+(defun exo-toggle-emacspeak ()
+    (interactive)
+    (dtk-toggle-quiet))
+
+(defun exo-toggle-inference-viewstyle ()
+    (interactive)
+    (setq exo-viewstyle (if (equal exo-viewstyle exo-sharability-viewstyle)
+        exo-inference-viewstyle
+        exo-sharability-viewstyle))
+    (exo-update-view)
+    (message (concat "switched to " exo-viewstyle " view style")))
+
+(defun exo-toggle-truncate-lines ()
+    (interactive)
+    (toggle-truncate-lines))
+
+(defun exo-update-to-backward-view ()
+    (interactive)
+    (if (in-view)
+        (request-view nil exo-mode exo-root-id exo-depth exo-backward-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))
+
+(defun exo-update-to-forward-view ()
+    (interactive)
+    (if (in-view)
+        (request-view nil exo-mode exo-root-id exo-depth exo-forward-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))
+
+(defun exo-update-view ()
+    (interactive)
+    (if (in-view)
+        (request-view t exo-mode exo-root-id exo-depth exo-style exo-min-sharability exo-max-sharability exo-default-sharability exo-min-weight exo-max-weight exo-default-weight)))
+
+(defun exo-visit-in-amazon (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://www.amazon.com/s?ie=UTF8&index=blended&link_code=qs&field-keywords=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-delicious (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://www.delicious.com/search?p=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-ebay (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://www.ebay.com/sch/i.html?_nkw=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-google (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://www.google.com/search?ie=UTF-8&q=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-google-maps (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://maps.google.com/maps?q=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-google-scholar (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://scholar.google.com/scholar?q=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-twitter (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://twitter.com/#!/search/" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-wikipedia (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-in-youtube (value-selector)
+    (visit-target-value value-selector (lambda (value)
+        (concat "http://www.youtube.com/results?search_query=" (w3m-url-encode-string value)))))
+
+(defun exo-visit-target ()
+    (interactive)
+    (let ((key (current-target-id)))
+        (if key
+            (request-view nil (mode-for-visit) key exo-depth exo-style exo-min-sharability exo-max-sharability (future-sharability (current-target-sharability)) exo-min-weight exo-max-weight exo-default-weight)
+            (no-target))))
+
+(defun exo-visit-target-alias ()
     (interactive)
     (let ((alias (current-target-alias)))
         (if alias
             (browse-url alias)
             (no-target))))
 
-(defun tn-visit-in-amazon (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://www.amazon.com/s?ie=UTF8&index=blended&link_code=qs&field-keywords=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-ebay (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://www.ebay.com/sch/i.html?_nkw=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-delicious (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://www.delicious.com/search?p=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-google (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://www.google.com/search?ie=UTF-8&q=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-google-scholar (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://scholar.google.com/scholar?q=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-google-maps (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://maps.google.com/maps?q=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-twitter (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://twitter.com/#!/search/" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-wikipedia (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=" (w3m-url-encode-string value)))))
-
-(defun tn-visit-in-youtube (value-selector)
-    (browse-target-value value-selector (lambda (value)
-        (concat "http://www.youtube.com/results?search_query=" (w3m-url-encode-string value)))))
-
-(defvar tn-date-format "%Y-%m-%d")
-(defvar tn-time-format "%H:%M")
-(defvar tn-time-with-seconds-format "%H:%M:%S")
-
-(defun tn-insert-current-date ()
-  "insert the current date into the current buffer."
-       (interactive)
-       (insert (format-time-string tn-date-format (current-time))))
-(defun tn-insert-current-time ()
-  "insert the current time into the current buffer."
-       (interactive)
-       (insert (format-time-string tn-time-format (current-time))))
-(defun tn-insert-current-time-with-seconds ()
-  "insert the current time into the current buffer."
-       (interactive)
-       (insert (format-time-string tn-time-with-seconds-format (current-time))))
-
-(defun tn-insert-attr-priority (expr)
-    (interactive)
-    (let ((n (number-shorthand-to-number expr)))
-        (if n (insert (concat "\n                @priority " (number-to-string (/ n 4.0)) "\n")))))
-
-(defun tn-insert-attr-sharability (expr)
-    (interactive)
-    (let ((n (number-shorthand-to-number expr)))
-        (if n (insert (concat "\n                @sharability " (number-to-string (/ n 4.0)) "\n")))))
-
-(defun tn-insert-attr-weight (expr)
-    (interactive)
-    (let ((n (number-shorthand-to-number expr)))
-        (if n (insert (concat "\n                @weight " (number-to-string (/ n 4.0)) "\n")))))
-
-;; note: working in Aquamacs, apparently not in the terminal Emacs 24 on Mac OS X
-(defun copy-to-clipboard (g)
-    (let ((buffer (get-buffer-create "*temp*")))
-        (with-current-buffer buffer
-            (unwind-protect
-                 (insert g)
-                 (let ((beg 1) (end (+ (length g) 1)))
-                    (clipboard-kill-ring-save beg end))
-                (kill-buffer buffer)))))
-
-;; note: for some reason, the id doesn't stay invisible when you paste it, although it stays light gray
-(defun tn-copy-target-reference-to-clipboard ()
-    (interactive)
-    (let ((id (current-target-id)))
-        (if id
-            (copy-to-clipboard (concat "*" (create-id-infix id)))
-            (no-target))))
-
-(defun tn-copy-target-value-to-clipboard ()
-    (interactive)
-    (let ((value (current-target-value)))
-        (if value
-            (copy-to-clipboard value)
-            (no-target))))
-
-(defun tn-preview-target-latex-math ()
-    (interactive)
-    (end-of-line)
-    (backward-word)
-    (latex-math-preview-expression))
-
-(defun tn-toggle-truncate-lines ()
-    (interactive)
-    (toggle-truncate-lines))
+(defun exo-visit-as-url (value-selector)
+    (visit-target-value value-selector (lambda (value) value)))
+
+(defun exo-visit-url-at-point ()
+    (interactive)
+    (goto-address-at-point))  ;; defined in Emacs goto-addr.el
+
+
+;; KEYBOARD MAPPINGS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defun minibuffer-arg (function prompt)
     (lexical-let ((f function) (p prompt))

;; for visiting URLs in a browser
(require 'goto-addr)

;;(require 'ring)


;; for encryption of sensitive values
(require 'aes)

;; LOCAL IMPORTS ;;;;;;;;;;;;;;;;;;;;;;;
;; not required by this library ;;;;;;;;

(require 'latex-math-preview)


;; HELPER CODE ;;;;;;;;;;;;;;;;;;;;;;;;;

;; from Emacs-w3m
(defun w3m-url-encode-string (str &optional coding)

                (depth (numeric-value json 'depth nil))

                ;; if the service doesn't specify these values, they will carry over from the previous buffer state
                (min-sharability (numeric-value json 'minSharability exo-min-sharability))
                (max-sharability (numeric-value json 'maxSharability exo-max-sharability))
                (default-sharability (numeric-value json 'defaultSharability exo-default-sharability))
                (min-weight (numeric-value json 'minWeight exo-min-weight))
                (max-weight (numeric-value json 'maxWeight exo-max-weight))
                (default-weight (numeric-value json 'defaultWeight exo-default-weight))

                (style (cdr (assoc 'style json)))
                (title (cdr (assoc 'title json))))
                    (switch-to-buffer (view-name root json))
                    (make-local-variable 'exo-root-id)
                    (make-local-variable 'exo-depth)
                    (make-local-variable 'exo-style)
                    (make-local-variable 'exo-title)
                    (make-local-variable 'exo-min-sharability)
                    (make-local-variable 'exo-max-sharability)
                    (make-local-variable 'exo-default-sharability)
                    (make-local-variable 'exo-min-weight)
                    (make-local-variable 'exo-max-weight)
                    (make-local-variable 'exo-atoms)
                    (make-local-variable 'exo-current-line)
                    (make-local-variable 'exo-mode)
                    (make-local-variable 'exo-value-truncation-length)
                    (setq exo-root-id root)
                    (if (equal mode exo-search-mode)
                        ;; Always leave a search view with depth 1, rather than that of the last view.
                        ;; The user experience is a little unpredictable otherwise.
                        (setq exo-depth 1)
                        (if depth (setq exo-depth depth)))
                    (setq exo-min-sharability min-sharability)
                    (setq exo-max-sharability max-sharability)
                    (setq exo-default-sharability exo-future-sharability)
                    (setq exo-min-weight min-weight)
                    (setq exo-max-weight max-weight)
                    (setq exo-default-weight default-weight)
                    (setq exo-style (if style style exo-style))
                    (setq exo-title title)
                    (setq exo-atoms (make-hash-table :test 'equal))
                    (setq exo-mode mode)
                    (setq buffer-read-only nil)
                    (erase-buffer)
                    (write-view editable (cdr (assoc 'children view)) 0)
