Inject functions to set or get graph data.

@param {Object} funcs reference
@param {Object} graph
494151
function injectAccessors (funcs, graph) {
  if (no(graph.data)) graph.data = {}

  funcs['this.graph.data'] = function () { return graph.data }

  /**
   * Inject accessor.
   *
   * @param {String} taskKey
   */

  function inject (taskKey) {
    var accessorName = null
    var taskName = graph.task[taskKey]

    /**
     * Accessor-like function.
     *
     * @param {*} data that JSON can serialize
     */

    function accessor (data) {
      // Behave like a setter if an argument is provided.
      if (arguments.length === 1) {
        var json = JSON.stringify(data)

        if (no(json)) {
          throw new Error('JSON do not serialize data:' + data)
        }

        graph.data[accessorName] = data
      }

      // Always behave also like a getter.
      return graph.data[accessorName]
    }

    if (regexAccessor.test(taskName)) {
      accessorName = taskName.substring(1)

      funcs[taskName] = accessor
    }
  }

  Object.keys(graph.task).forEach(inject)
}
512725
function evalTasks (funcs, task) {
  /**
  * Evaluate a single task and inject it.
  *
  * @param {String} taskKey
  */

  function inject (taskKey) {
    var taskName = task[taskKey]

    try {
      var e = eval(taskName) // eslint-disable-line

      if (typeof e === 'function') {
        funcs[taskName] = e
      } else {
        funcs[taskName] = function () { return e }
      }
    } catch (err) {
      var msg = 'Task not compiled: ' + taskName + ' [' + taskKey + ']' + err
      throw new Error(msg)
    }
  }

  Object.keys(task)
    .filter(reserved(task))
    .filter(dflowDSL(task))
    .filter(alreadyDefined(funcs, task))
    .forEach(inject)
}
1144665
function _newGraphSONMapperSync() {
        var builder = Tinkerpop.GraphSONMapper.build();
        builder.embedTypes(true);
        var mapper = builder.create();
        return mapper;
    }
1258199
function(func,factor) {
		return function() {

			/* globals setTimeout: false */

			var args = Array.prototype.slice.call(arguments),
				cb;
			while (typeof args.slice(-1)[0] === 'function') {
				cb = args.pop();
			}
			if (factor === false) {
				return cb(func.apply(this._inst,args));
			}
			setTimeout(function() {
				var r = [func.apply(this._inst,args)];
				if (nodeStyle) {
					r.unshift(null);
				}
				cb.apply(this, r);
			}.bind(this),Math.floor(Math.random() * factor) + 1);
		};
	}
1132529
function injectReferences (funcs, task) {
  /**
   * Inject task.
   *
   * @param {String} taskKey
   */

  function inject (taskKey) {
    var referenceName = null
    var referencedFunction = null
    var taskName = task[taskKey]

    /**
     * Inject reference.
     */

    function reference () {
      return referencedFunction
    }

    if (regexReference.test(taskName)) {
      referenceName = taskName.substring(1)

      if (typeof funcs[referenceName] === 'function') {
        referencedFunction = funcs[referenceName]
      } else {
        referencedFunction = walkGlobal(referenceName)
      }

      if (typeof referencedFunction === 'function') {
        funcs[taskName] = reference
      }
    }
  }

  Object.keys(task).forEach(inject)
}
185338
def _wrap_in_place(func):  # noqa: D202
        """"""

        @wraps(func)
        def wrapper(graph, *args, **kwargs):
            """Apply the enclosed function and returns the graph."""
            func(graph, *args, **kwargs)
            return graph

        return wrapper
