summaryrefslogtreecommitdiff
path: root/assets/viz/2/clojure
diff options
context:
space:
mode:
authorBrian Picciano <mediocregopher@gmail.com>2018-11-12 16:18:45 -0500
committerBrian Picciano <mediocregopher@gmail.com>2018-11-12 16:18:45 -0500
commit5ed62d23b4bbbf7717de4adfa0eaf2af19365408 (patch)
treeaa3285b40f9905e45b33f61b77afa06a0d33a790 /assets/viz/2/clojure
parent886684ec4c0a3d032a974ae8b8e29fb0e0632125 (diff)
add viz 2 post
Diffstat (limited to 'assets/viz/2/clojure')
-rw-r--r--assets/viz/2/clojure/set.cljs161
-rw-r--r--assets/viz/2/clojure/set.cljs.cache.edn1
-rw-r--r--assets/viz/2/clojure/set.js400
-rw-r--r--assets/viz/2/clojure/set.js.map1
-rw-r--r--assets/viz/2/clojure/string.cljs258
-rw-r--r--assets/viz/2/clojure/string.cljs.cache.edn1
-rw-r--r--assets/viz/2/clojure/string.js505
-rw-r--r--assets/viz/2/clojure/string.js.map1
8 files changed, 1328 insertions, 0 deletions
diff --git a/assets/viz/2/clojure/set.cljs b/assets/viz/2/clojure/set.cljs
new file mode 100644
index 0000000..b9ba41f
--- /dev/null
+++ b/assets/viz/2/clojure/set.cljs
@@ -0,0 +1,161 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns ^{:doc "Set operations such as union/intersection."
+ :author "Rich Hickey"}
+ clojure.set)
+
+(defn- bubble-max-key [k coll]
+ "Move a maximal element of coll according to fn k (which returns a number)
+ to the front of coll."
+ (let [max (apply max-key k coll)]
+ (cons max (remove #(identical? max %) coll))))
+
+(defn union
+ "Return a set that is the union of the input sets"
+ ([] #{})
+ ([s1] s1)
+ ([s1 s2]
+ (if (< (count s1) (count s2))
+ (reduce conj s2 s1)
+ (reduce conj s1 s2)))
+ ([s1 s2 & sets]
+ (let [bubbled-sets (bubble-max-key count (conj sets s2 s1))]
+ (reduce into (first bubbled-sets) (rest bubbled-sets)))))
+
+(defn intersection
+ "Return a set that is the intersection of the input sets"
+ ([s1] s1)
+ ([s1 s2]
+ (if (< (count s2) (count s1))
+ (recur s2 s1)
+ (reduce (fn [result item]
+ (if (contains? s2 item)
+ result
+ (disj result item)))
+ s1 s1)))
+ ([s1 s2 & sets]
+ (let [bubbled-sets (bubble-max-key #(- (count %)) (conj sets s2 s1))]
+ (reduce intersection (first bubbled-sets) (rest bubbled-sets)))))
+
+(defn difference
+ "Return a set that is the first set without elements of the remaining sets"
+ ([s1] s1)
+ ([s1 s2]
+ (if (< (count s1) (count s2))
+ (reduce (fn [result item]
+ (if (contains? s2 item)
+ (disj result item)
+ result))
+ s1 s1)
+ (reduce disj s1 s2)))
+ ([s1 s2 & sets]
+ (reduce difference s1 (conj sets s2))))
+
+
+(defn select
+ "Returns a set of the elements for which pred is true"
+ [pred xset]
+ (reduce (fn [s k] (if (pred k) s (disj s k)))
+ xset xset))
+
+(defn project
+ "Returns a rel of the elements of xrel with only the keys in ks"
+ [xrel ks]
+ (set (map #(select-keys % ks) xrel)))
+
+(defn rename-keys
+ "Returns the map with the keys in kmap renamed to the vals in kmap"
+ [map kmap]
+ (reduce
+ (fn [m [old new]]
+ (if (contains? map old)
+ (assoc m new (get map old))
+ m))
+ (apply dissoc map (keys kmap)) kmap))
+
+(defn rename
+ "Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"
+ [xrel kmap]
+ (set (map #(rename-keys % kmap) xrel)))
+
+(defn index
+ "Returns a map of the distinct values of ks in the xrel mapped to a
+ set of the maps in xrel with the corresponding values of ks."
+ [xrel ks]
+ (reduce
+ (fn [m x]
+ (let [ik (select-keys x ks)]
+ (assoc m ik (conj (get m ik #{}) x))))
+ {} xrel))
+
+(defn map-invert
+ "Returns the map with the vals mapped to the keys."
+ [m] (reduce (fn [m [k v]] (assoc m v k)) {} m))
+
+(defn join
+ "When passed 2 rels, returns the rel corresponding to the natural
+ join. When passed an additional keymap, joins on the corresponding
+ keys."
+ ([xrel yrel] ;natural join
+ (if (and (seq xrel) (seq yrel))
+ (let [ks (intersection (set (keys (first xrel))) (set (keys (first yrel))))
+ [r s] (if (<= (count xrel) (count yrel))
+ [xrel yrel]
+ [yrel xrel])
+ idx (index r ks)]
+ (reduce (fn [ret x]
+ (let [found (idx (select-keys x ks))]
+ (if found
+ (reduce #(conj %1 (merge %2 x)) ret found)
+ ret)))
+ #{} s))
+ #{}))
+ ([xrel yrel km] ;arbitrary key mapping
+ (let [[r s k] (if (<= (count xrel) (count yrel))
+ [xrel yrel (map-invert km)]
+ [yrel xrel km])
+ idx (index r (vals k))]
+ (reduce (fn [ret x]
+ (let [found (idx (rename-keys (select-keys x (keys k)) k))]
+ (if found
+ (reduce #(conj %1 (merge %2 x)) ret found)
+ ret)))
+ #{} s))))
+
+(defn subset?
+ "Is set1 a subset of set2?"
+ [set1 set2]
+ (and (<= (count set1) (count set2))
+ (every? #(contains? set2 %) set1)))
+
+(defn superset?
+ "Is set1 a superset of set2?"
+ [set1 set2]
+ (and (>= (count set1) (count set2))
+ (every? #(contains? set1 %) set2)))
+
+(comment
+(refer 'set)
+(def xs #{{:a 11 :b 1 :c 1 :d 4}
+ {:a 2 :b 12 :c 2 :d 6}
+ {:a 3 :b 3 :c 3 :d 8 :f 42}})
+
+(def ys #{{:a 11 :b 11 :c 11 :e 5}
+ {:a 12 :b 11 :c 12 :e 3}
+ {:a 3 :b 3 :c 3 :e 7 }})
+
+(join xs ys)
+(join xs (rename ys {:b :yb :c :yc}) {:a :a})
+
+(union #{:a :b :c} #{:c :d :e })
+(difference #{:a :b :c} #{:c :d :e})
+(intersection #{:a :b :c} #{:c :d :e})
+
+(index ys [:b]))
+
diff --git a/assets/viz/2/clojure/set.cljs.cache.edn b/assets/viz/2/clojure/set.cljs.cache.edn
new file mode 100644
index 0000000..2341e7d
--- /dev/null
+++ b/assets/viz/2/clojure/set.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :externs {Error {}}, :use-macros {}, :excludes #{}, :name clojure.set, :imports nil, :requires nil, :uses nil, :defs {union {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 19, :column 7, :end-line 19, :end-column 12, :arglists (quote ([] [s1] [s1 s2] [s1 s2 & sets])), :doc "Return a set that is the union of the input sets", :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([] [s1] [s1 s2]), :arglists ([] [s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil nil)}}, :name clojure.set/union, :variadic true, :file "out/clojure/set.cljs", :end-column 12, :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([] [s1] [s1 s2]), :arglists ([] [s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil nil)}, :method-params ([] [s1] [s1 s2]), :protocol-impl nil, :arglists-meta (nil nil nil nil), :column 1, :line 19, :end-line 19, :max-fixed-arity 2, :fn-var true, :arglists ([] [s1] [s1 s2] [s1 s2 & sets]), :doc "Return a set that is the union of the input sets"}, map-invert {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 97, :column 7, :end-line 97, :end-column 17, :arglists (quote ([m])), :doc "Returns the map with the vals mapped to the keys."}, :name clojure.set/map-invert, :variadic false, :file "out/clojure/set.cljs", :end-column 17, :method-params ([m]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 97, :end-line 97, :max-fixed-arity 1, :fn-var true, :arglists (quote ([m])), :doc "Returns the map with the vals mapped to the keys."}, join {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 101, :column 7, :end-line 101, :end-column 11, :arglists (quote ([xrel yrel] [xrel yrel km])), :doc "When passed 2 rels, returns the rel corresponding to the natural\n join. When passed an additional keymap, joins on the corresponding\n keys.", :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([xrel yrel] [xrel yrel km]), :arglists ([xrel yrel] [xrel yrel km]), :arglists-meta (nil nil)}}, :name clojure.set/join, :variadic false, :file "out/clojure/set.cljs", :end-column 11, :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([xrel yrel] [xrel yrel km]), :arglists ([xrel yrel] [xrel yrel km]), :arglists-meta (nil nil)}, :method-params ([xrel yrel] [xrel yrel km]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 101, :end-line 101, :max-fixed-arity 3, :fn-var true, :arglists ([xrel yrel] [xrel yrel km]), :doc "When passed 2 rels, returns the rel corresponding to the natural\n join. When passed an additional keymap, joins on the corresponding\n keys."}, select {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 61, :column 7, :end-line 61, :end-column 13, :arglists (quote ([pred xset])), :doc "Returns a set of the elements for which pred is true"}, :name clojure.set/select, :variadic false, :file "out/clojure/set.cljs", :end-column 13, :method-params ([pred xset]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 61, :end-line 61, :max-fixed-arity 2, :fn-var true, :arglists (quote ([pred xset])), :doc "Returns a set of the elements for which pred is true"}, intersection {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 31, :column 7, :end-line 31, :end-column 19, :arglists (quote ([s1] [s1 s2] [s1 s2 & sets])), :doc "Return a set that is the intersection of the input sets", :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([s1] [s1 s2]), :arglists ([s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil)}}, :name clojure.set/intersection, :variadic true, :file "out/clojure/set.cljs", :end-column 19, :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([s1] [s1 s2]), :arglists ([s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil)}, :method-params ([s1] [s1 s2]), :protocol-impl nil, :arglists-meta (nil nil nil), :column 1, :line 31, :end-line 31, :max-fixed-arity 2, :fn-var true, :arglists ([s1] [s1 s2] [s1 s2 & sets]), :doc "Return a set that is the intersection of the input sets"}, superset? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 137, :column 7, :end-line 137, :end-column 16, :arglists (quote ([set1 set2])), :doc "Is set1 a superset of set2?"}, :name clojure.set/superset?, :variadic false, :file "out/clojure/set.cljs", :end-column 16, :method-params ([set1 set2]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 137, :end-line 137, :max-fixed-arity 2, :fn-var true, :arglists (quote ([set1 set2])), :doc "Is set1 a superset of set2?"}, index {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 87, :column 7, :end-line 87, :end-column 12, :arglists (quote ([xrel ks])), :doc "Returns a map of the distinct values of ks in the xrel mapped to a\n set of the maps in xrel with the corresponding values of ks."}, :name clojure.set/index, :variadic false, :file "out/clojure/set.cljs", :end-column 12, :method-params ([xrel ks]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 87, :end-line 87, :max-fixed-arity 2, :fn-var true, :arglists (quote ([xrel ks])), :doc "Returns a map of the distinct values of ks in the xrel mapped to a\n set of the maps in xrel with the corresponding values of ks."}, bubble-max-key {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 13, :column 8, :end-line 13, :end-column 22, :private true, :arglists (quote ([k coll]))}, :private true, :name clojure.set/bubble-max-key, :variadic false, :file "out/clojure/set.cljs", :end-column 22, :method-params ([k coll]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 13, :end-line 13, :max-fixed-arity 2, :fn-var true, :arglists (quote ([k coll]))}, subset? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 131, :column 7, :end-line 131, :end-column 14, :arglists (quote ([set1 set2])), :doc "Is set1 a subset of set2?"}, :name clojure.set/subset?, :variadic false, :file "out/clojure/set.cljs", :end-column 14, :method-params ([set1 set2]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 131, :end-line 131, :max-fixed-arity 2, :fn-var true, :arglists (quote ([set1 set2])), :doc "Is set1 a subset of set2?"}, rename {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 82, :column 7, :end-line 82, :end-column 13, :arglists (quote ([xrel kmap])), :doc "Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"}, :name clojure.set/rename, :variadic false, :file "out/clojure/set.cljs", :end-column 13, :method-params ([xrel kmap]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 82, :end-line 82, :max-fixed-arity 2, :fn-var true, :arglists (quote ([xrel kmap])), :doc "Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"}, rename-keys {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 72, :column 7, :end-line 72, :end-column 18, :arglists (quote ([map kmap])), :doc "Returns the map with the keys in kmap renamed to the vals in kmap"}, :name clojure.set/rename-keys, :variadic false, :file "out/clojure/set.cljs", :end-column 18, :method-params ([map kmap]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 72, :end-line 72, :max-fixed-arity 2, :fn-var true, :arglists (quote ([map kmap])), :doc "Returns the map with the keys in kmap renamed to the vals in kmap"}, project {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 67, :column 7, :end-line 67, :end-column 14, :arglists (quote ([xrel ks])), :doc "Returns a rel of the elements of xrel with only the keys in ks"}, :name clojure.set/project, :variadic false, :file "out/clojure/set.cljs", :end-column 14, :method-params ([xrel ks]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 67, :end-line 67, :max-fixed-arity 2, :fn-var true, :arglists (quote ([xrel ks])), :doc "Returns a rel of the elements of xrel with only the keys in ks"}, difference {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/set.cljs", :line 46, :column 7, :end-line 46, :end-column 17, :arglists (quote ([s1] [s1 s2] [s1 s2 & sets])), :doc "Return a set that is the first set without elements of the remaining sets", :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([s1] [s1 s2]), :arglists ([s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil)}}, :name clojure.set/difference, :variadic true, :file "out/clojure/set.cljs", :end-column 17, :top-fn {:variadic true, :max-fixed-arity 2, :method-params ([s1] [s1 s2]), :arglists ([s1] [s1 s2] [s1 s2 & sets]), :arglists-meta (nil nil nil)}, :method-params ([s1] [s1 s2]), :protocol-impl nil, :arglists-meta (nil nil nil), :column 1, :line 46, :end-line 46, :max-fixed-arity 2, :fn-var true, :arglists ([s1] [s1 s2] [s1 s2 & sets]), :doc "Return a set that is the first set without elements of the remaining sets"}}, :require-macros nil, :doc "Set operations such as union/intersection."} \ No newline at end of file
diff --git a/assets/viz/2/clojure/set.js b/assets/viz/2/clojure/set.js
new file mode 100644
index 0000000..4f9c5dc
--- /dev/null
+++ b/assets/viz/2/clojure/set.js
@@ -0,0 +1,400 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('clojure.set');
+goog.require('cljs.core');
+clojure.set.bubble_max_key = (function clojure$set$bubble_max_key(k,coll){
+
+var max = cljs.core.apply.call(null,cljs.core.max_key,k,coll);
+return cljs.core.cons.call(null,max,cljs.core.remove.call(null,((function (max){
+return (function (p1__9452_SHARP_){
+return (max === p1__9452_SHARP_);
+});})(max))
+,coll));
+});
+/**
+ * Return a set that is the union of the input sets
+ */
+clojure.set.union = (function clojure$set$union(var_args){
+var args9453 = [];
+var len__7927__auto___9459 = arguments.length;
+var i__7928__auto___9460 = (0);
+while(true){
+if((i__7928__auto___9460 < len__7927__auto___9459)){
+args9453.push((arguments[i__7928__auto___9460]));
+
+var G__9461 = (i__7928__auto___9460 + (1));
+i__7928__auto___9460 = G__9461;
+continue;
+} else {
+}
+break;
+}
+
+var G__9458 = args9453.length;
+switch (G__9458) {
+case 0:
+return clojure.set.union.cljs$core$IFn$_invoke$arity$0();
+
+break;
+case 1:
+return clojure.set.union.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
+
+break;
+case 2:
+return clojure.set.union.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+default:
+var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9453.slice((2)),(0),null));
+return clojure.set.union.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
+
+}
+});
+
+clojure.set.union.cljs$core$IFn$_invoke$arity$0 = (function (){
+return cljs.core.PersistentHashSet.EMPTY;
+});
+
+clojure.set.union.cljs$core$IFn$_invoke$arity$1 = (function (s1){
+return s1;
+});
+
+clojure.set.union.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
+if((cljs.core.count.call(null,s1) < cljs.core.count.call(null,s2))){
+return cljs.core.reduce.call(null,cljs.core.conj,s2,s1);
+} else {
+return cljs.core.reduce.call(null,cljs.core.conj,s1,s2);
+}
+});
+
+clojure.set.union.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
+var bubbled_sets = clojure.set.bubble_max_key.call(null,cljs.core.count,cljs.core.conj.call(null,sets,s2,s1));
+return cljs.core.reduce.call(null,cljs.core.into,cljs.core.first.call(null,bubbled_sets),cljs.core.rest.call(null,bubbled_sets));
+});
+
+clojure.set.union.cljs$lang$applyTo = (function (seq9454){
+var G__9455 = cljs.core.first.call(null,seq9454);
+var seq9454__$1 = cljs.core.next.call(null,seq9454);
+var G__9456 = cljs.core.first.call(null,seq9454__$1);
+var seq9454__$2 = cljs.core.next.call(null,seq9454__$1);
+return clojure.set.union.cljs$core$IFn$_invoke$arity$variadic(G__9455,G__9456,seq9454__$2);
+});
+
+clojure.set.union.cljs$lang$maxFixedArity = (2);
+
+/**
+ * Return a set that is the intersection of the input sets
+ */
+clojure.set.intersection = (function clojure$set$intersection(var_args){
+var args9464 = [];
+var len__7927__auto___9470 = arguments.length;
+var i__7928__auto___9471 = (0);
+while(true){
+if((i__7928__auto___9471 < len__7927__auto___9470)){
+args9464.push((arguments[i__7928__auto___9471]));
+
+var G__9472 = (i__7928__auto___9471 + (1));
+i__7928__auto___9471 = G__9472;
+continue;
+} else {
+}
+break;
+}
+
+var G__9469 = args9464.length;
+switch (G__9469) {
+case 1:
+return clojure.set.intersection.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
+
+break;
+case 2:
+return clojure.set.intersection.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+default:
+var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9464.slice((2)),(0),null));
+return clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
+
+}
+});
+
+clojure.set.intersection.cljs$core$IFn$_invoke$arity$1 = (function (s1){
+return s1;
+});
+
+clojure.set.intersection.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
+while(true){
+if((cljs.core.count.call(null,s2) < cljs.core.count.call(null,s1))){
+var G__9474 = s2;
+var G__9475 = s1;
+s1 = G__9474;
+s2 = G__9475;
+continue;
+} else {
+return cljs.core.reduce.call(null,((function (s1,s2){
+return (function (result,item){
+if(cljs.core.contains_QMARK_.call(null,s2,item)){
+return result;
+} else {
+return cljs.core.disj.call(null,result,item);
+}
+});})(s1,s2))
+,s1,s1);
+}
+break;
+}
+});
+
+clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
+var bubbled_sets = clojure.set.bubble_max_key.call(null,(function (p1__9463_SHARP_){
+return (- cljs.core.count.call(null,p1__9463_SHARP_));
+}),cljs.core.conj.call(null,sets,s2,s1));
+return cljs.core.reduce.call(null,clojure.set.intersection,cljs.core.first.call(null,bubbled_sets),cljs.core.rest.call(null,bubbled_sets));
+});
+
+clojure.set.intersection.cljs$lang$applyTo = (function (seq9465){
+var G__9466 = cljs.core.first.call(null,seq9465);
+var seq9465__$1 = cljs.core.next.call(null,seq9465);
+var G__9467 = cljs.core.first.call(null,seq9465__$1);
+var seq9465__$2 = cljs.core.next.call(null,seq9465__$1);
+return clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic(G__9466,G__9467,seq9465__$2);
+});
+
+clojure.set.intersection.cljs$lang$maxFixedArity = (2);
+
+/**
+ * Return a set that is the first set without elements of the remaining sets
+ */
+clojure.set.difference = (function clojure$set$difference(var_args){
+var args9476 = [];
+var len__7927__auto___9482 = arguments.length;
+var i__7928__auto___9483 = (0);
+while(true){
+if((i__7928__auto___9483 < len__7927__auto___9482)){
+args9476.push((arguments[i__7928__auto___9483]));
+
+var G__9484 = (i__7928__auto___9483 + (1));
+i__7928__auto___9483 = G__9484;
+continue;
+} else {
+}
+break;
+}
+
+var G__9481 = args9476.length;
+switch (G__9481) {
+case 1:
+return clojure.set.difference.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
+
+break;
+case 2:
+return clojure.set.difference.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+default:
+var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9476.slice((2)),(0),null));
+return clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
+
+}
+});
+
+clojure.set.difference.cljs$core$IFn$_invoke$arity$1 = (function (s1){
+return s1;
+});
+
+clojure.set.difference.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
+if((cljs.core.count.call(null,s1) < cljs.core.count.call(null,s2))){
+return cljs.core.reduce.call(null,(function (result,item){
+if(cljs.core.contains_QMARK_.call(null,s2,item)){
+return cljs.core.disj.call(null,result,item);
+} else {
+return result;
+}
+}),s1,s1);
+} else {
+return cljs.core.reduce.call(null,cljs.core.disj,s1,s2);
+}
+});
+
+clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
+return cljs.core.reduce.call(null,clojure.set.difference,s1,cljs.core.conj.call(null,sets,s2));
+});
+
+clojure.set.difference.cljs$lang$applyTo = (function (seq9477){
+var G__9478 = cljs.core.first.call(null,seq9477);
+var seq9477__$1 = cljs.core.next.call(null,seq9477);
+var G__9479 = cljs.core.first.call(null,seq9477__$1);
+var seq9477__$2 = cljs.core.next.call(null,seq9477__$1);
+return clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic(G__9478,G__9479,seq9477__$2);
+});
+
+clojure.set.difference.cljs$lang$maxFixedArity = (2);
+
+/**
+ * Returns a set of the elements for which pred is true
+ */
+clojure.set.select = (function clojure$set$select(pred,xset){
+return cljs.core.reduce.call(null,(function (s,k){
+if(cljs.core.truth_(pred.call(null,k))){
+return s;
+} else {
+return cljs.core.disj.call(null,s,k);
+}
+}),xset,xset);
+});
+/**
+ * Returns a rel of the elements of xrel with only the keys in ks
+ */
+clojure.set.project = (function clojure$set$project(xrel,ks){
+return cljs.core.set.call(null,cljs.core.map.call(null,(function (p1__9486_SHARP_){
+return cljs.core.select_keys.call(null,p1__9486_SHARP_,ks);
+}),xrel));
+});
+/**
+ * Returns the map with the keys in kmap renamed to the vals in kmap
+ */
+clojure.set.rename_keys = (function clojure$set$rename_keys(map,kmap){
+return cljs.core.reduce.call(null,(function (m,p__9491){
+var vec__9492 = p__9491;
+var old = cljs.core.nth.call(null,vec__9492,(0),null);
+var new$ = cljs.core.nth.call(null,vec__9492,(1),null);
+if(cljs.core.contains_QMARK_.call(null,map,old)){
+return cljs.core.assoc.call(null,m,new$,cljs.core.get.call(null,map,old));
+} else {
+return m;
+}
+}),cljs.core.apply.call(null,cljs.core.dissoc,map,cljs.core.keys.call(null,kmap)),kmap);
+});
+/**
+ * Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap
+ */
+clojure.set.rename = (function clojure$set$rename(xrel,kmap){
+return cljs.core.set.call(null,cljs.core.map.call(null,(function (p1__9495_SHARP_){
+return clojure.set.rename_keys.call(null,p1__9495_SHARP_,kmap);
+}),xrel));
+});
+/**
+ * Returns a map of the distinct values of ks in the xrel mapped to a
+ * set of the maps in xrel with the corresponding values of ks.
+ */
+clojure.set.index = (function clojure$set$index(xrel,ks){
+return cljs.core.reduce.call(null,(function (m,x){
+var ik = cljs.core.select_keys.call(null,x,ks);
+return cljs.core.assoc.call(null,m,ik,cljs.core.conj.call(null,cljs.core.get.call(null,m,ik,cljs.core.PersistentHashSet.EMPTY),x));
+}),cljs.core.PersistentArrayMap.EMPTY,xrel);
+});
+/**
+ * Returns the map with the vals mapped to the keys.
+ */
+clojure.set.map_invert = (function clojure$set$map_invert(m){
+return cljs.core.reduce.call(null,(function (m__$1,p__9500){
+var vec__9501 = p__9500;
+var k = cljs.core.nth.call(null,vec__9501,(0),null);
+var v = cljs.core.nth.call(null,vec__9501,(1),null);
+return cljs.core.assoc.call(null,m__$1,v,k);
+}),cljs.core.PersistentArrayMap.EMPTY,m);
+});
+/**
+ * When passed 2 rels, returns the rel corresponding to the natural
+ * join. When passed an additional keymap, joins on the corresponding
+ * keys.
+ */
+clojure.set.join = (function clojure$set$join(var_args){
+var args9508 = [];
+var len__7927__auto___9517 = arguments.length;
+var i__7928__auto___9518 = (0);
+while(true){
+if((i__7928__auto___9518 < len__7927__auto___9517)){
+args9508.push((arguments[i__7928__auto___9518]));
+
+var G__9519 = (i__7928__auto___9518 + (1));
+i__7928__auto___9518 = G__9519;
+continue;
+} else {
+}
+break;
+}
+
+var G__9510 = args9508.length;
+switch (G__9510) {
+case 2:
+return clojure.set.join.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+case 3:
+return clojure.set.join.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
+
+break;
+default:
+throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args9508.length)].join('')));
+
+}
+});
+
+clojure.set.join.cljs$core$IFn$_invoke$arity$2 = (function (xrel,yrel){
+if((cljs.core.seq.call(null,xrel)) && (cljs.core.seq.call(null,yrel))){
+var ks = clojure.set.intersection.call(null,cljs.core.set.call(null,cljs.core.keys.call(null,cljs.core.first.call(null,xrel))),cljs.core.set.call(null,cljs.core.keys.call(null,cljs.core.first.call(null,yrel))));
+var vec__9511 = (((cljs.core.count.call(null,xrel) <= cljs.core.count.call(null,yrel)))?new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [xrel,yrel], null):new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [yrel,xrel], null));
+var r = cljs.core.nth.call(null,vec__9511,(0),null);
+var s = cljs.core.nth.call(null,vec__9511,(1),null);
+var idx = clojure.set.index.call(null,r,ks);
+return cljs.core.reduce.call(null,((function (ks,vec__9511,r,s,idx){
+return (function (ret,x){
+var found = idx.call(null,cljs.core.select_keys.call(null,x,ks));
+if(cljs.core.truth_(found)){
+return cljs.core.reduce.call(null,((function (found,ks,vec__9511,r,s,idx){
+return (function (p1__9504_SHARP_,p2__9505_SHARP_){
+return cljs.core.conj.call(null,p1__9504_SHARP_,cljs.core.merge.call(null,p2__9505_SHARP_,x));
+});})(found,ks,vec__9511,r,s,idx))
+,ret,found);
+} else {
+return ret;
+}
+});})(ks,vec__9511,r,s,idx))
+,cljs.core.PersistentHashSet.EMPTY,s);
+} else {
+return cljs.core.PersistentHashSet.EMPTY;
+}
+});
+
+clojure.set.join.cljs$core$IFn$_invoke$arity$3 = (function (xrel,yrel,km){
+var vec__9514 = (((cljs.core.count.call(null,xrel) <= cljs.core.count.call(null,yrel)))?new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [xrel,yrel,clojure.set.map_invert.call(null,km)], null):new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [yrel,xrel,km], null));
+var r = cljs.core.nth.call(null,vec__9514,(0),null);
+var s = cljs.core.nth.call(null,vec__9514,(1),null);
+var k = cljs.core.nth.call(null,vec__9514,(2),null);
+var idx = clojure.set.index.call(null,r,cljs.core.vals.call(null,k));
+return cljs.core.reduce.call(null,((function (vec__9514,r,s,k,idx){
+return (function (ret,x){
+var found = idx.call(null,clojure.set.rename_keys.call(null,cljs.core.select_keys.call(null,x,cljs.core.keys.call(null,k)),k));
+if(cljs.core.truth_(found)){
+return cljs.core.reduce.call(null,((function (found,vec__9514,r,s,k,idx){
+return (function (p1__9506_SHARP_,p2__9507_SHARP_){
+return cljs.core.conj.call(null,p1__9506_SHARP_,cljs.core.merge.call(null,p2__9507_SHARP_,x));
+});})(found,vec__9514,r,s,k,idx))
+,ret,found);
+} else {
+return ret;
+}
+});})(vec__9514,r,s,k,idx))
+,cljs.core.PersistentHashSet.EMPTY,s);
+});
+
+clojure.set.join.cljs$lang$maxFixedArity = 3;
+
+/**
+ * Is set1 a subset of set2?
+ */
+clojure.set.subset_QMARK_ = (function clojure$set$subset_QMARK_(set1,set2){
+return ((cljs.core.count.call(null,set1) <= cljs.core.count.call(null,set2))) && (cljs.core.every_QMARK_.call(null,(function (p1__9521_SHARP_){
+return cljs.core.contains_QMARK_.call(null,set2,p1__9521_SHARP_);
+}),set1));
+});
+/**
+ * Is set1 a superset of set2?
+ */
+clojure.set.superset_QMARK_ = (function clojure$set$superset_QMARK_(set1,set2){
+return ((cljs.core.count.call(null,set1) >= cljs.core.count.call(null,set2))) && (cljs.core.every_QMARK_.call(null,(function (p1__9522_SHARP_){
+return cljs.core.contains_QMARK_.call(null,set1,p1__9522_SHARP_);
+}),set2));
+});
+
+//# sourceMappingURL=set.js.map \ No newline at end of file
diff --git a/assets/viz/2/clojure/set.js.map b/assets/viz/2/clojure/set.js.map
new file mode 100644
index 0000000..94818dd
--- /dev/null
+++ b/assets/viz/2/clojure/set.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/clojure\/set.js","sources":["set.cljs"],"lineCount":400,"mappings":"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","names":["clojure.set\/bubble-max-key","k","coll","max","cljs.core\/apply","cljs.core\/max-key","cljs.core\/cons","p1__9452#","cljs.core\/remove","var_args","args9453","len__7927__auto__","i__7928__auto__","G__9458","clojure.set\/union","argseq__7946__auto__","cljs.core\/IndexedSeq","seq9454","G__9455","cljs.core\/first","cljs.core\/next","G__9456","s1","s2","cljs.core\/count","cljs.core\/reduce","cljs.core\/conj","sets","bubbled-sets","cljs.core\/into","cljs.core\/rest","args9464","G__9469","clojure.set\/intersection","seq9465","G__9466","G__9467","result","item","cljs.core\/contains?","cljs.core\/disj","p1__9463#","args9476","G__9481","clojure.set\/difference","seq9477","G__9478","G__9479","clojure.set\/select","pred","xset","s","clojure.set\/project","xrel","ks","cljs.core\/set","p1__9486#","cljs.core\/map","cljs.core\/select-keys","clojure.set\/rename-keys","map","kmap","p__9491","vec__9492","cljs.core\/nth","m","old","new","cljs.core\/assoc","cljs.core\/get","cljs.core\/dissoc","cljs.core\/keys","clojure.set\/rename","p1__9495#","clojure.set\/index","x","ik","clojure.set\/map-invert","p__9500","vec__9501","v","args9508","G__9510","clojure.set\/join","js\/Error","yrel","cljs.core\/seq","vec__9511","r","idx","ret","found","p1__9504#","p2__9505#","cljs.core\/merge","km","vec__9514","cljs.core\/vals","p1__9506#","p2__9507#","clojure.set\/subset?","set1","set2","p1__9521#","cljs.core\/every?","clojure.set\/superset?","p1__9522#"]} \ No newline at end of file
diff --git a/assets/viz/2/clojure/string.cljs b/assets/viz/2/clojure/string.cljs
new file mode 100644
index 0000000..4cf5ede
--- /dev/null
+++ b/assets/viz/2/clojure/string.cljs
@@ -0,0 +1,258 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns clojure.string
+ (:refer-clojure :exclude [replace reverse])
+ (:require [goog.string :as gstring])
+ (:import [goog.string StringBuffer]))
+
+(defn- seq-reverse
+ [coll]
+ (reduce conj () coll))
+
+(def ^:private re-surrogate-pair
+ (js/RegExp. "([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])" "g"))
+
+(defn reverse
+ "Returns s with its characters reversed."
+ [s]
+ (-> (.replace s re-surrogate-pair "$2$1")
+ (.. (split "") (reverse) (join ""))))
+
+(defn- replace-all
+ [s re replacement]
+ (.replace s (js/RegExp. (.-source re) "g") replacement))
+
+(defn- replace-with
+ [f]
+ (fn [& args]
+ (let [matches (drop-last 2 args)]
+ (if (= (count matches) 1)
+ (f (first matches))
+ (f (vec matches))))))
+
+(defn replace
+ "Replaces all instance of match with replacement in s.
+ match/replacement can be:
+
+ string / string
+ pattern / (string or function of match)."
+ [s match replacement]
+ (cond
+ (string? match)
+ (.replace s (js/RegExp. (gstring/regExpEscape match) "g") replacement)
+
+ (instance? js/RegExp match)
+ (if (string? replacement)
+ (replace-all s match replacement)
+ (replace-all s match (replace-with replacement)))
+
+ :else (throw (str "Invalid match arg: " match))))
+
+(defn replace-first
+ "Replaces the first instance of match with replacement in s.
+ match/replacement can be:
+
+ string / string
+ pattern / (string or function of match)."
+ [s match replacement]
+ (.replace s match replacement))
+
+(defn join
+ "Returns a string of all elements in coll, as returned by (seq coll),
+ separated by an optional separator."
+ ([coll]
+ (loop [sb (StringBuffer.) coll (seq coll)]
+ (if-not (nil? coll)
+ (recur (. sb (append (str (first coll)))) (next coll))
+ (.toString sb))))
+ ([separator coll]
+ (loop [sb (StringBuffer.) coll (seq coll)]
+ (if-not (nil? coll)
+ (do
+ (. sb (append (str (first coll))))
+ (let [coll (next coll)]
+ (when-not (nil? coll)
+ (. sb (append separator)))
+ (recur sb coll)))
+ (.toString sb)))))
+
+(defn upper-case
+ "Converts string to all upper-case."
+ [s]
+ (.toUpperCase s))
+
+(defn lower-case
+ "Converts string to all lower-case."
+ [s]
+ (.toLowerCase s))
+
+(defn capitalize
+ "Converts first character of the string to upper-case, all other
+ characters to lower-case."
+ [s]
+ (if (< (count s) 2)
+ (upper-case s)
+ (str (upper-case (subs s 0 1))
+ (lower-case (subs s 1)))))
+
+;; The JavaScript split function takes a limit argument but the return
+;; value is not the same as the Java split function.
+;;
+;; Java: (.split "a-b-c" #"-" 2) => ["a" "b-c"]
+;; JavaScript: (.split "a-b-c" #"-" 2) => ["a" "b"]
+;;
+;; For consistency, the three arg version has been implemented to
+;; mimic Java's behavior.
+
+(defn- pop-last-while-empty
+ [v]
+ (loop [v v]
+ (if (identical? "" (peek v))
+ (recur (pop v))
+ v)))
+
+(defn- discard-trailing-if-needed
+ [limit v]
+ (if (and (== 0 limit) (< 1 (count v)))
+ (pop-last-while-empty v)
+ v))
+
+(defn- split-with-empty-regex
+ [s limit]
+ (if (or (<= limit 0) (>= limit (+ 2 (count s))))
+ (conj (vec (cons "" (map str (seq s)))) "")
+ (condp == limit
+ 1 (vector s)
+ 2 (vector "" s)
+ (let [c (- limit 2)]
+ (conj (vec (cons "" (subvec (vec (map str (seq s))) 0 c))) (subs s c))))))
+
+(defn split
+ "Splits string on a regular expression. Optional argument limit is
+ the maximum number of splits. Not lazy. Returns vector of the splits."
+ ([s re]
+ (split s re 0))
+ ([s re limit]
+ (discard-trailing-if-needed limit
+ (if (identical? "/(?:)/" (str re))
+ (split-with-empty-regex s limit)
+ (if (< limit 1)
+ (vec (.split (str s) re))
+ (loop [s s
+ limit limit
+ parts []]
+ (if (== 1 limit)
+ (conj parts s)
+ (let [m (re-find re s)]
+ (if-not (nil? m)
+ (let [index (.indexOf s m)]
+ (recur (.substring s (+ index (count m)))
+ (dec limit)
+ (conj parts (.substring s 0 index))))
+ (conj parts s))))))))))
+
+(defn split-lines
+ "Splits s on \n or \r\n."
+ [s]
+ (split s #"\n|\r\n"))
+
+(defn trim
+ "Removes whitespace from both ends of string."
+ [s]
+ (gstring/trim s))
+
+(defn triml
+ "Removes whitespace from the left side of string."
+ [s]
+ (gstring/trimLeft s))
+
+(defn trimr
+ "Removes whitespace from the right side of string."
+ [s]
+ (gstring/trimRight s))
+
+(defn trim-newline
+ "Removes all trailing newline \\n or return \\r characters from
+ string. Similar to Perl's chomp."
+ [s]
+ (loop [index (.-length s)]
+ (if (zero? index)
+ ""
+ (let [ch (get s (dec index))]
+ (if (or (identical? \newline ch)
+ (identical? \return ch))
+ (recur (dec index))
+ (.substring s 0 index))))))
+
+(defn ^boolean blank?
+ "True is s is nil, empty, or contains only whitespace."
+ [s]
+ (gstring/isEmptySafe s))
+
+(defn escape
+ "Return a new string, using cmap to escape each character ch
+ from s as follows:
+
+ If (cmap ch) is nil, append ch to the new string.
+ If (cmap ch) is non-nil, append (str (cmap ch)) instead."
+ [s cmap]
+ (let [buffer (StringBuffer.)
+ length (.-length s)]
+ (loop [index 0]
+ (if (== length index)
+ (. buffer (toString))
+ (let [ch (.charAt s index)
+ replacement (get cmap ch)]
+ (if-not (nil? replacement)
+ (.append buffer (str replacement))
+ (.append buffer ch))
+ (recur (inc index)))))))
+
+(defn index-of
+ "Return index of value (string or char) in s, optionally searching
+ forward from from-index or nil if not found."
+ ([s value]
+ (let [result (.indexOf s value)]
+ (if (neg? result)
+ nil
+ result)))
+ ([s value from-index]
+ (let [result (.indexOf s value from-index)]
+ (if (neg? result)
+ nil
+ result))))
+
+(defn last-index-of
+ "Return last index of value (string or char) in s, optionally
+ searching backward from from-index or nil if not found."
+ ([s value]
+ (let [result (.lastIndexOf s value)]
+ (if (neg? result)
+ nil
+ result)))
+ ([s value from-index]
+ (let [result (.lastIndexOf s value from-index)]
+ (if (neg? result)
+ nil
+ result))))
+
+(defn ^boolean starts-with?
+ "True if s starts with substr."
+ [s substr]
+ (gstring/startsWith s substr))
+
+(defn ^boolean ends-with?
+ "True if s ends with substr."
+ [s substr]
+ (gstring/endsWith s substr))
+
+(defn ^boolean includes?
+ "True if s includes substr."
+ [s substr]
+ (gstring/contains s substr))
diff --git a/assets/viz/2/clojure/string.cljs.cache.edn b/assets/viz/2/clojure/string.cljs.cache.edn
new file mode 100644
index 0000000..e4ac146
--- /dev/null
+++ b/assets/viz/2/clojure/string.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :externs {RegExp {}, Error {}}, :use-macros {}, :excludes #{reverse replace}, :name clojure.string, :imports {StringBuffer goog.string.StringBuffer}, :requires {gstring goog.string, goog.string goog.string, StringBuffer goog.string.StringBuffer}, :uses nil, :defs {ends-with? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 250, :column 16, :end-line 250, :end-column 26, :tag boolean, :arglists (quote ([s substr])), :doc "True if s ends with substr."}, :name clojure.string/ends-with?, :variadic false, :file "out/clojure/string.cljs", :end-column 26, :method-params ([s substr]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 250, :ret-tag boolean, :end-line 250, :max-fixed-arity 2, :tag boolean, :fn-var true, :arglists (quote ([s substr])), :doc "True if s ends with substr."}, seq-reverse {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 14, :column 8, :end-line 14, :end-column 19, :private true, :arglists (quote ([coll]))}, :private true, :name clojure.string/seq-reverse, :variadic false, :file "out/clojure/string.cljs", :end-column 19, :method-params ([coll]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 14, :end-line 14, :max-fixed-arity 1, :fn-var true, :arglists (quote ([coll]))}, replace-with {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 31, :column 8, :end-line 31, :end-column 20, :private true, :arglists (quote ([f]))}, :private true, :name clojure.string/replace-with, :variadic false, :file "out/clojure/string.cljs", :end-column 20, :method-params ([f]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 31, :end-line 31, :max-fixed-arity 1, :fn-var true, :arglists (quote ([f]))}, capitalize {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 95, :column 7, :end-line 95, :end-column 17, :arglists (quote ([s])), :doc "Converts first character of the string to upper-case, all other\n characters to lower-case."}, :name clojure.string/capitalize, :variadic false, :file "out/clojure/string.cljs", :end-column 17, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 95, :end-line 95, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Converts first character of the string to upper-case, all other\n characters to lower-case."}, reverse {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 21, :column 7, :end-line 21, :end-column 14, :arglists (quote ([s])), :doc "Returns s with its characters reversed."}, :name clojure.string/reverse, :variadic false, :file "out/clojure/string.cljs", :end-column 14, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 21, :end-line 21, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Returns s with its characters reversed."}, join {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 66, :column 7, :end-line 66, :end-column 11, :arglists (quote ([coll] [separator coll])), :doc "Returns a string of all elements in coll, as returned by (seq coll),\n separated by an optional separator.", :top-fn {:variadic false, :max-fixed-arity 2, :method-params ([coll] [separator coll]), :arglists ([coll] [separator coll]), :arglists-meta (nil nil)}}, :name clojure.string/join, :variadic false, :file "out/clojure/string.cljs", :end-column 11, :top-fn {:variadic false, :max-fixed-arity 2, :method-params ([coll] [separator coll]), :arglists ([coll] [separator coll]), :arglists-meta (nil nil)}, :method-params ([coll] [separator coll]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 66, :end-line 66, :max-fixed-arity 2, :fn-var true, :arglists ([coll] [separator coll]), :doc "Returns a string of all elements in coll, as returned by (seq coll),\n separated by an optional separator."}, replace-first {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 57, :column 7, :end-line 57, :end-column 20, :arglists (quote ([s match replacement])), :doc "Replaces the first instance of match with replacement in s.\n match/replacement can be:\n\n string / string\n pattern / (string or function of match)."}, :name clojure.string/replace-first, :variadic false, :file "out/clojure/string.cljs", :end-column 20, :method-params ([s match replacement]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 57, :end-line 57, :max-fixed-arity 3, :fn-var true, :arglists (quote ([s match replacement])), :doc "Replaces the first instance of match with replacement in s.\n match/replacement can be:\n\n string / string\n pattern / (string or function of match)."}, starts-with? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 245, :column 16, :end-line 245, :end-column 28, :tag boolean, :arglists (quote ([s substr])), :doc "True if s starts with substr."}, :name clojure.string/starts-with?, :variadic false, :file "out/clojure/string.cljs", :end-column 28, :method-params ([s substr]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 245, :ret-tag boolean, :end-line 245, :max-fixed-arity 2, :tag boolean, :fn-var true, :arglists (quote ([s substr])), :doc "True if s starts with substr."}, escape {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 198, :column 7, :end-line 198, :end-column 13, :arglists (quote ([s cmap])), :doc "Return a new string, using cmap to escape each character ch\n from s as follows:\n\n If (cmap ch) is nil, append ch to the new string.\n If (cmap ch) is non-nil, append (str (cmap ch)) instead."}, :name clojure.string/escape, :variadic false, :file "out/clojure/string.cljs", :end-column 13, :method-params ([s cmap]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 198, :end-line 198, :max-fixed-arity 2, :fn-var true, :arglists (quote ([s cmap])), :doc "Return a new string, using cmap to escape each character ch\n from s as follows:\n\n If (cmap ch) is nil, append ch to the new string.\n If (cmap ch) is non-nil, append (str (cmap ch)) instead."}, replace-all {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 27, :column 8, :end-line 27, :end-column 19, :private true, :arglists (quote ([s re replacement]))}, :private true, :name clojure.string/replace-all, :variadic false, :file "out/clojure/string.cljs", :end-column 19, :method-params ([s re replacement]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 27, :end-line 27, :max-fixed-arity 3, :fn-var true, :arglists (quote ([s re replacement]))}, discard-trailing-if-needed {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 120, :column 8, :end-line 120, :end-column 34, :private true, :arglists (quote ([limit v]))}, :private true, :name clojure.string/discard-trailing-if-needed, :variadic false, :file "out/clojure/string.cljs", :end-column 34, :method-params ([limit v]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 120, :end-line 120, :max-fixed-arity 2, :fn-var true, :arglists (quote ([limit v]))}, last-index-of {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 231, :column 7, :end-line 231, :end-column 20, :arglists (quote ([s value] [s value from-index])), :doc "Return last index of value (string or char) in s, optionally\n searching backward from from-index or nil if not found.", :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s value] [s value from-index]), :arglists ([s value] [s value from-index]), :arglists-meta (nil nil)}}, :name clojure.string/last-index-of, :variadic false, :file "out/clojure/string.cljs", :end-column 20, :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s value] [s value from-index]), :arglists ([s value] [s value from-index]), :arglists-meta (nil nil)}, :method-params ([s value] [s value from-index]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 231, :end-line 231, :max-fixed-arity 3, :fn-var true, :arglists ([s value] [s value from-index]), :doc "Return last index of value (string or char) in s, optionally\n searching backward from from-index or nil if not found."}, pop-last-while-empty {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 113, :column 8, :end-line 113, :end-column 28, :private true, :arglists (quote ([v]))}, :private true, :name clojure.string/pop-last-while-empty, :variadic false, :file "out/clojure/string.cljs", :end-column 28, :method-params ([v]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 113, :end-line 113, :max-fixed-arity 1, :fn-var true, :arglists (quote ([v]))}, includes? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 255, :column 16, :end-line 255, :end-column 25, :tag boolean, :arglists (quote ([s substr])), :doc "True if s includes substr."}, :name clojure.string/includes?, :variadic false, :file "out/clojure/string.cljs", :end-column 25, :method-params ([s substr]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 255, :ret-tag boolean, :end-line 255, :max-fixed-arity 2, :tag boolean, :fn-var true, :arglists (quote ([s substr])), :doc "True if s includes substr."}, replace {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 39, :column 7, :end-line 39, :end-column 14, :arglists (quote ([s match replacement])), :doc "Replaces all instance of match with replacement in s.\n match/replacement can be:\n\n string / string\n pattern / (string or function of match)."}, :name clojure.string/replace, :variadic false, :file "out/clojure/string.cljs", :end-column 14, :method-params ([s match replacement]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 39, :end-line 39, :max-fixed-arity 3, :fn-var true, :arglists (quote ([s match replacement])), :doc "Replaces all instance of match with replacement in s.\n match/replacement can be:\n\n string / string\n pattern / (string or function of match)."}, split-lines {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 160, :column 7, :end-line 160, :end-column 18, :arglists (quote ([s])), :doc "Splits s on \n or \r\n."}, :name clojure.string/split-lines, :variadic false, :file "out/clojure/string.cljs", :end-column 18, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 160, :end-line 160, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Splits s on \n or \r\n."}, lower-case {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 90, :column 7, :end-line 90, :end-column 17, :arglists (quote ([s])), :doc "Converts string to all lower-case."}, :name clojure.string/lower-case, :variadic false, :file "out/clojure/string.cljs", :end-column 17, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 90, :end-line 90, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Converts string to all lower-case."}, trim-newline {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 180, :column 7, :end-line 180, :end-column 19, :arglists (quote ([s])), :doc "Removes all trailing newline \\n or return \\r characters from\n string. Similar to Perl's chomp."}, :name clojure.string/trim-newline, :variadic false, :file "out/clojure/string.cljs", :end-column 19, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 180, :end-line 180, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Removes all trailing newline \\n or return \\r characters from\n string. Similar to Perl's chomp."}, upper-case {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 85, :column 7, :end-line 85, :end-column 17, :arglists (quote ([s])), :doc "Converts string to all upper-case."}, :name clojure.string/upper-case, :variadic false, :file "out/clojure/string.cljs", :end-column 17, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 85, :end-line 85, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Converts string to all upper-case."}, split {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 136, :column 7, :end-line 136, :end-column 12, :arglists (quote ([s re] [s re limit])), :doc "Splits string on a regular expression. Optional argument limit is\n the maximum number of splits. Not lazy. Returns vector of the splits.", :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s re] [s re limit]), :arglists ([s re] [s re limit]), :arglists-meta (nil nil)}}, :name clojure.string/split, :variadic false, :file "out/clojure/string.cljs", :end-column 12, :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s re] [s re limit]), :arglists ([s re] [s re limit]), :arglists-meta (nil nil)}, :method-params ([s re] [s re limit]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 136, :end-line 136, :max-fixed-arity 3, :fn-var true, :arglists ([s re] [s re limit]), :doc "Splits string on a regular expression. Optional argument limit is\n the maximum number of splits. Not lazy. Returns vector of the splits."}, trimr {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 175, :column 7, :end-line 175, :end-column 12, :arglists (quote ([s])), :doc "Removes whitespace from the right side of string."}, :name clojure.string/trimr, :variadic false, :file "out/clojure/string.cljs", :end-column 12, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 175, :end-line 175, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Removes whitespace from the right side of string."}, index-of {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 217, :column 7, :end-line 217, :end-column 15, :arglists (quote ([s value] [s value from-index])), :doc "Return index of value (string or char) in s, optionally searching\n forward from from-index or nil if not found.", :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s value] [s value from-index]), :arglists ([s value] [s value from-index]), :arglists-meta (nil nil)}}, :name clojure.string/index-of, :variadic false, :file "out/clojure/string.cljs", :end-column 15, :top-fn {:variadic false, :max-fixed-arity 3, :method-params ([s value] [s value from-index]), :arglists ([s value] [s value from-index]), :arglists-meta (nil nil)}, :method-params ([s value] [s value from-index]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 217, :end-line 217, :max-fixed-arity 3, :fn-var true, :arglists ([s value] [s value from-index]), :doc "Return index of value (string or char) in s, optionally searching\n forward from from-index or nil if not found."}, trim {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 165, :column 7, :end-line 165, :end-column 11, :arglists (quote ([s])), :doc "Removes whitespace from both ends of string."}, :name clojure.string/trim, :variadic false, :file "out/clojure/string.cljs", :end-column 11, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 165, :end-line 165, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Removes whitespace from both ends of string."}, triml {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 170, :column 7, :end-line 170, :end-column 12, :arglists (quote ([s])), :doc "Removes whitespace from the left side of string."}, :name clojure.string/triml, :variadic false, :file "out/clojure/string.cljs", :end-column 12, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 170, :end-line 170, :max-fixed-arity 1, :fn-var true, :arglists (quote ([s])), :doc "Removes whitespace from the left side of string."}, blank? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 193, :column 16, :end-line 193, :end-column 22, :tag boolean, :arglists (quote ([s])), :doc "True is s is nil, empty, or contains only whitespace."}, :name clojure.string/blank?, :variadic false, :file "out/clojure/string.cljs", :end-column 22, :method-params ([s]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 193, :ret-tag boolean, :end-line 193, :max-fixed-arity 1, :tag boolean, :fn-var true, :arglists (quote ([s])), :doc "True is s is nil, empty, or contains only whitespace."}, re-surrogate-pair {:name clojure.string/re-surrogate-pair, :file "out/clojure/string.cljs", :line 18, :column 1, :end-line 18, :end-column 33, :private true, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 18, :column 16, :end-line 18, :end-column 33, :private true}, :tag js/RegExp}, split-with-empty-regex {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/clojure/string.cljs", :line 126, :column 8, :end-line 126, :end-column 30, :private true, :arglists (quote ([s limit]))}, :private true, :name clojure.string/split-with-empty-regex, :variadic false, :file "out/clojure/string.cljs", :end-column 30, :method-params ([s limit]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 126, :end-line 126, :max-fixed-arity 2, :fn-var true, :arglists (quote ([s limit]))}}, :require-macros nil, :cljs.analyzer/constants {:seen #{:else}, :order [:else]}, :doc nil} \ No newline at end of file
diff --git a/assets/viz/2/clojure/string.js b/assets/viz/2/clojure/string.js
new file mode 100644
index 0000000..b2f5754
--- /dev/null
+++ b/assets/viz/2/clojure/string.js
@@ -0,0 +1,505 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('clojure.string');
+goog.require('cljs.core');
+goog.require('goog.string');
+goog.require('goog.string.StringBuffer');
+clojure.string.seq_reverse = (function clojure$string$seq_reverse(coll){
+return cljs.core.reduce.call(null,cljs.core.conj,cljs.core.List.EMPTY,coll);
+});
+clojure.string.re_surrogate_pair = (new RegExp("([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])","g"));
+/**
+ * Returns s with its characters reversed.
+ */
+clojure.string.reverse = (function clojure$string$reverse(s){
+return s.replace(clojure.string.re_surrogate_pair,"$2$1").split("").reverse().join("");
+});
+clojure.string.replace_all = (function clojure$string$replace_all(s,re,replacement){
+return s.replace((new RegExp(re.source,"g")),replacement);
+});
+clojure.string.replace_with = (function clojure$string$replace_with(f){
+return (function() {
+var G__8074__delegate = function (args){
+var matches = cljs.core.drop_last.call(null,(2),args);
+if(cljs.core._EQ_.call(null,cljs.core.count.call(null,matches),(1))){
+return f.call(null,cljs.core.first.call(null,matches));
+} else {
+return f.call(null,cljs.core.vec.call(null,matches));
+}
+};
+var G__8074 = function (var_args){
+var args = null;
+if (arguments.length > 0) {
+var G__8075__i = 0, G__8075__a = new Array(arguments.length - 0);
+while (G__8075__i < G__8075__a.length) {G__8075__a[G__8075__i] = arguments[G__8075__i + 0]; ++G__8075__i;}
+ args = new cljs.core.IndexedSeq(G__8075__a,0);
+}
+return G__8074__delegate.call(this,args);};
+G__8074.cljs$lang$maxFixedArity = 0;
+G__8074.cljs$lang$applyTo = (function (arglist__8076){
+var args = cljs.core.seq(arglist__8076);
+return G__8074__delegate(args);
+});
+G__8074.cljs$core$IFn$_invoke$arity$variadic = G__8074__delegate;
+return G__8074;
+})()
+;
+});
+/**
+ * Replaces all instance of match with replacement in s.
+ * match/replacement can be:
+ *
+ * string / string
+ * pattern / (string or function of match).
+ */
+clojure.string.replace = (function clojure$string$replace(s,match,replacement){
+if(typeof match === 'string'){
+return s.replace((new RegExp(goog.string.regExpEscape(match),"g")),replacement);
+} else {
+if((match instanceof RegExp)){
+if(typeof replacement === 'string'){
+return clojure.string.replace_all.call(null,s,match,replacement);
+} else {
+return clojure.string.replace_all.call(null,s,match,clojure.string.replace_with.call(null,replacement));
+}
+} else {
+throw [cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid match arg: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(match)].join('');
+
+}
+}
+});
+/**
+ * Replaces the first instance of match with replacement in s.
+ * match/replacement can be:
+ *
+ * string / string
+ * pattern / (string or function of match).
+ */
+clojure.string.replace_first = (function clojure$string$replace_first(s,match,replacement){
+return s.replace(match,replacement);
+});
+/**
+ * Returns a string of all elements in coll, as returned by (seq coll),
+ * separated by an optional separator.
+ */
+clojure.string.join = (function clojure$string$join(var_args){
+var args8077 = [];
+var len__7927__auto___8080 = arguments.length;
+var i__7928__auto___8081 = (0);
+while(true){
+if((i__7928__auto___8081 < len__7927__auto___8080)){
+args8077.push((arguments[i__7928__auto___8081]));
+
+var G__8082 = (i__7928__auto___8081 + (1));
+i__7928__auto___8081 = G__8082;
+continue;
+} else {
+}
+break;
+}
+
+var G__8079 = args8077.length;
+switch (G__8079) {
+case 1:
+return clojure.string.join.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
+
+break;
+case 2:
+return clojure.string.join.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+default:
+throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8077.length)].join('')));
+
+}
+});
+
+clojure.string.join.cljs$core$IFn$_invoke$arity$1 = (function (coll){
+var sb = (new goog.string.StringBuffer());
+var coll__$1 = cljs.core.seq.call(null,coll);
+while(true){
+if(!((coll__$1 == null))){
+var G__8084 = sb.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(cljs.core.first.call(null,coll__$1))].join(''));
+var G__8085 = cljs.core.next.call(null,coll__$1);
+sb = G__8084;
+coll__$1 = G__8085;
+continue;
+} else {
+return sb.toString();
+}
+break;
+}
+});
+
+clojure.string.join.cljs$core$IFn$_invoke$arity$2 = (function (separator,coll){
+var sb = (new goog.string.StringBuffer());
+var coll__$1 = cljs.core.seq.call(null,coll);
+while(true){
+if(!((coll__$1 == null))){
+sb.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(cljs.core.first.call(null,coll__$1))].join(''));
+
+var coll__$2 = cljs.core.next.call(null,coll__$1);
+if((coll__$2 == null)){
+} else {
+sb.append(separator);
+}
+
+var G__8086 = sb;
+var G__8087 = coll__$2;
+sb = G__8086;
+coll__$1 = G__8087;
+continue;
+} else {
+return sb.toString();
+}
+break;
+}
+});
+
+clojure.string.join.cljs$lang$maxFixedArity = 2;
+
+/**
+ * Converts string to all upper-case.
+ */
+clojure.string.upper_case = (function clojure$string$upper_case(s){
+return s.toUpperCase();
+});
+/**
+ * Converts string to all lower-case.
+ */
+clojure.string.lower_case = (function clojure$string$lower_case(s){
+return s.toLowerCase();
+});
+/**
+ * Converts first character of the string to upper-case, all other
+ * characters to lower-case.
+ */
+clojure.string.capitalize = (function clojure$string$capitalize(s){
+if((cljs.core.count.call(null,s) < (2))){
+return clojure.string.upper_case.call(null,s);
+} else {
+return [cljs.core.str.cljs$core$IFn$_invoke$arity$1(clojure.string.upper_case.call(null,cljs.core.subs.call(null,s,(0),(1)))),cljs.core.str.cljs$core$IFn$_invoke$arity$1(clojure.string.lower_case.call(null,cljs.core.subs.call(null,s,(1))))].join('');
+}
+});
+clojure.string.pop_last_while_empty = (function clojure$string$pop_last_while_empty(v){
+var v__$1 = v;
+while(true){
+if(("" === cljs.core.peek.call(null,v__$1))){
+var G__8088 = cljs.core.pop.call(null,v__$1);
+v__$1 = G__8088;
+continue;
+} else {
+return v__$1;
+}
+break;
+}
+});
+clojure.string.discard_trailing_if_needed = (function clojure$string$discard_trailing_if_needed(limit,v){
+if((((0) === limit)) && (((1) < cljs.core.count.call(null,v)))){
+return clojure.string.pop_last_while_empty.call(null,v);
+} else {
+return v;
+}
+});
+clojure.string.split_with_empty_regex = (function clojure$string$split_with_empty_regex(s,limit){
+if(((limit <= (0))) || ((limit >= ((2) + cljs.core.count.call(null,s))))){
+return cljs.core.conj.call(null,cljs.core.vec.call(null,cljs.core.cons.call(null,"",cljs.core.map.call(null,cljs.core.str,cljs.core.seq.call(null,s)))),"");
+} else {
+var pred__8092 = cljs.core._EQ__EQ_;
+var expr__8093 = limit;
+if(cljs.core.truth_(pred__8092.call(null,(1),expr__8093))){
+return (new cljs.core.PersistentVector(null,1,(5),cljs.core.PersistentVector.EMPTY_NODE,[s],null));
+} else {
+if(cljs.core.truth_(pred__8092.call(null,(2),expr__8093))){
+return (new cljs.core.PersistentVector(null,2,(5),cljs.core.PersistentVector.EMPTY_NODE,["",s],null));
+} else {
+var c = (limit - (2));
+return cljs.core.conj.call(null,cljs.core.vec.call(null,cljs.core.cons.call(null,"",cljs.core.subvec.call(null,cljs.core.vec.call(null,cljs.core.map.call(null,cljs.core.str,cljs.core.seq.call(null,s))),(0),c))),cljs.core.subs.call(null,s,c));
+}
+}
+}
+});
+/**
+ * Splits string on a regular expression. Optional argument limit is
+ * the maximum number of splits. Not lazy. Returns vector of the splits.
+ */
+clojure.string.split = (function clojure$string$split(var_args){
+var args8095 = [];
+var len__7927__auto___8098 = arguments.length;
+var i__7928__auto___8099 = (0);
+while(true){
+if((i__7928__auto___8099 < len__7927__auto___8098)){
+args8095.push((arguments[i__7928__auto___8099]));
+
+var G__8100 = (i__7928__auto___8099 + (1));
+i__7928__auto___8099 = G__8100;
+continue;
+} else {
+}
+break;
+}
+
+var G__8097 = args8095.length;
+switch (G__8097) {
+case 2:
+return clojure.string.split.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+case 3:
+return clojure.string.split.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
+
+break;
+default:
+throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8095.length)].join('')));
+
+}
+});
+
+clojure.string.split.cljs$core$IFn$_invoke$arity$2 = (function (s,re){
+return clojure.string.split.call(null,s,re,(0));
+});
+
+clojure.string.split.cljs$core$IFn$_invoke$arity$3 = (function (s,re,limit){
+return clojure.string.discard_trailing_if_needed.call(null,limit,((("/(?:)/" === [cljs.core.str.cljs$core$IFn$_invoke$arity$1(re)].join('')))?clojure.string.split_with_empty_regex.call(null,s,limit):(((limit < (1)))?cljs.core.vec.call(null,[cljs.core.str.cljs$core$IFn$_invoke$arity$1(s)].join('').split(re)):(function (){var s__$1 = s;
+var limit__$1 = limit;
+var parts = cljs.core.PersistentVector.EMPTY;
+while(true){
+if(((1) === limit__$1)){
+return cljs.core.conj.call(null,parts,s__$1);
+} else {
+var m = cljs.core.re_find.call(null,re,s__$1);
+if(!((m == null))){
+var index = s__$1.indexOf(m);
+var G__8102 = s__$1.substring((index + cljs.core.count.call(null,m)));
+var G__8103 = (limit__$1 - (1));
+var G__8104 = cljs.core.conj.call(null,parts,s__$1.substring((0),index));
+s__$1 = G__8102;
+limit__$1 = G__8103;
+parts = G__8104;
+continue;
+} else {
+return cljs.core.conj.call(null,parts,s__$1);
+}
+}
+break;
+}
+})())));
+});
+
+clojure.string.split.cljs$lang$maxFixedArity = 3;
+
+/**
+ * Splits s on
+ * or
+ * .
+ */
+clojure.string.split_lines = (function clojure$string$split_lines(s){
+return clojure.string.split.call(null,s,/\n|\r\n/);
+});
+/**
+ * Removes whitespace from both ends of string.
+ */
+clojure.string.trim = (function clojure$string$trim(s){
+return goog.string.trim(s);
+});
+/**
+ * Removes whitespace from the left side of string.
+ */
+clojure.string.triml = (function clojure$string$triml(s){
+return goog.string.trimLeft(s);
+});
+/**
+ * Removes whitespace from the right side of string.
+ */
+clojure.string.trimr = (function clojure$string$trimr(s){
+return goog.string.trimRight(s);
+});
+/**
+ * Removes all trailing newline \n or return \r characters from
+ * string. Similar to Perl's chomp.
+ */
+clojure.string.trim_newline = (function clojure$string$trim_newline(s){
+var index = s.length;
+while(true){
+if((index === (0))){
+return "";
+} else {
+var ch = cljs.core.get.call(null,s,(index - (1)));
+if((("\n" === ch)) || (("\r" === ch))){
+var G__8105 = (index - (1));
+index = G__8105;
+continue;
+} else {
+return s.substring((0),index);
+}
+}
+break;
+}
+});
+/**
+ * True is s is nil, empty, or contains only whitespace.
+ */
+clojure.string.blank_QMARK_ = (function clojure$string$blank_QMARK_(s){
+return goog.string.isEmptySafe(s);
+});
+/**
+ * Return a new string, using cmap to escape each character ch
+ * from s as follows:
+ *
+ * If (cmap ch) is nil, append ch to the new string.
+ * If (cmap ch) is non-nil, append (str (cmap ch)) instead.
+ */
+clojure.string.escape = (function clojure$string$escape(s,cmap){
+var buffer = (new goog.string.StringBuffer());
+var length = s.length;
+var index = (0);
+while(true){
+if((length === index)){
+return buffer.toString();
+} else {
+var ch = s.charAt(index);
+var replacement = cljs.core.get.call(null,cmap,ch);
+if(!((replacement == null))){
+buffer.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(replacement)].join(''));
+} else {
+buffer.append(ch);
+}
+
+var G__8106 = (index + (1));
+index = G__8106;
+continue;
+}
+break;
+}
+});
+/**
+ * Return index of value (string or char) in s, optionally searching
+ * forward from from-index or nil if not found.
+ */
+clojure.string.index_of = (function clojure$string$index_of(var_args){
+var args8107 = [];
+var len__7927__auto___8110 = arguments.length;
+var i__7928__auto___8111 = (0);
+while(true){
+if((i__7928__auto___8111 < len__7927__auto___8110)){
+args8107.push((arguments[i__7928__auto___8111]));
+
+var G__8112 = (i__7928__auto___8111 + (1));
+i__7928__auto___8111 = G__8112;
+continue;
+} else {
+}
+break;
+}
+
+var G__8109 = args8107.length;
+switch (G__8109) {
+case 2:
+return clojure.string.index_of.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+case 3:
+return clojure.string.index_of.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
+
+break;
+default:
+throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8107.length)].join('')));
+
+}
+});
+
+clojure.string.index_of.cljs$core$IFn$_invoke$arity$2 = (function (s,value){
+var result = s.indexOf(value);
+if((result < (0))){
+return null;
+} else {
+return result;
+}
+});
+
+clojure.string.index_of.cljs$core$IFn$_invoke$arity$3 = (function (s,value,from_index){
+var result = s.indexOf(value,from_index);
+if((result < (0))){
+return null;
+} else {
+return result;
+}
+});
+
+clojure.string.index_of.cljs$lang$maxFixedArity = 3;
+
+/**
+ * Return last index of value (string or char) in s, optionally
+ * searching backward from from-index or nil if not found.
+ */
+clojure.string.last_index_of = (function clojure$string$last_index_of(var_args){
+var args8114 = [];
+var len__7927__auto___8117 = arguments.length;
+var i__7928__auto___8118 = (0);
+while(true){
+if((i__7928__auto___8118 < len__7927__auto___8117)){
+args8114.push((arguments[i__7928__auto___8118]));
+
+var G__8119 = (i__7928__auto___8118 + (1));
+i__7928__auto___8118 = G__8119;
+continue;
+} else {
+}
+break;
+}
+
+var G__8116 = args8114.length;
+switch (G__8116) {
+case 2:
+return clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+case 3:
+return clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
+
+break;
+default:
+throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8114.length)].join('')));
+
+}
+});
+
+clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$2 = (function (s,value){
+var result = s.lastIndexOf(value);
+if((result < (0))){
+return null;
+} else {
+return result;
+}
+});
+
+clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$3 = (function (s,value,from_index){
+var result = s.lastIndexOf(value,from_index);
+if((result < (0))){
+return null;
+} else {
+return result;
+}
+});
+
+clojure.string.last_index_of.cljs$lang$maxFixedArity = 3;
+
+/**
+ * True if s starts with substr.
+ */
+clojure.string.starts_with_QMARK_ = (function clojure$string$starts_with_QMARK_(s,substr){
+return goog.string.startsWith(s,substr);
+});
+/**
+ * True if s ends with substr.
+ */
+clojure.string.ends_with_QMARK_ = (function clojure$string$ends_with_QMARK_(s,substr){
+return goog.string.endsWith(s,substr);
+});
+/**
+ * True if s includes substr.
+ */
+clojure.string.includes_QMARK_ = (function clojure$string$includes_QMARK_(s,substr){
+return goog.string.contains(s,substr);
+});
+
+//# sourceMappingURL=string.js.map \ No newline at end of file
diff --git a/assets/viz/2/clojure/string.js.map b/assets/viz/2/clojure/string.js.map
new file mode 100644
index 0000000..12d3b4d
--- /dev/null
+++ b/assets/viz/2/clojure/string.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/clojure\/string.js","sources":["string.cljs"],"lineCount":505,"mappings":";AAQA;;;;AAKA,6BAAA,7BAAOA,kEACJC;AADH,AAEE,iDAAA,1CAACC,2BAAOC,oCAAQF;;AAElB,AAAeG,mCACb,KAAAC,OAAA,yCAAA;AAEF;;;yBAAA,zBAAMC,0DAEHC;AAFH,OAGM,2CAAA,3CAAUA,UAAEH,jBACZ,OAAA,AAAA,yDAAA,mBAAA;;AAEN,6BAAA,7BAAOI,kEACJD,EAAEE,GAAGC;AADR,AAEE,OAAUH,UAAE,KAAAF,iBAAA,VAAY,AAAUI,gBAASC;;AAE7C,8BAAA,9BAAOC,oEACJC;AADH,AAEE;kCAAOC;AAAP,AACE,IAAMC,UAAQ,8BAAA,9BAACC,kCAAYF;AAA3B,AACE,GAAI,4DAAA,5DAACG,yBAAE,AAACC,0BAAMH;AACZ,OAACF,YAAE,AAACM,0BAAMJ;;AACV,OAACF,YAAE,AAACO,wBAAIL;;;;IAJPD;;;;EAAAA;;mCAAAA;;;IAAAA;yBAAAA;;;;;;;AAMT;;;;;;;yBAAA,zBAAMO,0DAMHb,EAAEc,MAAMX;AANX,AAOE,GACE,OAASW;AACT,OAAUd,UAAE,KAAAF,uCAAA,hCAAY,AAACiB,yBAAqBD,aAAYX;;AAF5D,GAIE,kBAAWL,jBAAUgB;AACrB,GAAI,OAASX;AACX,OAACF,qCAAYD,EAAEc,MAAMX;;AACrB,OAACF,qCAAYD,EAAEc,MAAM,AAACV,sCAAaD;;;AAPvC,AASQ,MAAO,6CAAA,mEAA2BW;;;;;AAE5C;;;;;;;+BAAA,\/BAAME,sEAMHhB,EAAEc,MAAMX;AANX,AAOE,OAAUH,UAAEc,MAAMX;;AAEpB,AAAA;;;;sBAAA,8BAAAc,pDAAMK;AAAN,AAAA,IAAAJ,WAAA;AAAA,AAAA,IAAAC,yBAAA,AAAA;AAAA,AAAA,IAAAC,uBAAA;;AAAA,AAAA,GAAA,CAAAA,uBAAAD;AAAA,AAAA,AAAAD,cAAA,CAAA,UAAAE;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAAC,UAAA,AAAAH;AAAA,AAAA,QAAAG;KAAA;AAAA,OAAAC,kDAAA,CAAA,UAAA;;;KAAA;AAAA,OAAAA,kDAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;;AAAA,MAAA,KAAAC,MAAA,6CAAA,+DAAA,AAAAL;;;;;AAAA,AAAA,oDAAA,pDAAMI,+DAGF5B;AAHJ,AAIG,IAAO8B,KAAG,KAAAC;IAAgB\/B,WAAK,AAACgC,wBAAIhC;;AAApC,AACE,GAAA,EAAQ,aAAA,ZAAMA;AACZ,cAAO,AAAG8B,UAAW,6CAAK,AAACb,0BAAMjB;cAAS,AAACiC,yBAAKjC;;;;;AAChD,OAAW8B;;;;;;AAPlB,AAAA,oDAAA,pDAAMF,+DAQFM,UAAUlC;AARd,AASG,IAAO8B,KAAG,KAAAC;IAAgB\/B,WAAK,AAACgC,wBAAIhC;;AAApC,AACE,GAAA,EAAQ,aAAA,ZAAMA;AACZ,AACE,AAAG8B,UAAW,6CAAK,AAACb,0BAAMjB;;AAC1B,IAAMA,WAAK,AAACiC,yBAAKjC;AAAjB,AACE,GAAU,aAAA,ZAAMA;AAAhB;AAAA,AACE,AAAG8B,UAAWI;;;AAChB,cAAOJ;cAAG9B;;;;;AACd,OAAW8B;;;;;;AAjBlB,AAAA,8CAAA,9CAAMF;;AAAN,AAmBA;;;4BAAA,5BAAMO,gEAEH7B;AAFH,AAGE,OAAcA;;AAEhB;;;4BAAA,5BAAM8B,gEAEH9B;AAFH,AAGE,OAAcA;;AAEhB;;;;4BAAA,5BAAM+B,gEAGH\/B;AAHH,AAIE,GAAI,gCAAA,\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\/B,AAAA,+CAAA,\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","names":["clojure.string\/seq-reverse","coll","cljs.core\/reduce","cljs.core\/conj","clojure.string\/re-surrogate-pair","js\/RegExp","clojure.string\/reverse","s","clojure.string\/replace-all","re","replacement","clojure.string\/replace-with","f","args","matches","cljs.core\/drop-last","cljs.core\/=","cljs.core\/count","cljs.core\/first","cljs.core\/vec","clojure.string\/replace","match","goog.string\/regExpEscape","clojure.string\/replace-first","var_args","args8077","len__7927__auto__","i__7928__auto__","G__8079","clojure.string\/join","js\/Error","sb","goog\/string.StringBuffer","cljs.core\/seq","cljs.core\/next","separator","clojure.string\/upper-case","clojure.string\/lower-case","clojure.string\/capitalize","cljs.core\/subs","clojure.string\/pop-last-while-empty","v","cljs.core\/peek","cljs.core\/pop","clojure.string\/discard-trailing-if-needed","limit","clojure.string\/split-with-empty-regex","cljs.core\/cons","cljs.core\/map","cljs.core\/str","pred__8092","expr__8093","cljs.core\/==","cljs.core\/PersistentVector","c","cljs.core\/subvec","args8095","G__8097","clojure.string\/split","parts","m","cljs.core\/re-find","index","clojure.string\/split-lines","clojure.string\/trim","goog.string\/trim","clojure.string\/triml","goog.string\/trimLeft","clojure.string\/trimr","goog.string\/trimRight","clojure.string\/trim-newline","ch","cljs.core\/get","clojure.string\/blank?","goog.string\/isEmptySafe","clojure.string\/escape","cmap","buffer","length","args8107","G__8109","clojure.string\/index-of","value","result","from-index","args8114","G__8116","clojure.string\/last-index-of","clojure.string\/starts-with?","substr","goog.string\/startsWith","clojure.string\/ends-with?","goog.string\/endsWith","clojure.string\/includes?","goog.string\/contains"]} \ No newline at end of file