          "\n"
          "}")))
 
+
 (defn- write-property-accessor-function [to-id slot]
   (str "GroupedNode.prototype." (:name slot) " = function (value) {\n"
        "  return this." (node-id->var to-id)
        "." (:name slot) "(value);\n"
        "};"))
 
-(defn- write-property-constant-function [to-id slot]
+
+(defmulti write-accessor-function (fn [_ slot] (:type slot)))
+
+(defmethod write-accessor-function :accessor [to-id slot]
+  (write-property-accessor-function to-id slot))
+
+(defmethod write-accessor-function :gate [to-id slot]
+  (write-property-accessor-function to-id slot))
+
+(defmethod write-accessor-function :constant [to-id slot]
   (str "GroupedNode.prototype." (:name slot) " = function (value) {\n"
        "  if (value === undefined) {\n"
        "    return this." (node-id->var to-id) "." (:name slot) ";\n"

(defn- node-id->var [node-id]
  (string/replace (str node-id) #"[:-]" ""))

(defn- write-dependency [[class-name [file _]]]
  (str "var " class-name " = require('" file "');"))

(defn- node-dependencies [node]
  (-> node node/node-type :export-data :dependencies))

(defn- write-dependencies [node-graph]
  (->> (:nodes node-graph)

       (map write-dependency)
       (string/join "\n")))


(defmulti write-set-input (fn [_ [_ input]] (:type input)))

(defmethod write-set-input :param [node-id [_ input]]
  (str "  " (node-id->var node-id)
       "." (:name input)
       ".value = " (:default input) ";"))

(defmethod write-set-input :constant [node-id [_ input]]
  (str "  " (node-id->var node-id)
       "." (:name input)
       " = " (pr-str (:default input)) ";"))

(defmethod write-set-input :default [_ _] nil)



(defn- write-create-node [[node-id node]]
  (let [construct (str "  var " (node-id->var node-id)
                       " = " (node-constructor node))
        props (->> (node-inputs node)
                   (keep (partial write-set-input node-id))
                   (string/join "\n"))]
    (str construct "\n"
         props (if (string/blank? props) "" "\n"))))

(defn- write-create-nodes [node-graph]
  (->> (:nodes node-graph)
       (filter (fn [[_ n]] (node-constructor n)))
       (map write-create-node)
       (string/join "\n")))



(defmulti write-connect-call (fn [_ _ _ to-slot] (:type to-slot)))

(defmethod write-connect-call :param [from-node-var from-slot to-node-var to-slot]
  (str "  " from-node-var
       ".connect(" to-node-var "." (:name to-slot)
       ", " (:index from-slot)
       ");"))

(defmethod write-connect-call :null-node [_ _ _ _] nil)

(defmethod write-connect-call :default [from-node-var from-slot to-node-var to-slot]
  (str "  " from-node-var
       ".connect(" to-node-var
       ", " (:index from-slot)
       ");"))


(defn- write-connection [node-graph [[from-node-id from-slot-id] [to-node-id to-slot-id]]]
  (let [from-node-var (node-id->var from-node-id)
        to-node-var (node-id->var to-node-id)

        from-slot (-> (node-graph-node node-graph from-node-id)
                      (node-output from-slot-id))
        to-slot (-> (node-graph-node node-graph from-node-id)
                    (node-input to-slot-id))]

    (when-not (= (:type from-slot) :null-node)
      (write-connect-call from-node-var from-slot to-node-var to-slot))))

(defn- write-connections [node-graph]
  (->> (:connections node-graph)
       (map (partial write-connection node-graph))
       (remove nil?)
       (string/join "\n")))



(defn- write-property-input [node-graph [from-node-id _]]
  (->> (node-graph/nodes-out-from node-graph from-node-id)
       (map (fn [[_ [to-id to-slot-id]]]
              [to-id (-> (node-graph-node node-graph to-id)
                         (node-input to-slot-id))]))
       (filter (fn [[_ slot]] (#{:param :node} (:type slot))))
       (map (fn [[node-id slot]]
              (str "  this." (or (:name slot) (node-id->var node-id))
                   " = " (node-id->var node-id) (if (= (:type slot) :param)
