anchor.diff:        permission: permission,
         node1_id: topic1.id,
         node2_id: topic2.id
  -    });
  -    Metamaps.Synapses.add(synapse);
  +    })
  +    Metamaps.Synapses.add(synapse)
   
       var mapping = new Metamaps.Backbone.Mapping({
  -      mappable_type: "Synapse",
  -      mappable_id: synapse.cid,
  -    });
  -    Metamaps.Mappings.add(mapping);
  -
  -    Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true);
  -  },
  -};
  +      mappable_type: 'Synapse',
  +      mappable_id: synapse.cid
  +    })
  +    Metamaps.Mappings.add(mapping)
  +
  +    Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true)
  +  }
  +}
  
positive.code: /*
   * Example tab-separated input:
   * Some fields will be ignored
   *
   * Topics								
   * Id	Name	Metacode	X	Y	Description	Link	User	Permission
   * 8	topic8	Action	-231	131			admin	commons
   * 5	topic	Action	-229	-131			admin	commons
   * 7	topic7.1	Action	-470	-55	hey		admin	commons
   * 2	topic2	Event	-57	-63			admin	commons
   * 1	topic1	Catalyst	-51	50			admin	commons
   * 6	topic6	Action	-425	63			admin	commons
   * 								
   * Synapses								
   * Topic1	Topic2	Category	Description	User	Permission		
   * 6	2	from-to		admin	commons		
   * 6	1	from-to		admin	commons		
   * 6	5	from-to		admin	commons		
   * 2	7	from-to		admin	commons		
   * 8	6	from-to		admin	commons		
   * 8	1	from-to		admin	commons		
   *
   */
  
  Metamaps.Import = {
  
negative.code:       TOPICS_NEED_HEADERS: 1,
        SYNAPSES_NEED_HEADERS: 2,
        TOPICS: 3,
        SYNAPSES: 4
      }
  
      // state & lines determine parser behaviour
      var state = STATES.UNKNOWN
      var lines = text.split(delim)
      var results = { topics: [], synapses: [] }
      var topicHeaders = []
      var synapseHeaders = []
  
      lines.forEach(function (line_raw, index) {
        var line = line_raw.split('\t')
        var noblanks = line.filter(function (elt) {
          return elt !== ''
        })
        switch (state) {
          case STATES.UNKNOWN:
            if (noblanks.length === 0) {
              state = STATES.UNKNOWN
              break
            } else if (noblanks.length === 1 && self.simplify(line[0]) === 'topics') {
              state = STATES.TOPICS_NEED_HEADERS
              break
            } else if (noblanks.length === 1 && self.simplify(line[0]) === 'synapses') {
              state = STATES.SYNAPSES_NEED_HEADERS
              break
            }
            state = STATES.TOPICS_NEED_HEADERS
            // FALL THROUGH - if we're not sure what to do, pretend
            // we're on the TOPICS_NEED_HEADERS state and parse some headers
  
          case STATES.TOPICS_NEED_HEADERS: // eslint-disable-line
            if (noblanks.length < 2) {
              self.abort('Not enough topic headers on line ' + index)
              state = STATES.ABORT
            }
            topicHeaders = line.map(function (header, index) {
              return header.toLowerCase().replace('description', 'desc')
            })
            state = STATES.TOPICS
            break
  
          case STATES.SYNAPSES_NEED_HEADERS:
            if (noblanks.length < 2) {
              self.abort('Not enough synapse headers on line ' + index)
              state = STATES.ABORT
            }
            synapseHeaders = line.map(function (header, index) {
              return header.toLowerCase().replace('description', 'desc')
            })
            state = STATES.SYNAPSES
            break
  
          case STATES.TOPICS:
            if (noblanks.length === 0) {
              state = STATES.UNKNOWN
            } else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
              state = STATES.TOPICS_NEED_HEADERS
            } else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
              state = STATES.SYNAPSES_NEED_HEADERS
            } else {
              var topic = {}
              line.forEach(function (field, index) {
                var header = topicHeaders[index]
                if (self.topicWhitelist.indexOf(header) === -1) return
                topic[header] = field
                if (['id', 'x', 'y'].indexOf(header) !== -1) {
                  topic[header] = parseInt(topic[header])
                } // if
              })
              results.topics.push(topic)
            }
            break
  
          case STATES.SYNAPSES:
            if (noblanks.length === 0) {
              state = STATES.UNKNOWN
            } else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
              state = STATES.TOPICS_NEED_HEADERS
            } else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
              state = STATES.SYNAPSES_NEED_HEADERS
            } else {
              var synapse = {}
              line.forEach(function (field, index) {
                var header = synapseHeaders[index]
                if (self.synapseWhitelist.indexOf(header) === -1) return
                synapse[header] = field
                if (['id', 'topic1', 'topic2'].indexOf(header) !== -1) {
                  synapse[header] = parseInt(synapse[header])
                } // if
              })
              results.synapses.push(synapse)
            }
            break
          case STATES.ABORT:
  
          default:
            self.abort('Invalid state while parsing import data. Check code.')
            state = STATES.ABORT
        }
      })
  
      if (state === STATES.ABORT) {
        return false
      } else {
        return results
      }
    },
  
    importTopics: function (parsedTopics) {
      var self = Metamaps.Import
  
      // up to 25 topics: scale 100
      // up to 81 topics: scale 200
      // up to 169 topics: scale 300
      var scale = Math.floor((Math.sqrt(parsedTopics.length) - 1) / 4) * 100
      if (scale < 100) scale = 100
      var autoX = -scale
      var autoY = -scale
  
      parsedTopics.forEach(function (topic) {
        var x, y
        if (topic.x && topic.y) {
          x = topic.x
          y = topic.y
        } else {
          x = autoX
          y = autoY
          autoX += 50
          if (autoX > scale) {
            autoY += 50
            autoX = -scale
          }
        }
  
        self.createTopicWithParameters(
          topic.name, topic.metacode, topic.permission,
          topic.desc, topic.link, x, y, topic.id
        )
      })
    },
  
    importSynapses: function (parsedSynapses) {
      var self = Metamaps.Import
  
      parsedSynapses.forEach(function(synapse) {
        // only createSynapseWithParameters once both topics are persisted
        var topic1 = Metamaps.Topics.get(self.cidMappings[synapse.topic1])
        var topic2 = Metamaps.Topics.get(self.cidMappings[synapse.topic2])
        if (!topic1 || !topic2) {
          console.error("One of the two topics doesn't exist!")
          console.error(synapse)
          return true
        }
  
        var synapse_created = false
        topic1.once('sync', function () {
          if (topic1.id && topic2.id && !synapse_created) {
            synapse_created = true
            self.createSynapseWithParameters(
              synapse.desc, synapse.category, synapse.permission,
              topic1, topic2
            )
          } // if
        })
        topic2.once('sync', function () {
          if (topic1.id && topic2.id && !synapse_created) {
            synapse_created = true
            self.createSynapseWithParameters(
              synapse.desc, synapse.category, synapse.permission,
              topic1, topic2
            )
          } // if
        })
      })
    },
  
    createTopicWithParameters: function (name, metacode_name, permission, desc,
      link, xloc, yloc, import_id) {
      var self = Metamaps.Import
      $(document).trigger(Metamaps.Map.events.editedByActiveMapper)
      var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null
      if (metacode === null) return console.error('metacode not found')
  
      var topic = new Metamaps.Backbone.Topic({
        name: name,
        metacode_id: metacode.id,
        permission: permission || Metamaps.Active.Map.get('permission'),
        desc: desc,
        link: link
      })
      Metamaps.Topics.add(topic)
      self.cidMappings[import_id] = topic.cid
  
      var mapping = new Metamaps.Backbone.Mapping({
        xloc: xloc,
        yloc: yloc,
        mappable_id: topic.cid,
        mappable_type: 'Topic'
      })
      Metamaps.Mappings.add(mapping)
  
      // this function also includes the creation of the topic in the database
      Metamaps.Topic.renderTopic(mapping, topic, true, true)
  
      Metamaps.Famous.viz.hideInstructions()
    },
  
    createSynapseWithParameters: function (description, category, permission,
      topic1, topic2) {
      var node1 = topic1.get('node')
      var node2 = topic2.get('node')
  
      if (!topic1.id || !topic2.id) {
        console.error('missing topic id when creating synapse')
        return
      } // if
  
      var synapse = new Metamaps.Backbone.Synapse({
        desc: description,
  