1285608
function ( func, slices, stacks ) {

	BufferGeometry.call( this );

	this.type = '';

	this.parameters = {
		func: func,
		slices: slices,
		stacks: stacks
	};

	// buffers

	var indices = [];
	var vertices = [];
	var normals = [];
	var uvs = [];

	var EPS = 0.00001;

	var normal = new Vector3();

	var p0 = new Vector3(), p1 = new Vector3();
	var pu = new Vector3(), pv = new Vector3();

	var i, j;

	if ( func.length < 3 ) {

		console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' );

	}

	// generate vertices, normals and uvs

	var sliceCount = slices + 1;

	for ( i = 0; i <= stacks; i ++ ) {

		var v = i / stacks;

		for ( j = 0; j <= slices; j ++ ) {

			var u = j / slices;

			// vertex

			func( u, v, p0 );
			vertices.push( p0.x, p0.y, p0.z );

			// normal

			// approximate tangent vectors via finite differences

			if ( u - EPS >= 0 ) {

				func( u - EPS, v, p1 );
				pu.subVectors( p0, p1 );

			} else {

				func( u + EPS, v, p1 );
				pu.subVectors( p1, p0 );

			}

			if ( v - EPS >= 0 ) {

				func( u, v - EPS, p1 );
				pv.subVectors( p0, p1 );

			} else {

				func( u, v + EPS, p1 );
				pv.subVectors( p1, p0 );

			}

			// cross product of tangent vectors returns surface normal

			normal.crossVectors( pu, pv ).normalize();
			normals.push( normal.x, normal.y, normal.z );

			// uv

			uvs.push( u, v );

		}

	}

	// generate indices

	for ( i = 0; i < stacks; i ++ ) {

		for ( j = 0; j < slices; j ++ ) {

			var a = i * sliceCount + j;
			var b = i * sliceCount + j + 1;
			var c = ( i + 1 ) * sliceCount + j + 1;
			var d = ( i + 1 ) * sliceCount + j;

			// faces one and two

			indices.push( a, b, d );
			indices.push( b, c, d );

		}

	}

	// build geometry

	this.setIndex( indices );
	this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
	this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
	this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );

}
666964
public void initFunctionFromProperties(String mappedTfName, DifferentialFunction on, Map<String, AttrValue> attributesForNode, NodeDef node, GraphDef graph) {
        val properties = on.mappingsForFunction();
        val tfProperties = properties.get(mappedTfName);
        val fields = DifferentialFunctionClassHolder.getInstance().getFieldsForFunction(on);
        val attributeAdapters = on.attributeAdaptersForFunction();

        // if there's no properties announced for this function - just return
        if (tfProperties == null)
            return;

        //Can't execute in just any order: sometimes there are dependencies between attribute mappings
        //For example, conv2d strides depend on data format -> need to map data format before mapping strides
        //Solution: map nodes without adapters before nodes with adapters. This doesn't guarantee we'll always be
        // mapping in the right order (for example, we might have adapter(x) depends on adapter(y)) but it should catch most cases
        Map<String,PropertyMapping> map;
        if(attributeAdapters == null || !attributeAdapters.containsKey(mappedTfName)) {
            map = tfProperties;
        } else {
            map = new LinkedHashMap<>();
            for (Map.Entry<String, PropertyMapping> e : tfProperties.entrySet()) {
                if (!attributeAdapters.get(mappedTfName).containsKey(e.getKey())) {
                    //No adapter for this attribute
                    map.put(e.getKey(), e.getValue());
                }
            }
            for (Map.Entry<String, PropertyMapping> e : tfProperties.entrySet()) {
                if (!map.containsKey(e.getKey())) {
                    //Not added on first pass -> must have attribute mapper
                    map.put(e.getKey(), e.getValue());
                }
            }
        }

        for(Map.Entry<String,PropertyMapping> entry : map.entrySet()){
            val tfAttrName = entry.getValue().getTfAttrName();
            val currentField = fields.get(entry.getKey());

            AttributeAdapter adapter = null;
            if(attributeAdapters != null && !attributeAdapters.isEmpty()) {
                val mappers = attributeAdapters.get(mappedTfName);
                val adapterFor = mappers.get(entry.getKey());
                adapter = adapterFor;
            }


            if(tfAttrName != null) {
                if(currentField == null) {
                    continue;
                }

                if(attributesForNode.containsKey(tfAttrName)) {
                    val attr = attributesForNode.get(tfAttrName);
                    switch (attr.getValueCase()) {
                        case B:
                            if (adapter != null) {
                                adapter.mapAttributeFor(attr.getB(), currentField, on);
                            }
                            break;
                        case F: break;
                        case FUNC: break;
                        case S:
                            val setString = attr.getS().toStringUtf8();
                            if(adapter != null) {
                                adapter.mapAttributeFor(setString,currentField,on);
                            }
                            else
                                on.setValueFor(currentField,setString);
                            break;
                        case I:
                            val setInt = (int) attr.getI();
                            if(adapter != null) {
                                adapter.mapAttributeFor(setInt,currentField,on);
                            }
                            else
                                on.setValueFor(currentField,setInt);
                            break;
                        case SHAPE:
                            val shape = attr.getShape().getDimList();
                            int[] dimsToSet = new int[shape.size()];
                            for(int i = 0; i < dimsToSet.length; i++) {
                                dimsToSet[i] = (int) shape.get(i).getSize();
                            }

                            if(adapter != null) {
                                adapter.mapAttributeFor(dimsToSet,currentField,on);
                            }

                            else
                                on.setValueFor(currentField,dimsToSet);
                            break;
                        case VALUE_NOT_SET:break;
                        case PLACEHOLDER: break;
                        case LIST:
                            val setList = attr.getList();
                            if(!setList.getIList().isEmpty()) {
                                val intList = Ints.toArray(setList.getIList());
                                if(adapter != null) {
                                    adapter.mapAttributeFor(intList,currentField,on);
                                }
                                else
                                    on.setValueFor(currentField,intList);
                            }
                            else if(!setList.getBList().isEmpty()) {
                                break;
                            }
                            else if(!setList.getFList().isEmpty()) {
                                val floats = Floats.toArray(setList.getFList());
                                if(adapter != null) {
                                    adapter.mapAttributeFor(floats,currentField,on);
                                }

                                else
                                    on.setValueFor(currentField,floats);
                                break;
                            }
                            else if(!setList.getFuncList().isEmpty()) {
                                break;
                            }
                            else if(!setList.getTensorList().isEmpty()) {
                                break;
                            }
                            break;
                        case TENSOR:
                            val tensorToGet = TFGraphMapper.getInstance().mapTensorProto(attr.getTensor());
                            if(adapter != null) {
                                adapter.mapAttributeFor(tensorToGet,currentField,on);
                            }
                            else
                                on.setValueFor(currentField,tensorToGet);
                            break;
                        case TYPE:
                            if (adapter != null) {
                                adapter.mapAttributeFor(attr.getType(), currentField, on);
                            }
                            break;
                    }
                }
            }

            else if(entry.getValue().getTfInputPosition() != null) {


                int position = entry.getValue().getTfInputPosition();
                if(position < 0) {
                    position += node.getInputCount();
                }

                val inputFromNode = TFGraphMapper.getInstance().getNodeWithNameFromGraph(graph,node.getInput(position));
                INDArray tensor = inputFromNode != null ? TFGraphMapper.getInstance().getNDArrayFromTensor("value",inputFromNode,graph) : null;
                if(tensor == null) {
                    tensor = on.getSameDiff().getArrForVarName(getNodeName(node.getInput(position)));
                }


                if(tensor != null) {
                    //use adapter instead of direct mapping just like above
                    if(adapter != null) {
                        adapter.mapAttributeFor(tensor,currentField,on);
                    }
                    else {
                        if(currentField.getType().equals(int[].class)) {
                            on.setValueFor(currentField,tensor.data().asInt());
                        }
                        else if(currentField.getType().equals(double[].class)) {
                            on.setValueFor(currentField,tensor.data().asDouble());

                        }
                        else if(currentField.getType().equals(float[].class)) {
                            on.setValueFor(currentField,tensor.data().asFloat());

                        }
                        else if(currentField.getType().equals(INDArray.class)) {
                            on.setValueFor(currentField,tensor);
                        }
                        else if(currentField.getType().equals(int.class)) {
                            on.setValueFor(currentField,tensor.getInt(0));
                        }
                        else if(currentField.getType().equals(double.class)) {
                            on.setValueFor(currentField,tensor.getDouble(0));
                        }
                        else if(currentField.getType().equals(float.class)) {
                            on.setValueFor(currentField,tensor.getFloat(0));
                        }
                    }
                } else {
                    on.getSameDiff().addPropertyToResolve(on,entry.getKey());
                }
            }
        }
    }
