          :fixture fixture :id (id-fn)))
 
 (defn- patch-heads
-  "Assigns the heads of a fixture to a DMX universe and starting channel; resolves all of
-  their channel assignments."
+  "Assigns the heads of a fixture to a DMX universe and starting
+  channel; resolves all of their channel assignments."
   [fixture channel-assigner id-fn]
   (let [assigner (partial patch-head channel-assigner fixture id-fn)]
     (update-in fixture [:heads] #(map assigner %))))
 
 (defn patch-fixture
-  "Assign a fixture to a DMX universe and starting channel; resolves all of its channel assignments."
+  "Assign a fixture to a DMX universe and starting channel; resolves
+  all of its channel assignments."
   [fixture universe start-address id-fn]
   (let [assigner (partial assign-channel universe start-address)]
     (update-in (patch-heads fixture assigner id-fn) [:channels] #(map assigner %))))

  {:author "James Elliott"}
  (:require [com.evocomputing.colors :as colors]))

(defn channel [offset]
  {:offset offset})

(defn- assign-channel [universe start-address raw-channel]

  "Defines a channel whose values are divided up into different ranges
  which perform different functions. After the channel type and DMX
  offset, pass a list of starting values and function specifications.

  The simplest form of specification is a keyword or string
  identifying the function type; this will be expanded into a
  variable-range (for keywords) or fixed-range (for strings) function
  of that type.

  For more complex functions, pass in a map containing the `:type`
  keyword and any other settings you need to make (e.g. `:label`,
  `:range`, `:var-label`), and the rest will be filled in for you.

  To skip a range, pass `nil` for its specification.

  The ranges need to be in order of increasing starting
  values, and the ending values for each will be figured out by
  context, e.g.

  ```
  (functions :strobe 40
             0 nil
             10 \"strobe-random\"
             20 :strobe)
  ```

  See the [online
  documentation](https://github.com/brunchboy/afterglow/blob/master/doc/fixture_definitions.adoc#function-channels)
  for more details and examples."
  {:doc/format :markdown}
  [chan-type offset & functions]
  {:pre (some? chan-type) (integer? offset) (<= 1 offset 512)}
  (let [chan-type (keyword chan-type)]