945457
function saveGraphSON(graph, filename, callback) {
        var FileOutputStream = Tinkerpop.autoImport('FileOutputStream');
        var stream = new FileOutputStream(filename);
        return Tinkerpop.GraphSONWriter.buildP()
            .then(function (builder) {
            return _newGraphSONMapper()
                .then(function (mapper) { return builder.mapperP(mapper); });
        })
            .then(function (builder) { return builder.createP(); })
            .then(function (writer) { return writer.writeGraphP(stream, graph); })
            .then(function () { return graph; })
            .nodeify(callback);
    }
544754
function Task(func) {
        _super.call(this);
        if (!TypeUtils.isNullOrUndefined(func)) {
            if (typeof func !== "function") {
                throw "'func' must be a function!";
            }
        }
        this._FUNC = func;
        this.updateStatus(TaskStatus.Created);
    }
1148355
function transformFunction(node) {
  var nameNode = node.nodes[0];
  var paramsNodes = node.nodes[1] ? node.nodes[1].nodes : [];
  node.name = nameNode.value;
  if (node.name) {
    node.item('functions')[node.name] = node;
  }
  node.params = [];
  node.paramIndex = {};

  var paramTags = node.paramTags;
  // for functions assigned to variables, paramTags are in parent --
  // i.e. '/* @param a */ var parent = function (a) {}'
  if (node.paramTags === undefined && node.parent &&
      node.parent.type === 'assign' && node.parent.paramTags) {
    paramTags = node.parent.paramTags;
  }
  node.item('paramTags', paramTags);

  if (node.copyTags) {
    var tagSource = node.item('functions')[node.copyTags];
    if (tagSource) {
      if (!node.description && tagSource.description) {
        node.description = tagSource.description;
      }
      if (!paramTags && tagSource.item('paramTags')) {
        paramTags = tagSource.item('paramTags');
      }
    }
  }

  paramsNodes.forEach(function (paramNode, i) {
    var param = {
      name: paramNode.value
    };
    node.paramIndex[param.name] = i;
    if (paramTags) {
      if (paramTags[param.name]) {
        var tagValue = paramTags[param.name];
    // if (node.item('path') === 'cli') {
    //   console.log(tagValue)
    // }
        Object.keys(tagValue).forEach(function (key, i) {
          if (key !== 'name') {
            param[key] = tagValue[key];
          }
        });
      }
    }
    node.params.push(param);
  });
    // if (node.item('path') === 'cli') {
    //   console.log(node.params)
    // }
}
1186218
function(mapping, notYetSubstitutedFact, causedBy, graphs) {
        var subject, predicate, object, substitutedFact;
        if (mapping == {}) {
            return notYetSubstitutedFact;
        }
        subject = this.substituteElementVariablesWithMapping(notYetSubstitutedFact.subject, mapping);
        predicate = this.substituteElementVariablesWithMapping(notYetSubstitutedFact.predicate, mapping);
        object = this.substituteElementVariablesWithMapping(notYetSubstitutedFact.object, mapping);        

        substitutedFact = new Fact(predicate, subject, object, [], false);

        if (causedBy) {
            substitutedFact.causedBy = causedBy;
            substitutedFact.explicit = false;
        }

        if (graphs) {
            substitutedFact.graphs = graphs;
        }

        return substitutedFact;
    }
544423
function factoryGraph(ParentClass){if(!ParentClass){var ParentClass=function ParentClass(){_classCallCheck(this,ParentClass)}}/**
   * Class to inherit. Class with methods for control links in graph.
   * Must be completed for adaptation to a particular database.
   * 
   * @class
   * @description `import { Graph } from 'ancient-graph';`
   */var Graph=function(_ParentClass){_inherits(Graph,_ParentClass);/**
     * Construct new graph and checks for required adaptation methods.
     * @throws {Error} if the adapter methods is not complete
     * 
     * @param {} collection - A pointer to the collection dannymineobhodimye daapteru to work with the graph. This may be a connection to the SQL database and table name, for example, or a collection of Mongo. 
     * @param {Object.<string, string>} fields - Comparison of the data in the collection of data in the graph. It is necessary for the adapter.
     * @param {Object} [config] - Additional config.
     * @param {Object} [config.aliases]
     * @param {String} [config.aliases.$]
     */function Graph(collection,fields,config){_classCallCheck(this,Graph);var _this=_possibleConstructorReturn(this,(Graph.__proto__||Object.getPrototypeOf(Graph)).apply(this,arguments));_this.collection=collection;_this.fields=fields;if((typeof config==='undefined'?'undefined':_typeof(config))!='object')var config={};_this.config=config;if(_typeof(config.aliases)!='object')config.aliases={};for(var f in fields){if(!config.aliases[f])config.aliases[f]=f}_this.config._aliases={};for(var a in _this.config.aliases){_this.config._aliases[_this.config.aliases[a]]=a}if(_this.insert==Graph.prototype.insert){throw new Error('Method `insert` is not adapted.')}if(_this.update==Graph.prototype.update){throw new Error('Method `update` is not adapted.')}if(_this.remove==Graph.prototype.remove){throw new Error('Method `remove` is not adapted.')}if(_this.query==Graph.prototype.query){throw new Error('Method `query` is not adapted.')}if(_this.options==Graph.prototype.options){throw new Error('Method `options` is not adapted.')}if(_this.fetch==Graph.prototype.fetch){throw new Error('Method `fetch` is not adapted.')}if(_this.get==Graph.prototype.get){throw new Error('Method `get` is not adapted.')}if(_this.each==Graph.prototype.each){throw new Error('Method `each` is not adapted.')}if(_this.map==Graph.prototype.map){throw new Error('Method `map` is not adapted.')}if(_this.count==Graph.prototype.count){throw new Error('Method `count` is not adapted.')}if(_this.on==Graph.prototype.on){throw new Error('Method `on` is not adapted.')}return _this}/**
     * Should insert new link into graph.
     * If the database allows, it is recommended to return a synchronous result. This can be useful in your application. But for writing generic code, it is recommended to only use the callback result.
     * 
     * @param {Link} link
     * @param {Graph~insertCallback} [callback]
     * @param {Object} [context]
     * @return {string} [id]
     */_createClass(Graph,[{key:'insert',value:function insert(link,callback,context){}/**
     * Optional callback. If present, called with an error object as the first argument and, if no error, the unique id of inserted link as the second.
     *
     * @callback Graph~insertCallback
     * @param {Error} [error]
     * @param {string} [id]
     *//**
     * Should update to new state of modifier object link by unique id or by link query object.
     * If the database allows, it is recommended to return a synchronous result. This can be useful in your application. But for writing generic code, it is recommended to only use the callback result.
     * 
     * @param {string|LinkSelector} selector
     * @param {LinkModifier} modifier
     * @param {Graph~updateCallback} [callback]
     * @param {Object} [context]
     * @return {number} [count]
     */},{key:'update',value:function update(selector,modifier,callback,context){}/**
     * Optional callback. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
     *
     * @callback Graph~updateCallback
     * @param {Error} [error]
     * @param {number} [count]
     *//**
     * Should remove link by unique id or by link query object.
     * 
     * @param {string|LinkSelector} selector
     * @param {Graph~removeCallback} [callback]
     * @param {Object} [context]
     */},{key:'remove',value:function remove(selector,callback,context){}/**
     * Optional callback. If present, called with an error object as the first argument.
     *
     * @callback Graph~removeCallback
     * @param {Error} [error]
     * @param {number} [count]
     *//**
     * Should generate adapter for database query for links search by unique id or by link query object.
     * 
     * @param {string|LinkSelector} selector
     * @return {*} query
     */},{key:'query',value:function query(selector){}/**
     * Should generate adapter for database options. 
     * 
     * @param {Object} [options]
     * @return {*} options - a options suitable for the database
     */},{key:'options',value:function options(_options){}/**
     * Find and all matching links as an Array.
     * 
     * @param {string|LinkSelector} selector
     * @param {SelectOptions} [options]
     * @param {Graph~fetchCallback} [callback]
     * @return {Link[]} links - result links objects in array
     */},{key:'fetch',value:function fetch(selector,options,callback){}/**
     * Optional callback. If present, called with an error object as the first argument and, if no error, the result links objects in array.
     *
     * @callback Graph~fetchCallback
     * @param {Error} [error]
     * @param {Link[]} [links]
     *//**
     * Get one first matching link.
     * 
     * @param {string|LinkSelector} selector
     * @param {SelectOptions} [options]
     * @param {Graph~getCallback} [callback]
     * @return {Link} link - result link object
     */},{key:'get',value:function get(selector,options,callback){}/**
     * Optional callback. If present, called with an error object as the first argument and, if no error, the result link object.
     *
     * @callback Graph~getCallback
     * @param {Error} [error]
     * @param {Link} [link]
     *//**
     * Should call callback once for each matching document, sequentially and synchronously.
     * 
     * @param {string|LinkSelector} selector
     * @param {SelectOptions} [options]
     * @param {Graph~eachCallback} [callback]
     */},{key:'each',value:function each(selector,options,callback){}/**
     * @callback Graph~eachCallback
     * @param {Link} [link]
     *//**
     * Should map callback over all matching documents. Returns an Array.
     * 
     * @param {string|LinkSelector} selector
     * @param {SelectOptions} [options]
     * @param {Graph~mapCallback} [callback]
     * @return {Array} results
     */},{key:'map',value:function map(selector,options,callback){}/**
     * @callback Graph~mapCallback
     * @param {Link} [link]
     * @return {*} result
     *//**
     * Should count all matching documents.
     * 
     * @param {string|LinkSelector} selector
     * @param {SelectOptions} [options]
     * @param {Graph~countCallback} [callback]
     * @return {number} [count]
     */},{key:'count',value:function count(selector,options,callback){}/**
     * @callback Graph~countCallback
     * @param {Error} [error]
     * @param {number} [count]
     *//**
     * Should subscribe to the events: link, unlink, insert, update, remove.
     * 
     * @param {string} event - One event name
     * @param {Graph~onCallback} callback
     * @returns {Function} Stops event subscription.
     * @example
     * var counter = 0;
     * var stop = graph.on('update', (oldData, newData) => {
     *   if (oldData.id == '1') console.log(oldData.id, 'is changed');
     *   counter++;
     *   if (counter == 3) stop();
     * });
     */},{key:'on',value:function on(event,callback){}/**
     * @callback Graph~onCallback
     * @param {Link} [oldLink] - can be undefined on link and insert events
     * @param {Link} [newLink] - can be undefined on unlink and remove events
     * @param {Object} [context] - additional app information, such as context.userId
     */}]);return Graph}(ParentClass);;return Graph}
735013
public void initFunctionFromProperties(DifferentialFunction on, Map<String, AttrValue> attributesForNode, NodeDef node, GraphDef graph) {
        initFunctionFromProperties(on.tensorflowName(),on,attributesForNode,node,graph);
    }
322189
function graphFromStatements (rdf, statements) {
  let graph = rdf.graph()

  statements.forEach((st) => { graph.addStatement(st) })

  return graph
}
112310
function forEachEdge(graph, type, callback) {
  if (graph.size === 0)
    return;

  if (type === 'mixed' || type === graph.type) {
    graph._edges.forEach((data, key) => {

      const {attributes, source, target} = data;

      callback(
        key,
        attributes,
        source.key,
        target.key,
        source.attributes,
        target.attributes
      );
    });
  }
  else {
    const mask = type === 'undirected';

    graph._edges.forEach((data, key) => {
      if ((data instanceof UndirectedEdgeData) === mask) {

        const {attributes, source, target} = data;

        callback(
          key,
          attributes,
          source.key,
          target.key,
          source.attributes,
          target.attributes
        );
      }
    });
  }
}
1226894
function decorateFunctions(node) {
    var i;
    var funcNode = getCommentedFunctionNode(node);
    if (!funcNode || !funcNode.jsdoc) {
        return;
    }

    // Pair up the function params with the JSDoc params (if they exist)
    funcNode.node.params.forEach(function(param) {
        for (i = 0; i < funcNode.jsdoc.params.length; i++) {
            if (!funcNode.jsdoc.params[i].type) {
                continue;
            }

            // If default options are set keep the assignment in flow
            if (param.type === 'AssignmentPattern') {
                if (funcNode.jsdoc.params[i].name === param.left.name) {
                    // Remove ? if default value is set
                    var type = funcNode.jsdoc.params[i].type.replace(/^\?/, '');

                    param.update(
                        param.left.source() + ": " + type + ' = ' + param.right.source()
                    );
                }
            } else {
                if (funcNode.jsdoc.params[i].name === param.name) {
                    param.update(
                        param.source() + ": " + funcNode.jsdoc.params[i].type
                    );
                }
            }
        }
    });

    // Pair up the return value if possible
    // we only support 1 return type currently
    var returnDoc = funcNode.jsdoc.returns[0];
    if (returnDoc && returnDoc.type && funcNode.node.body) {
        if (funcNode.node.type === "ArrowFunctionExpression") {
            // we can't just add this to the end as it will then appear AFTER the =>
            // whereas we actually want it BEFORE the =>
            // Sadly, there isn't a nice way to access the bit before the =>. We do
            // however know that the node source is the entire function, and the node
            // body is the stuff between the { }. We can therefore grab the function
            // header portion and find/replace on the fat arrow.
            var funcHeader = funcNode.node.source().replace(funcNode.node.body.source(), "");
            var arrowIndex = funcHeader.lastIndexOf("=>");
            if (arrowIndex === -1) {
                // well this was unexpected...
                return;
            }
            // inject annotation before the arrow
            funcHeader = (
                funcHeader.slice(0, arrowIndex) + ": " + returnDoc.type + " " + funcHeader.slice(arrowIndex)
            );
            // replace the entire function to replace the header portion
            funcNode.node.update(
                funcHeader + funcNode.node.body.source()
            );
        }
        else {
            funcNode.node.body.update(
                ": " + returnDoc.type + " " + funcNode.node.body.source()
            );
        }
    }
}