change the spacing

change the spacing

--- app.coffee
+++ app.coffee
@@ -23,7 +23,7 @@
 if 'development' == app.get('env')
   app.use express.errorHandler()

-app.get '/',                         routes.backboneIndex
+app.get '/',                                 routes.backboneIndex
 app.get  '/past',                            routes.projectIndex
 #app.get  '/token',                           routes.tokenIndex
 #app.get  '/kanban/:projectId',               routes.kanbanIndex


Increase req and res stream timeouts to 3 minutes

--- app.coffee
+++ app.coffee
@@ -17,6 +17,15 @@
 app = express()

 app.use Metrics.http.monitor(logger)
+
+# Compile requests can take longer than the default two
+# minutes (including file download time), so bump up the
+# timeout a bit.
+TIMEOUT = threeMinutes = 3 * 60 * 1000
+app.use (req, res, next) ->
+	req.setTimeout TIMEOUT
+	res.setTimeout TIMEOUT
+	next()

 app.post   "/project/:project_id/compile", bodyParser.json(limit: "5mb"), CompileController.compile
 app.delete "/project/:project_id", CompileController.clearCache


take room params

take room params

--- app.coffee
+++ app.coffee
@@ -132,6 +132,7 @@
     payloadForwarder = (mountPath, toMessageType, enableBacklog) =>
       @app.post mountPath, (req,res) ->
         data = req.body
+        data.room = data.room || req.params.room
         return res.send(".room is required.") unless data.room
         io.sockets.in(data.room).emit( toMessageType, data)
         self.backlog.append(data.room, toMessageType, data) if enableBacklog


Removed unused file

Removed unused file

--- lib/stomp.coffee
+++ lib/stomp.coffee
@@ -1,527 +0,0 @@
-
-# **STOMP Over Web Socket** is a JavaScript STOMP Client using
-# [HTML5 Web Sockets API](http://www.w3.org/TR/websockets).
-#
-# * Copyright (C) 2010-2012 [Jeff Mesnil](http://jmesnil.net/)
-# * Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com)
-#
-# This library supports:
-#
-# * [STOMP 1.0](http://stomp.github.com/stomp-specification-1.0.html)
-# * [STOMP 1.1](http://stomp.github.com/stomp-specification-1.1.html)
-#
-# The library is accessed through the `Stomp` object that is set on the `window`
-# when running in a Web browser.
-
-###
-   Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0
-
-   Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/)
-   Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com)
-###
-
-# Define constants for bytes used throughout the code.
-Byte =
-  # LINEFEED byte (octet 10)
-  LF: '\x0A'
-  # NULL byte (octet 0)
-  NULL: '\x00'
-
-# ##[STOMP Frame](http://stomp.github.com/stomp-specification-1.1.html#STOMP_Frames) Class
-class Frame
-  # Frame constructor
-  constructor: (@command, @headers={}, @body='') ->
-
-  # Provides a textual representation of the frame
-  # suitable to be sent to the server
-  toString: ->
-    lines = [@command]
-    skipContentLength = if (@headers['content-length'] == false) then true else false
-    delete @headers['content-length'] if skipContentLength
-
-    for own name, value of @headers
-      lines.push("#{name}:#{value}")
-    if @body && !skipContentLength
-      lines.push("content-length:#{Frame.sizeOfUTF8(@body)}")
-    lines.push(Byte.LF + @body)
-    return lines.join(Byte.LF)
-
-  # Compute the size of a UTF-8 string by counting its number of bytes
-  # (and not the number of characters composing the string)
-  @sizeOfUTF8: (s)->
-    if s
-      encodeURI(s).match(/%..|./g).length
-    else
-      0
-
-  # Unmarshall a single STOMP frame from a `data` string
-  unmarshallSingle= (data) ->
-    # search for 2 consecutives LF byte to split the command
-    # and headers from the body
-    divider = data.search(///#{Byte.LF}#{Byte.LF}///)
-    headerLines = data.substring(0, divider).split(Byte.LF)
-    command = headerLines.shift()
-    headers = {}
-    # utility function to trim any whitespace before and after a string
-    trim= (str) ->
-      str.replace(/^\s+|\s+$/g,'')
-    # Parse headers in reverse order so that for repeated headers, the 1st
-    # value is used
-    for line in headerLines.reverse()
-      idx = line.indexOf(':')
-      headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1))
-    # Parse body
-    # check for content-length or  topping at the first NULL byte found.
-    body = ''
-    # skip the 2 LF bytes that divides the headers from the body
-    start = divider + 2
-    if headers['content-length']
-      len = parseInt headers['content-length']
-      body = ('' + data).substring(start, start + len)
-    else
-      chr = null
-      for i in [start...data.length]
-        chr = data.charAt(i)
-        break if chr is Byte.NULL
-        body += chr
-    return new Frame(command, headers, body)
-
-  # Split the data before unmarshalling every single STOMP frame.
-  # Web socket servers can send multiple frames in a single websocket message.
-  # If the message size exceeds the websocket message size, then a single
-  # frame can be fragmented across multiple messages.
-  #
-  # `datas` is a string.
-  #
-  # returns an *array* of Frame objects
-  @unmarshall: (datas) ->
-    # Ugly list comprehension to split and unmarshall *multiple STOMP frames*
-    # contained in a *single WebSocket frame*.
-    # The data is split when a NULL byte (followed by zero or many LF bytes) is
-    # found
-    frames = datas.split(///#{Byte.NULL}#{Byte.LF}*///)
-
-    r =
-      frames:  []
-      partial: ''
-    r.frames = (unmarshallSingle(frame) for frame in frames[0..-2])
-
-    # If this contains a final full message or just a acknowledgement of a PING
-    # without any other content, process this frame, otherwise return the
-    # contents of the buffer to the caller.
-    last_frame = frames[-1..][0]
-
-    if last_frame is Byte.LF or (last_frame.search ///#{Byte.NULL}#{Byte.LF}*$///) isnt -1
-      r.frames.push(unmarshallSingle(last_frame))
-    else
-      r.partial = last_frame
-    return r
-
-  # Marshall a Stomp frame
-  @marshall: (command, headers, body) ->
-    frame = new Frame(command, headers, body)
-    return frame.toString() + Byte.NULL
-
-# ##STOMP Client Class
-#
-# All STOMP protocol is exposed as methods of this class (`connect()`,
-# `send()`, etc.)
-class Client
-  constructor: (@ws) ->
-    @ws.binaryType = "arraybuffer"
-    # used to index subscribers
-    @counter = 0
-    @connected = false
-    # Heartbeat properties of the client
-    @heartbeat = {
-      # send heartbeat every 10s by default (value is in ms)
-      outgoing: 10000
-      # expect to receive server heartbeat at least every 10s by default
-      # (value in ms)
-      incoming: 10000
-    }
-    # maximum *WebSocket* frame size sent by the client. If the STOMP frame
-    # is bigger than this value, the STOMP frame will be sent using multiple
-    # WebSocket frames (default is 16KiB)
-    @maxWebSocketFrameSize = 16*1024
-    # subscription callbacks indexed by subscriber's ID
-    @subscriptions = {}
-    @partialData = ''
-
-  # ### Debugging
-  #
-  # By default, debug messages are logged in the window's console if it is defined.
-  # This method is called for every actual transmission of the STOMP frames over the
-  # WebSocket.
-  #
-  # It is possible to set a `debug(message)` method
-  # on a client instance to handle differently the debug messages:
-  #
-  #     client.debug = function(str) {
-  #         // append the debug log to a #debug div
-  #         $("#debug").append(str + "\n");
-  #     };
-  debug: (message) ->
-    window?.console?.log message
-
-  # Utility method to get the current timestamp (Date.now is not defined in IE8)
-  now= ->
-    if Date.now then Date.now() else new Date().valueOf
-
-  # Base method to transmit any stomp frame
-  _transmit: (command, headers, body) ->
-    out = Frame.marshall(command, headers, body)
-    @debug? ">>> " + out
-    # if necessary, split the *STOMP* frame to send it on many smaller
-    # *WebSocket* frames
-    while(true)
-      if out.length > @maxWebSocketFrameSize
-        @ws.send(out.substring(0, @maxWebSocketFrameSize))
-        out = out.substring(@maxWebSocketFrameSize)
-        @debug? "remaining = " + out.length
-      else
-        return @ws.send(out)
-
-  # Heart-beat negotiation
-  _setupHeartbeat: (headers) ->
-    return unless headers.version in [Stomp.VERSIONS.V1_1, Stomp.VERSIONS.V1_2]
-
-    # heart-beat header received from the server looks like:
-    #
-    #     heart-beat: sx, sy
-    [serverOutgoing, serverIncoming] = (parseInt(v) for v in headers['heart-beat'].split(","))
-
-    unless @heartbeat.outgoing == 0 or serverIncoming == 0
-      ttl = Math.max(@heartbeat.outgoing, serverIncoming)
-      @debug? "send PING every #{ttl}ms"
-      # The `Stomp.setInterval` is a wrapper to handle regular callback
-      # that depends on the runtime environment (Web browser or node.js app)
-      @pinger = Stomp.setInterval ttl, =>
-        @ws.send Byte.LF
-        @debug? ">>> PING"
-
-    unless @heartbeat.incoming == 0 or serverOutgoing == 0
-      ttl = Math.max(@heartbeat.incoming, serverOutgoing)
-      @debug? "check PONG every #{ttl}ms"
-      @ponger = Stomp.setInterval ttl, =>
-        delta = now() - @serverActivity
-        # We wait twice the TTL to be flexible on window's setInterval calls
-        if delta > ttl * 2
-          @debug? "did not receive server activity for the last #{delta}ms"
-          @ws.close()
-
-  # parse the arguments number and type to find the headers, connectCallback and
-  # (eventually undefined) errorCallback
-  _parseConnect: (args...) ->
-    headers = {}
-    switch args.length
-      when 2
-        [headers, connectCallback] = args
-      when 3
-        if args[1] instanceof Function
-          [headers, connectCallback, errorCallback] = args
-        else
-          [headers.login, headers.passcode, connectCallback] = args
-      when 4
-        [headers.login, headers.passcode, connectCallback, errorCallback] = args
-      else
-        [headers.login, headers.passcode, connectCallback, errorCallback, headers.host] = args
-
-    [headers, connectCallback, errorCallback]
-
-  # [CONNECT Frame](http://stomp.github.com/stomp-specification-1.1.html#CONNECT_or_STOMP_Frame)
-  #
-  # The `connect` method accepts different number of arguments and types:
-  #
-  # * `connect(headers, connectCallback)`
-  # * `connect(headers, connectCallback, errorCallback)`
-  # * `connect(login, passcode, connectCallback)`
-  # * `connect(login, passcode, connectCallback, errorCallback)`
-  # * `connect(login, passcode, connectCallback, errorCallback, host)`
-  #
-  # The errorCallback is optional and the 2 first forms allow to pass other
-  # headers in addition to `client`, `passcode` and `host`.
-  connect: (args...) ->
-    out = @_parseConnect(args...)
-    [headers, @connectCallback, errorCallback] = out
-    @debug? "Opening Web Socket..."
-    @ws.onmessage = (evt) =>
-      data = if typeof(ArrayBuffer) != 'undefined' and evt.data instanceof ArrayBuffer
-        # the data is stored inside an ArrayBuffer, we decode it to get the
-        # data as a String
-        arr = new Uint8Array(evt.data)
-        @debug? "--- got data length: #{arr.length}"
-        # Return a string formed by all the char codes stored in the Uint8array
-        (String.fromCharCode(c) for c in arr).join('')
-      else
-        # take the data directly from the WebSocket `data` field
-        evt.data
-      @serverActivity = now()
-      if data == Byte.LF # heartbeat
-        @debug? "<<< PONG"
-        return
-      @debug? "<<< #{data}"
-      # Handle STOMP frames received from the server
-      # The unmarshall function returns the frames parsed and any remaining
-      # data from partial frames.
-      unmarshalledData = Frame.unmarshall(@partialData + data)
-      @partialData = unmarshalledData.partial
-      for frame in unmarshalledData.frames
-        switch frame.command
-          # [CONNECTED Frame](http://stomp.github.com/stomp-specification-1.1.html#CONNECTED_Frame)
-          when "CONNECTED"
-            @debug? "connected to server #{frame.headers.server}"
-            @connected = true
-            @_setupHeartbeat(frame.headers)
-            @connectCallback? frame
-          # [MESSAGE Frame](http://stomp.github.com/stomp-specification-1.1.html#MESSAGE)
-          when "MESSAGE"
-            # the `onreceive` callback is registered when the client calls
-            # `subscribe()`.
-            # If there is registered subscription for the received message,
-            # we used the default `onreceive` method that the client can set.
-            # This is useful for subscriptions that are automatically created
-            # on the browser side (e.g. [RabbitMQ's temporary
-            # queues](http://www.rabbitmq.com/stomp.html)).
-            subscription = frame.headers.subscription
-            onreceive = @subscriptions[subscription] or @onreceive
-            if onreceive
-              client = this
-              messageID = frame.headers["message-id"]
-              # add `ack()` and `nack()` methods directly to the returned frame
-              # so that a simple call to `message.ack()` can acknowledge the message.
-              frame.ack = (headers = {}) =>
-                client .ack messageID , subscription, headers
-              frame.nack = (headers = {}) =>
-                client .nack messageID, subscription, headers
-              onreceive frame
-            else
-              @debug? "Unhandled received MESSAGE: #{frame}"
-          # [RECEIPT Frame](http://stomp.github.com/stomp-specification-1.1.html#RECEIPT)
-          #
-          # The client instance can set its `onreceipt` field to a function taking
-          # a frame argument that will be called when a receipt is received from
-          # the server:
-          #
-          #     client.onreceipt = function(frame) {
-          #       receiptID = frame.headers['receipt-id'];
-          #       ...
-          #     }
-          when "RECEIPT"
-            @onreceipt?(frame)
-          # [ERROR Frame](http://stomp.github.com/stomp-specification-1.1.html#ERROR)
-          when "ERROR"
-            errorCallback?(frame)
-          else
-            @debug? "Unhandled frame: #{frame}"
-    @ws.onclose   = =>
-      msg = "Whoops! Lost connection to #{@ws.url}"
-      @debug?(msg)
-      @_cleanUp()
-      errorCallback?(msg)
-    @ws.onopen    = =>
-      @debug?('Web Socket Opened...')
-      headers["accept-version"] = Stomp.VERSIONS.supportedVersions()
-      headers["heart-beat"] = [@heartbeat.outgoing, @heartbeat.incoming].join(',')
-      @_transmit "CONNECT", headers
-
-  # [DISCONNECT Frame](http://stomp.github.com/stomp-specification-1.1.html#DISCONNECT)
-  disconnect: (disconnectCallback, headers={}) ->
-    @_transmit "DISCONNECT", headers
-    # Discard the onclose callback to avoid calling the errorCallback when
-    # the client is properly disconnected.
-    @ws.onclose = null
-    @ws.close()
-    @_cleanUp()
-    disconnectCallback?()
-
-  # Clean up client resources when it is disconnected or the server did not
-  # send heart beats in a timely fashion
-  _cleanUp: () ->
-    @connected = false
-    Stomp.clearInterval @pinger if @pinger
-    Stomp.clearInterval @ponger if @ponger
-
-  # [SEND Frame](http://stomp.github.com/stomp-specification-1.1.html#SEND)
-  #
-  # * `destination` is MANDATORY.
-  send: (destination, headers={}, body='') ->
-    headers.destination = destination
-    @_transmit "SEND", headers, body
-
-  # [SUBSCRIBE Frame](http://stomp.github.com/stomp-specification-1.1.html#SUBSCRIBE)
-  subscribe: (destination, callback, headers={}) ->
-    # for convenience if the `id` header is not set, we create a new one for this client
-    # that will be returned to be able to unsubscribe this subscription
-    unless headers.id
-      headers.id = "sub-" + @counter++
-    headers.destination = destination
-    @subscriptions[headers.id] = callback
-    @_transmit "SUBSCRIBE", headers
-    client = this
-    return {
-      id: headers.id
-
-      unsubscribe: ->
-        client.unsubscribe headers.id
-    }
-
-  # [UNSUBSCRIBE Frame](http://stomp.github.com/stomp-specification-1.1.html#UNSUBSCRIBE)
-  #
-  # * `id` is MANDATORY.
-  #
-  # It is preferable to unsubscribe from a subscription by calling
-  # `unsubscribe()` directly on the object returned by `client.subscribe()`:
-  #
-  #     var subscription = client.subscribe(destination, onmessage);
-  #     ...
-  #     subscription.unsubscribe();
-  unsubscribe: (id) ->
-    delete @subscriptions[id]
-    @_transmit "UNSUBSCRIBE", {
-      id: id
-    }
-
-  # [BEGIN Frame](http://stomp.github.com/stomp-specification-1.1.html#BEGIN)
-  #
-  # If no transaction ID is passed, one will be created automatically
-  begin: (transaction) ->
-    txid = transaction || "tx-" + @counter++
-    @_transmit "BEGIN", {
-      transaction: txid
-    }
-    client = this
-    return {
-      id: txid
-      commit: ->
-        client.commit txid
-      abort: ->
-        client.abort txid
-    }
-
-  # [COMMIT Frame](http://stomp.github.com/stomp-specification-1.1.html#COMMIT)
-  #
-  # * `transaction` is MANDATORY.
-  #
-  # It is preferable to commit a transaction by calling `commit()` directly on
-  # the object returned by `client.begin()`:
-  #
-  #     var tx = client.begin(txid);
-  #     ...
-  #     tx.commit();
-  commit: (transaction) ->
-    @_transmit "COMMIT", {
-      transaction: transaction
-    }
-
-  # [ABORT Frame](http://stomp.github.com/stomp-specification-1.1.html#ABORT)
-  #
-  # * `transaction` is MANDATORY.
-  #
-  # It is preferable to abort a transaction by calling `abort()` directly on
-  # the object returned by `client.begin()`:
-  #
-  #     var tx = client.begin(txid);
-  #     ...
-  #     tx.abort();
-  abort: (transaction) ->
-    @_transmit "ABORT", {
-      transaction: transaction
-    }
-
-  # [ACK Frame](http://stomp.github.com/stomp-specification-1.1.html#ACK)
-  #
-  # * `messageID` & `subscription` are MANDATORY.
-  #
-  # It is preferable to acknowledge a message by calling `ack()` directly
-  # on the message handled by a subscription callback:
-  #
-  #     client.subscribe(destination,
-  #       function(message) {
-  #         // process the message
-  #         // acknowledge it
-  #         message.ack();
-  #       },
-  #       {'ack': 'client'}
-  #     );
-  ack: (messageID, subscription, headers = {}) ->
-    headers["message-id"] = messageID
-    headers.subscription = subscription
-    @_transmit "ACK", headers
-
-  # [NACK Frame](http://stomp.github.com/stomp-specification-1.1.html#NACK)
-  #
-  # * `messageID` & `subscription` are MANDATORY.
-  #
-  # It is preferable to nack a message by calling `nack()` directly on the
-  # message handled by a subscription callback:
-  #
-  #     client.subscribe(destination,
-  #       function(message) {
-  #         // process the message
-  #         // an error occurs, nack it
-  #         message.nack();
-  #       },
-  #       {'ack': 'client'}
-  #     );
-  nack: (messageID, subscription, headers = {}) ->
-    headers["message-id"] = messageID
-    headers.subscription = subscription
-    @_transmit "NACK", headers
-
-# ##The `Stomp` Object
-Stomp =
-  VERSIONS:
-    V1_0: '1.0'
-    V1_1: '1.1'
-    V1_2: '1.2'
-
-    # Versions of STOMP specifications supported
-    supportedVersions: ->
-      '1.1,1.0'
-
-  # This method creates a WebSocket client that is connected to
-  # the STOMP server located at the url.
-  client: (url, protocols = ['v10.stomp', 'v11.stomp']) ->
-    # This is a hack to allow another implementation than the standard
-    # HTML5 WebSocket class.
-    #
-    # It is possible to use another class by calling
-    #
-    #     Stomp.WebSocketClass = MozWebSocket
-    #
-    # *prior* to call `Stomp.client()`.
-    #
-    # This hack is deprecated and  `Stomp.over()` method should be used
-    # instead.
-    klass = Stomp.WebSocketClass || WebSocket
-    ws = new klass(url, protocols)
-    new Client ws
-
-  # This method is an alternative to `Stomp.client()` to let the user
-  # specify the WebSocket to use (either a standard HTML5 WebSocket or
-  # a similar object).
-  over: (ws) ->
-    new Client ws
-
-  # For testing purpose, expose the Frame class inside Stomp to be able to
-  # marshall/unmarshall frames
-  Frame: Frame
-
-# # `Stomp` object exportation
-
-# export as CommonJS module
-if exports?
-  exports.Stomp = Stomp
-
-# export in the Web Browser
-if window?
-  # in the Web browser, rely on `window.setInterval` to handle heart-beats
-  Stomp.setInterval= (interval, f) ->
-    window.setInterval f, interval
-  Stomp.clearInterval= (id) ->
-    window.clearInterval id
-  window.Stomp = Stomp
-# or in the current object (e.g. a WebWorker)
-else if !exports
-  self.Stomp = Stomp


Some more docs fixes

Some more docs fixes

/cc @gjtorikian

--- src/app/display-buffer.coffee
+++ src/app/display-buffer.coffee
@@ -63,35 +63,37 @@
     bufferDelta = 0
     @triggerChanged({ start, end, screenDelta, bufferDelta })

-  # Public: Gets the line for the given screen row.
+  # Public: Gets the screen line for the given screen row.
   #
   # screenRow - A {Number} indicating the screen row.
   #
-  # Returns a {String}.
+  # Returns a {ScreenLine}.
   lineForRow: (row) ->
     @lineMap.lineForScreenRow(row)

-  # Public: Gets the lines for the given screen row boundaries.
+  # Public: Gets the screen lines for the given screen row range.
   #
   # startRow - A {Number} indicating the beginning screen row.
   # endRow - A {Number} indicating the ending screen row.
   #
-  # Returns an {Array} of {String}s.
+  # Returns an {Array} of {ScreenLine}s.
   linesForRows: (startRow, endRow) ->
     @lineMap.linesForScreenRows(startRow, endRow)

-  # Public: Gets the lines in the buffer.
-  #
-  # Returns an {Array} of {String}s.
+  # Public: Gets all the screen lines.
+  #
+  # Returns an {Array} of {ScreenLines}s.
   getLines: ->
     @lineMap.linesForScreenRows(0, @lineMap.lastScreenRow())

-  # Public: Given a starting and ending row, this converts every row into a buffer position.
-  #
-  # startRow - The row {Number} to start at
-  # endRow - The row {Number} to end at (default: {.getLastRow})
-  #
-  # Returns an {Array} of {Range}s.
+
+  # Public: Given starting and ending screen rows, this returns an array of the
+  # buffer rows corresponding to every screen row in the range
+  #
+  # startRow - The screen row {Integer} to start at
+  # endRow - The screen row {Integer} to end at (default: {.lastScreenRow})
+  #
+  # Returns an {Array} of buffer rows as {Integers}s.
   bufferRowsForScreenRows: (startRow, endRow) ->
     @lineMap.bufferRowsForScreenRows(startRow, endRow)


fills newly created items if bound

fills newly created items if bound

--- app/assets/javascripts/backend/budget.js.coffee
+++ app/assets/javascripts/backend/budget.js.coffee
@@ -87,6 +87,7 @@
       new_item = $(this).closest('td').prev()
       if new_item.prev().hasClass('homogeneous')
         new_item.addClass('homogeneous')
+        updateItems()
       new_item.attr('data-support-destroy', support_destroy_id)
     # adds total calculation cells
     $("[data-appendable]").each ->


do not return if we are in an if statement

--- lib/atom-ternjs-type.coffee
+++ lib/atom-ternjs-type.coffee
@@ -123,10 +123,6 @@

     text = buffer.getTextInRange([[rangeBefore.start.row, 0], [rangeBefore.start.row, rangeBefore.start.column]])

-    if !text.replace(/\s/g, '').length or text.match(/\bif\b/)
-      @destroyOverlay()
-      return
-
     @manager.client.update(editor.getURI(), editor.getText()).then =>
       @manager.client.type(editor, rangeBefore.start).then (data) =>
         if !data or data.type is '?' or !data.exprName


CSS Item mouse coords fixed for firefox

CSS Item mouse coords fixed for firefox

--- impl/css/level0/item.coffee
+++ impl/css/level0/item.coffee
@@ -56,8 +56,8 @@
 getMouseCoords = do ->
 	getArgs = (e) ->
 		rect = e.currentTarget.getBoundingClientRect()
-		x = e.layerX - rect.left
-		y = e.layerY - rect.top
+		x = e.pageX - rect.left
+		y = e.pageY - rect.top

 		x: x
 		y: y
@@ -74,8 +74,8 @@
 getRestrictedMouseCoords = do ->
 	getArgs = (e) ->
 		rect = e.currentTarget.getBoundingClientRect()
-		x = e.layerX - rect.left
-		y = e.layerY - rect.top
+		x = e.pageX - rect.left
+		y = e.pageY - rect.top

 		if x >= 0 and y >= 0 and x <= rect.width and y <= rect.height
 			x: x


Fixed feathures modification to be applied to nav menu

--- app/coffee/modules/admin/project-profile.coffee
+++ app/coffee/modules/admin/project-profile.coffee
@@ -118,6 +118,7 @@
             promise = $repo.save($scope.project)
             promise.then ->
                 $confirm.notify("success")
+                $scope.$emit("project:loaded", $scope.project)

             promise.then null, (data) ->
                 console.log "FAIL"


use env variable to give tokens instead of reading a file

--- lib/token.coffee
+++ lib/token.coffee
@@ -34,17 +34,18 @@
 ## @callback {function} Continuation to pass control back to when complete.
 ## Initialize tokens which contains applications and their tokens
 module.exports.init = (app, callback) ->
-    app.tokens = []
-    token = fs.readFileSync('/etc/cozy/tokens/data-system.token', 'utf8')
-    token = token.split('\n')[0]
-    app.tokens['home'] = token
-    app.tokens['proxy'] = token
-    db.view 'application/all', (err, res) ->
-        if (err)
-            callback new Error("Error in view")
-        else
-            # Search application with token
-            res.forEach (row) ->
-                if row.state is "installed"
-                    app.tokens[row.name] = row.password
-            callback app.tokens+    app.tokens = []
+    if process.env.NODE_ENV is "production"
+        token = process.env.token
+        token = token.split('\n')[0]
+        app.tokens['home'] = token
+        app.tokens['proxy'] = token
+        db.view 'application/all', (err, res) ->
+            if (err)
+                callback new Error("Error in view application/all")
+            else
+                # Search application with token
+                res.forEach (row) ->
+                    if row.state is "installed"
+                        app.tokens[row.name] = row.password
+                callback app.tokens


Sort imports

Sort imports

--- app.coffee
+++ app.coffee
@@ -26,19 +26,19 @@
 	return if err?
 	serverVersion = stdout.trim()

+async = require 'async'
+basicAuth = require 'basic-auth'
+bcrypt = require 'bcrypt'
+crypto = require 'crypto'
+escapeRegExp = require 'escape-string-regexp'
 express = require 'express'
 fs = require 'fs'
-stream = require 'stream'
+path = require 'path'
+tarstream = require 'tar-stream'
+watchr = require 'watchr'
 xmlstream = require 'xml-stream'
-path = require 'path'
-async = require 'async'
-tarstream = require 'tar-stream'
 xmlwriter = require 'xml-writer'
-bcrypt = require 'bcrypt'
-watchr = require 'watchr'
-crypto = require 'crypto'
-basicAuth = require 'basic-auth'
-escapeRegExp = require 'escape-string-regexp'
+
 debug = (require 'debug')('PackageServer:debug')
 warn = (require 'debug')('PackageServer:warn')
 warn.log = console.warn.bind console


path for env development

path for env development

--- app.coffee
+++ app.coffee
@@ -55,7 +55,8 @@
 pathVideo = (data, fileName)->
   ext = fileName.split('.')
   if env is 'development'
-    __dirname + '/video/' + data.name + '.' + ext[ext.length - 1]
+    dir = data.path.split('/')
+    __dirname + '/video/' + dir[dir.length - 2] + '/' + data.name + '.' + ext[ext.length - 1]
   else
     data.path + data.name + '.' + ext[ext.length - 1]

@@ -67,7 +68,7 @@
       id:id
     , (err, status, body) ->
       body = JSON.parse(body)
-      console.log
+      console.log body
       if err or status.statusCode isnt 200 or body.success is false
         next(err)
       else


upload check disabled #2

upload check disabled #2

--- lib/directory-upload.coffee
+++ lib/directory-upload.coffee
@@ -66,9 +66,9 @@
         data: content
         filename: file.name
         type: file.type
-      else
-        eventbus.fire "Notifications","info","Die Datei '#{filename}' ist keine Text-/Office-Datei."
-        eventbus.fire "Notifications","info","Bild Datein und andere Binary Dateien können über 'Daisy->Dateien->Neue Datei anlegen' hochgeladen werden."
+      # else
+      #   eventbus.fire "Notifications","info","Die Datei '#{filename}' ist keine Text-/Office-Datei."
+      #   eventbus.fire "Notifications","info","Bild Datein und andere Binary Dateien können über 'Daisy->Dateien->Neue Datei anlegen' hochgeladen werden."

   #Teile den Dateinamen in name und type auf.
   splitFileName: (filename) ->


add gc to filestore

add gc to filestore

--- app.coffee
+++ app.coffee
@@ -14,6 +14,7 @@
 Metrics.initialize("filestore")
 Metrics.open_sockets.monitor(logger)
 Metrics.event_loop?.monitor(logger)
+Metrics.memory.monitor(logger)

 app.configure ->
 	app.use express.bodyParser()


compatibility with newer version of poet

--- app.coffee
+++ app.coffee
@@ -134,7 +134,8 @@

 .addTemplate
   ext: ['markdown', 'md']
-  fn: marked
+  fn: (options) ->
+    marked options.source

 .addRoute '/', (req, res) ->
   res.render 'page',


app.checkEnvironment

app.checkEnvironment

--- app.coffee
+++ app.coffee
@@ -10,14 +10,26 @@

 global.app = express()

-config = require './config'
+config = null

-if fs.existsSync config.web.listen
-  fs.unlinkSync config.web.listen
+exports.checkEnvironment = ->
+  config_file_path = path.join __dirname, 'config.coffee'

-fs.chmodSync path.join(__dirname, 'config.coffee'), 0o750
+  unless fs.existsSync config_file_path
+    default_config_file_path = path.join __dirname, './sample/rpvhost.config.coffee'
+    fs.writeFileSync config_file_path, fs.readFileSync default_config_file_path
+    console.log '[Warning] Copy sample config file to ./config.coffee'
+
+  fs.chmodSync config_file_path, 0o750
+
+  config = require './config'
+
+  if fs.existsSync config.web.listen
+    fs.unlinkSync config.web.listen

 exports.run = ->
+  exports.checkEnvironment()
+
   {user, password, host, name} = config.mongodb

   if user and password


Change faye namespace.

Change faye namespace.

--- app.coffee
+++ app.coffee
@@ -48,7 +48,7 @@
       type: fayeRedis
       host: config.redis.host
       port: config.redis.port
-      namespace: "faye"
+      namespace: "cloudsdale:faye"

   global.fayengine = faye._server._engine._engine
   global.rediscli = faye._server._engine._engine._redis


Change publicLink to be correct

Change publicLink to be correct

--- app.coffee
+++ app.coffee
@@ -64,10 +64,7 @@
   if not droom?
     rooms.push new Room
   otherUserJoined = droom? and (droom.top? or droom.bottom?)
-  if config.publicPort != 80
-    publicLink = "http://#{config.publicHost}:#{config.publicPort}/#{token}"
-  else
-    publicLink = "http://#{config.publicHost}/#{token}"
+  publicLink = "http://#{config.publicHost}/#{token}"
   response.render 'room',
     "otherUserJoined": otherUserJoined
     room: token


Stop the beforeAction execution chain when  is disposed

--- src/chaplin/dispatcher.coffee
+++ src/chaplin/dispatcher.coffee
@@ -186,8 +186,10 @@
       # Detect a CommonJS promise  in order to use pipelining below,
       # otherwise execute next method directly
       if previous and typeof previous.then is 'function'
-        previous.then (data) ->
-          next beforeActions.shift(), data
+        previous.then (data) =>
+          # Execute as long as the currentController is the callee for this promise
+          if not @currentController or controller is @currentController
+            next beforeActions.shift(), data
       else
         next beforeActions.shift(), previous


mark irrelevant tests to pending to later update

--- desktop/apps/partnerships/test/templates.coffee
+++ desktop/apps/partnerships/test/templates.coffee
@@ -16,16 +16,16 @@

 describe 'Partnerships templates', ->

-  it 'shows the h1 header', ->
+  xit 'shows the h1 header', ->
     $(render()).find('h1').html().should.equal 'Artsy for Galleries'

-  it 'shows the h2 headers for each section', ->
+  xit 'shows the h2 headers for each section', ->
     _.map($(render()).find('h2'), (x) -> $(x).html()).should.eql [
       'Network', 'Audience', 'Access',
       'Tools', 'Artsy Folio', 'Support'
     ]

-  it 'shows the CTA in nav', ->
+  xit 'shows the CTA in nav', ->
     $(render()).find('.partnerships-section-nav a:last-child')
       .attr('href').should.containEql '/apply'


Update site.coffee

Update site.coffee

--- scripts/site.coffee
+++ scripts/site.coffee
@@ -23,8 +23,11 @@
 main = ->
 	exec "git config --local --get remote.origin.url", (err, output) ->
 		output = output.trim()
-		if output != "git@github.com:koenbok/framer.git"
-			throw Error("Not the right repo: '#{output}'")
+		output = output.toLowerCase()
+		if output not in [
+				"git@github.com:koenbok/framer.git",
+				"https://github.com/koenbok/Framer.git"]
+				throw Error("Not the right repo: '#{output}'")
 		_main()

 _main = ->
@@ -56,8 +59,6 @@

 	exec "git log --pretty=format:\"%h\t%an\t%ad\t%s\" --first-parent master", (err, output) ->
 		throw err if err
-
-		console.log output

 		start = false


fix last reference removal

fix last reference removal

--- lib/insert-link-view.coffee
+++ lib/insert-link-view.coffee
@@ -152,7 +152,10 @@
     @editor.buffer.scan /// ^ \[#{@referenceId}\]: \ + ///, (match) =>
       @editor.setSelectedBufferRange(match.range)
       @editor.deleteLine()
-      @editor.deleteLine() unless @editor.selectToEndOfLine()[0].getText()
+      emptyLine = !@editor.selectLine()[0].getText().trim()
+      @editor.moveCursorUp()
+      emptyLineAbove = !@editor.selectLine()[0].getText().trim()
+      @editor.deleteLine() if emptyLine and emptyLineAbove
     @editor.setCursorBufferPosition(position)
     @editor.buffer.commitTransaction()


Avoid triggering trix-change on initial load

--- src/trix/elements/trix_editor_element.coffee
+++ src/trix/elements/trix_editor_element.coffee
@@ -100,7 +100,8 @@
       when "change", "attachment-add", "attachment-edit", "attachment-remove"
         @inputElement.value = Trix.serializeToContentType(this, "text/html")

-    triggerEvent("trix-#{message}", onElement: this, attributes: data)
+    if @editorController
+      triggerEvent("trix-#{message}", onElement: this, attributes: data)

   # Element lifecycle


poi popup

poi popup

--- js/views/map.coffee
+++ js/views/map.coffee
@@ -31,7 +31,22 @@
         @addLayer(utils.routeLayer)
       unless(utils.poiLayer)
         utils.poiLayer = new OpenLayers.Layer.Vector("POIs", {styleMap: utils.poiStyleMap})
+        selectControl = new OpenLayers.Control.SelectFeature(
+                utils.poiLayer,
+                {
+                  id: 'poi-select-control'
+                  onSelect: @showPOIDetails
+                  #unUnselect: onPopupFeatureUnselect
+                }
+                )
+        utils.map.instance.addControl(selectControl)
+        selectControl.activate()
         @addLayer(utils.poiLayer)
+
+
+    showPOIDetails: (poi) ->
+      poi = poi.attributes
+      alert(poi.title)

     showRoute: (routeFeature) ->


Issue #1687. Keeping a reference to __originalDirname in Cake tasks, after Node's __dirname

--- cake.coffee
+++ cake.coffee
@@ -39,12 +39,13 @@
     missingTask name unless tasks[name]
     tasks[name].action options

-
 # Run `cake`. Executes all of the tasks you pass, in order. Note that Node's
 # asynchrony may cause tasks to execute in a different order than you'd expect.
-# If no tasks are passed, print the help screen.
+# If no tasks are passed, print the help screen. Keep a reference to the
+# original directory name, when running Cake tasks from subdirectories.
 exports.run = ->
-  process.chdir cakefileDirectory fs.realpathSync '.'
+  global.__originalDirname = fs.realpathSync '.'
+  process.chdir cakefileDirectory __originalDirname
   args = process.argv.slice 2
   CoffeeScript.run fs.readFileSync('Cakefile').toString(), filename: 'Cakefile'
   oparse = new optparse.OptionParser switches


Should keep parent window when reloading iframe

--- lib/zombie/history.coffee
+++ lib/zombie/history.coffee
@@ -47,6 +47,13 @@
 createHistory = (browser, focus)->
   history = new History(browser, focus)
   return history.open.bind(history)
+
+
+# If window is not the top level window, return parent for creating new child
+# window, otherwise returns false.
+parentFrom = (window)->
+  unless window.parent == window.getGlobal()
+    return window.parent

 # Entry has the following properties:
@@ -142,13 +149,11 @@
   submit: ({ url, method, encoding, data })->
     window = @current.window
     url = HTML.resourceLoader.resolve(window.document, url)
-    unless window.parent == window.getGlobal()
-      parent = window.parent
     params =
       browser:  @browser
       history:  this
       name:     window.name
-      parent:   parent
+      parent:   parentFrom(window)
       url:      url
       method:   method
       encoding: encoding
@@ -178,9 +183,7 @@
       event.initEvent("hashchange", true, false)
       window._dispatchEvent(window, event, true)
     else
-      if @current.window.parent != @current.window.getGlobal()
-        parent = @current.window.parent
-      window = createWindow(browser: @browser, history: this, name: name, url: url, parent: parent)
+      window = createWindow(browser: @browser, history: this, name: name, url: url, parent: parentFrom(@current.window))
       @addEntry(window, url)
     return

@@ -200,16 +203,14 @@
       event.initEvent("hashchange", true, false)
       window._dispatchEvent(window, event, true)
     else
-      if @current.window.parent != @current.window
-        parent = @current.window.parent
-      window = createWindow(browser: @browser, history: this, name: name, url: url, parent: parent)
+      window = createWindow(browser: @browser, history: this, name: name, url: url, parent: parentFrom(@current.window))
       @replaceEntry(window, url)
     return

   reload: ->
     if window = @current.window
       url = window.location.href
-      newWindow = createWindow(browser: @browser, history: this, name: window.name, url: url, parent: window.parent)
+      newWindow = createWindow(browser: @browser, history: this, name: window.name, url: url, parent: parentFrom(window))
       @replaceEntry(newWindow, url)

   # This method is available from Location.


More better error checking

More better error checking

--- server/index.coffee
+++ server/index.coffee
@@ -24,7 +24,8 @@

 # Load Routes for the API, admin, and frontend
 try
-  app.use "/#{config.buckets.apiSegment}", api for api in util.loadClasses "#{__dirname}/routes/api/"
+  for api in util.loadClasses "#{__dirname}/routes/api/"
+    app.use "/#{config.buckets.apiSegment}", api if api.init
 catch e
   console.log e
   throw 'Missing API Class'.red


$apply keyboard shortcuts so they're real snappy

--- src/scripts/controllers/main.coffee
+++ src/scripts/controllers/main.coffee
@@ -3,13 +3,13 @@
 .controller('MainCtrl', ['$scope', ($scope) ->
     Mousetrap.bind 'space', (e) ->
         e.preventDefault()
-        $scope.player.togglePause()
+        $scope.$apply -> $scope.player.togglePause()

     Mousetrap.bind 'shift+right', ->
-        $scope.player.next()
+        $scope.$apply -> $scope.player.next()

     Mousetrap.bind 'shift+left', ->
-        $scope.player.prev()
+        $scope.$apply -> $scope.player.prev()

     $scope.$on '$destroy', ->
         Mousetrap.unbind 'space'


basic reputation scoring works

basic reputation scoring works

--- src/scripts/opendns-umbrella.coffee
+++ src/scripts/opendns-umbrella.coffee
@@ -13,34 +13,34 @@
 # Author:
 #   Scott J Roberts - @sroberts

-VIRUSTOTAL_API_KEY = process.env.OPENDNS_KEY
+OPENDNS_KEY = process.env.OPENDNS_KEY
+token = OPENDNS_KEY
 opendns_base = "https://investigate.api.opendns.com/"

 module.exports = (robot) ->
   robot.respond /opendns (.*)/i, (msg) ->

-    if OPENDNSKEY_KEY?
-      msg.send "#{OPENDNS_KEY}"
-    #   hash = msg.match[1].toLowerCase()
-    #   data = "apikey=#{encodeURIComponent VIRUSTOTAL_API_KEY}&resource=#{encodeURIComponent hash}"
-    #
-    #   robot.http(vt_file_report_url)
-    #     .post(data) (err, res, body) ->
-    #       if res.statusCode is 200
-    #         vt_json = JSON.parse(body)
-    #
-    #         if vt_json.response_code == 1
-    #           summary = """VirusTotal Result: #{vt_json.resource}
-    #           - Scanned at: #{vt_json.scan_date}
-    #           - Results:    #{vt_json.positives}/#{vt_json.total}
-    #           - Link:       #{vt_json.permalink}
-    #           """
-    #
-    #           msg.send summary
-    #
-    #         else
-    #           msg.send "VirusTotal URL Analysis: #{vt_json.verbose_msg}"
-    #       else
-    #         msg.send "Error: Couldn't access #{vt_url}."
+    if OPENDNS_KEY?
+      artifact = msg.match[1].toLowerCase()
+
+      msg.http("https://investigate.api.opendns.com/domains/score/#{artifact}")
+        .headers('Authorization': 'Bearer ' + token)
+        .get() (err, res, body) ->
+
+          if res.statusCode is 200
+
+            opendns_json = JSON.parse body
+
+            for key, value of opendns_json
+              if value is "1"
+                msg.send "Yeah... #{key} seems ok."
+              if value is "0"
+                msg.send "Not sure about that #{key}. Ask again later."
+              if value is "-1"
+                msg.send "That #{key} looks bad. It'll probably own your box. Probably."
+
+            msg.send "THE END!"
+          else
+            msg.send "Doh! #{res.statusCode}: Which means that didn't work."
     else
       msg.send "OpenDNS API key not configured."


Updating text on display buttons.

Updating text on display buttons.

--- lib/proto-repl-sayid.coffee
+++ lib/proto-repl-sayid.coffee
@@ -51,12 +51,12 @@
       )
       displayButtons = []
       displayButtons.push(
-        name: "Last Captured",
+        name: "Display Last",
         icon: "eye",
         onClick: ()=> @displayLastCaptured()
       )
       displayButtons.push(
-        name: "All Captured",
+        name: "Display All",
         icon: "eye",
         onClick: ()=> @displayAllCaptured()
       )


Fixed random letter selection bug

Fixed random letter selection bug

--- lib/ricksum-provider.coffee
+++ lib/ricksum-provider.coffee
@@ -3,7 +3,7 @@
 matchers = ['ricksum', 'lorem']

 parsePrefix = (prefix, matchers) ->
-  matcher = matchers.find (val) -> val.indexOf(prefix) >= 0
+  matcher = matchers.find (val) -> val.indexOf(prefix) == 0
   if matcher then return {
     display: matcher,
     quotes: atom.config.get('lorem-ricksum.quotes'),


client side -- start project running if necessary when getting directory listing

--- src/smc-webapp/project_store.coffee
+++ src/smc-webapp/project_store.coffee
@@ -638,14 +638,18 @@
         # get_my_group is defined.
         id = misc.uuid()
         @set_activity(id:id, status:"getting file listing for #{misc.trunc_middle(path,30)}...")
-        async.waterfall([
+        my_group = undefined
+        the_listing = undefined
+        async.series([
             (cb) =>
                 # make sure that our relationship to this project is known.
                 @redux.getStore('projects').wait
                     until   : (s) => s.get_my_group(@project_id)
                     timeout : 30
-                    cb      : cb
-            (group, cb) =>
+                    cb      : (err, group) =>
+                        my_group = group
+                        cb(err)
+            (cb) =>
                 store = @get_store()
                 if not store?
                     cb("store no longer defined"); return
@@ -655,16 +659,18 @@
                     path       : path
                     hidden     : true
                     max_time_s : 120  # keep trying for up to 2 minutes
-                    group      : group
-                    cb         : cb
-        ], (err, listing) =>
+                    group      : my_group
+                    cb         : (err, listing) =>
+                        the_listing = listing
+                        cb(err)
+        ], (err) =>
             @set_activity(id:id, stop:'')
             # Update the path component of the immutable directory listings map:
             store = @get_store()
             #if DEBUG then console.log('ProjectStore::fetch_directory_listing done', store, listing)
             if not store?
                 return
-            map = store.directory_listings.set(path, if err then misc.to_json(err) else immutable.fromJS(listing.files))
+            map = store.directory_listings.set(path, if err then misc.to_json(err) else immutable.fromJS(the_listing.files))
             @setState(directory_listings : map)
             # done! releasing lock, then executing callback(s)
             cbs = @_set_directory_files_lock[_key]
@@ -1710,6 +1716,10 @@
     {webapp_client} = require('./webapp_client')
     if opts.group in ['owner', 'collaborator', 'admin']
         method = webapp_client.project_directory_listing
+        # Also, make sure project starts running, in case it isn't.
+        state = redux.getStore('projects').getIn([opts.project_id, 'state', 'state'])
+        if state != 'running'
+            redux.getActions('projects').start_project(opts.project_id)
     else
         method = webapp_client.public_project_directory_listing
     listing     = undefined


Ignore errors unlinking non-existent path

--- src/stdlib/command-installer.coffee
+++ src/stdlib/command-installer.coffee
@@ -17,9 +17,9 @@
           fs.chmod(destinationPath, 0o755, callback)

 unlinkCommand = (destinationPath, callback) ->
-  fs.exists destinationPath, (exists) ->
-    if exists
-      fs.unlink(destinationPath, callback)
+  fs.unlink destinationPath, (error) ->
+    if error? and error.code isnt 'ENOENT'
+      callback(error)
     else
       callback()


Fix typo in signup controller that failed to update schools.

--- app/assets/javascripts/angular/signup.js.coffee
+++ app/assets/javascripts/angular/signup.js.coffee
@@ -53,7 +53,7 @@

     self.districtSelected = () ->
       if self.isDomestic()
-        self.loadDomesticSChools()
+        self.loadDomesticSchools()
       delete self.school

     self.loadRemoteCollection = (collectionName, params={}, success_fn=null) ->


only select first element in interactive div

This means for 'image' type interactive the caption
and credits won't be snapshotted. Currently Shutterbug
doesn't handle multiple element selectors very well.
It will set the size of each element to be the size
of the first element. This creates lots of whitespace.

[#54415592]
https://www.pivotaltracker.com/story/show/54415592

--- app/assets/javascripts/image_question.js.coffee
+++ app/assets/javascripts/image_question.js.coffee
@@ -17,7 +17,7 @@
       modal: true
     })

-    @shutterbug       = new Shutterbug(".interactive-mod > *", null,(image_tag)=>
+    @shutterbug       = new Shutterbug(".interactive-mod > *:first-child", null,(image_tag)=>
       @set_image(image_tag)
     ,@image_question_id)


adding scroll_to_error method

adding scroll_to_error method

--- app/assets/javascripts/mobile/_mobile.js.coffee
+++ app/assets/javascripts/mobile/_mobile.js.coffee
@@ -1,11 +1,12 @@
 window.templates = {}

 $ ->
+    window.header_height =  ($ '.mobile-header').height()
     window.has_touch_events = !($ 'html').hasClass('no-touch')
     toggle_menu = -> ($ '#menu').toggle()

     if has_touch_events
-        ($ '.mobile-layout-inner').css('padding-top', ($ '.mobile-header').height())
+        ($ '.mobile-layout-inner').css('padding-top', header_height)
         ($ '#menu_button').tap((e) ->
             e.preventDefault()
             toggle_menu())
@@ -13,6 +14,10 @@
         ($ '#menu_button').click((e) ->
             e.preventDefault()
             toggle_menu())
+
+    window.scroll_to_error = ($context) ->
+        error_y = $context.find('.unhappy').first().offset().top - header_height - 20
+        scrollTo(0, error_y)

 window.pluralize_like_count = (like_count) ->
     if like_count is 1 then 'like' else 'likes'
@@ -188,7 +193,7 @@
         .submit((e) ->
             if ($ @).find('.unhappy').length
                 e.preventDefault()
-                scrollTo(($ @).find('.unhappy').first()))
+                scroll_to_error(($ @)))

 if gon.page is 'orders_new' or gon.page is 'orders_edit' or gon.page is 'orders_create'
     $ ->
@@ -224,7 +229,7 @@
                         exp_year: $credit_card_expiration_year.val()
                     }, stripeResponseHandler)
                 else
-                    scrollTo(($ @).find('.unhappy').first())
+                    scroll_to_error(($ @))

 render_nested_product_attribute_input = ($el) ->
@@ -275,8 +280,8 @@

         $mobile_form
             .isHappy(product_form_validation_rules)
-            .submit((e) ->
+            .submit (e) ->
                 if ($ @).find('.unhappy').length
                     e.preventDefault()
-                    scrollTo(($ @).find('.unhappy').first()))
-
+                    scroll_to_error(($ @))
+


OX-164 fixed reloading bug

OX-164 fixed reloading bug

--- app/assets/javascripts/model/binary/cube.coffee
+++ app/assets/javascripts/model/binary/cube.coffee
@@ -79,7 +79,7 @@

     bucketIndex = @bucketIndexByAddress3(bucket_x, bucket_y, bucket_z)

-    if cube[bucketIndex]
+    if bucketIndex? cube[bucketIndex]
       cube[bucketIndex].requestedZoomStep
     else
       @ZOOM_STEP_COUNT
@@ -152,7 +152,7 @@

             bucketIndex = @bucketIndexByAddress3(x + dx, y + dy, z + dz)

-            if bucketIndex
+            if bucketIndex?
               bucket = cube[bucketIndex]
               if bucketData
                 if zoomStep < bucket.zoomStep
@@ -164,7 +164,7 @@

     else
       bucketIndex = @bucketIndexByAddress3(bucket_x, bucket_y, bucket_z)
-      if bucketIndex
+      if bucketIndex?
         bucket = cube[bucketIndex]
         unless bucket
           return 0
@@ -206,7 +206,7 @@

             bucketIndex = @bucketIndexByAddress3(x + dx, y + dy, z + dz)

-            if cube[bucketIndex]
+            if bucketIndex? and cube[bucketIndex]
               cube[bucketIndex].requestedZoomStep = Math.min(zoomStep, cube[bucketIndex].requestedZoomStep)
             else
               cube[bucketIndex] = { requestedZoomStep : zoomStep, zoomStep : @ZOOM_STEP_COUNT }
@@ -215,7 +215,7 @@

       bucketIndex = @bucketIndexByAddress3(bucket_x, bucket_y, bucket_z)

-      if cube[bucketIndex]
+      if bucketIndex? and cube[bucketIndex]
         cube[bucketIndex].requestedZoomStep = 0
       else
         cube[bucketIndex] = { requestedZoomStep : 0, zoomStep : @ZOOM_STEP_COUNT }


Fix the tooltip gravity on resque updates

--- app/assets/javascripts/peek/views/resque.coffee
+++ app/assets/javascripts/peek/views/resque.coffee
@@ -1,2 +1,4 @@
 $(document).on 'peek:render', (event, request_id, data) ->
-  $('#resque-jobs-tooltip').attr('title', "Failures: #{data.context.resque.jobs.failures}").tipsy()
+  $('#resque-jobs-tooltip')
+    .attr('title', "Failures: #{data.context.resque.jobs.failures}")
+    .tipsy gravity: $.fn.tipsy.autoNS


Navigation buttons looks more pretty.

Navigation buttons looks more pretty.

--- app/assets/javascripts/simple_gallery.js.coffee
+++ app/assets/javascripts/simple_gallery.js.coffee
@@ -82,15 +82,15 @@
   button.css("display", "block")
   button.css("cursor", "pointer")

-  button.css("background", "#777")
+  button.css("background", "#EEE")
   button.css("display", "block")
-  button.css("opacity", "0.6")
-  button.css("filter", "alpha(opacity=60)")
+  button.css("opacity", "0.7")
+  button.css("filter", "alpha(opacity=70)")
   button.css("border-radius", "7px")
   button.css("-webkit-border-radius", "7px")
   button.css("-moz-border-radius", "7px")

-  button.css("color", "#FFF")
+  button.css("color", "#000")
   button.css("text-align", "center")
   button.css("vertical-align", "middle")
   button.css("font", "30px Tahoma,Arial,Helvetica,sans-serif")


showFormError option; two spaces separator before postfix form of "if" and "unless"; some comments.

--- app/assets/javascripts/ultimate/flash.js.coffee
+++ app/assets/javascripts/ultimate/flash.js.coffee
@@ -32,6 +32,7 @@
       showTimePerChar: 30
       showAjaxErrors: true
       showAjaxSuccesses: true
+      showFormError: true  # can be function (parsedJSON)
       hideOnClick: true
       removeOnHide: true
       forceAddDotsAfterLastWord: false
@@ -45,13 +46,13 @@

   constructor: (@jContainer, options = {}) ->
     _locale = options['locale'] or @constructor.defaults.options['locale']
-    $.error "Locale [#{_locale}] not exists in UltimateFlash default locales." unless @constructor.defaults.locales[_locale]
+    $.error "Locale [#{_locale}] not exists in UltimateFlash default locales."  unless @constructor.defaults.locales[_locale]
     @settings = $.extend {}, @constructor.defaults.options, @constructor.defaults.locales[_locale], options
     @jContainer.data @constructor.defaults.constants.widgetDataKey, @
     _self = @
     # delegate event for hide on click
     @jContainer.delegate '.flash:not(:animated)', 'click.ultimate_flash_close', ->
-      _self._hide $ @ if _self.settings.hideOnClick
+      _self._hide $ @  if _self.settings.hideOnClick
       false
     # init flashes from server
     @jFlashes().each ->
@@ -60,26 +61,26 @@
       _self._setTimeout jFlash
     # binding hook ajaxError handler
     @jContainer.ajaxError =>
-      @ajaxError arguments if @settings.showAjaxErrors
+      @ajaxError arguments  if @settings.showAjaxErrors
     # binding hook ajaxSuccess handler
     @jContainer.ajaxSuccess =>
-      @ajaxSuccess arguments if @settings.showAjaxSuccesses
+      @ajaxSuccess arguments  if @settings.showAjaxSuccesses

   jFlashes: (filterSelector) ->
     _jFlashes = @jContainer.find '.flash'
     if filterSelector then _jFlashes.filter filterSelector else _jFlashes

   _prepareText: (text) ->
-    text = strTrim text
+    text = $.trim text
     # Add dot after last word (if word has minimum 3 characters)
-    text += '.' if @settings.forceAddDotsAfterLastWord and @settings.regExpLastWordWithoutDot.test text
-    text = text.replace @settings.regExpLastWordWithDot, '$1' if @settings.forceRemoveDotsAfterLastWord
+    text += '.'  if @settings.forceAddDotsAfterLastWord and @settings.regExpLastWordWithoutDot.test text
+    text = text.replace @settings.regExpLastWordWithDot, '$1'  if @settings.forceRemoveDotsAfterLastWord
     text

   _hide: (jFlash) ->
     clearTimeout jFlash.data 'timeout_id'
     _self = @
-    jFlash.slideUp @settings.slideTime, -> $(@).remove() if _self.settings.removeOnHide
+    jFlash.slideUp @settings.slideTime, -> $(@).remove()  if _self.settings.removeOnHide

   _setTimeout: (jFlash) ->
     timeoutId = false
@@ -101,7 +102,7 @@
     @settings

   show: (type, text) ->
-    return false if $.isEmptyString text
+    return false  if $.isEmptyString text
     jFlash = $ "
#{@_prepareText text}
"
     jFlash.appendTo(@jContainer).slideDown @settings.slideTime
     @_setTimeout jFlash
@@ -124,17 +125,18 @@
   ###
   ajaxSuccess: (successArgs) ->
     successArgs = args successArgs
-    successArgs.shift() if successArgs[0].target # remove event
+    successArgs.shift()  if successArgs[0].target # remove event
     if $.isString successArgs[0]
       [data, textStatus, jqXHR] = successArgs
     else
       [jqXHR, ajaxSettings, data] = successArgs
-    return false if jqXHR.breakFlash
+    # prevent recall
+    return false  if jqXHR.breakFlash
     jqXHR.breakFlash = true
     if $.isString data
-      return @notice data if data.length and not $.isHTML data
+      return @notice data  if data.length and not $.isHTML data
     else if $.isPlainObject data
-      return @auto data['flash'] if data['flash']
+      return @auto data['flash']  if data['flash']
     false

   ###
@@ -149,30 +151,38 @@
       _next = arguments[0]
       if $.isString _next
         text = _next
-        _next = arguments[1] if arguments.length > 1
-      errorArgs = _next if not $.isString(_next) and _next.length
+        _next = arguments[1]  if arguments.length > 1
+      errorArgs = _next  if not $.isString(_next) and _next.length
     if errorArgs.length
       errorArgs = args errorArgs
-      errorArgs.shift() if errorArgs[0].target # remove event
+      errorArgs.shift()  if errorArgs[0].target # remove event
       [jqXHR, ajaxSettings, thrownError] = errorArgs
-      return false if jqXHR.breakFlash
+      # prevent recall
+      return false  if jqXHR.breakFlash
       jqXHR.breakFlash = true
       if jqXHR.responseText
         try
           if parsedJSON = $.parseJSON jqXHR.responseText
-            return @auto parsedJSON['flash'] if parsedJSON['flash']
-            return @alert parsedJSON['error'] if parsedJSON['error']
-            return @alert @settings.formFieldsError
+            return @auto parsedJSON['flash']  if parsedJSON['flash']
+            return @alert parsedJSON['error']  if parsedJSON['error']
+            if @settings.showFormError and _.isBoolean @settings.showFormError
+              return @alert @settings.formFieldsError
+            else if _.isFunction @settings.showFormError
+              return @settings.showFormError.apply @, [parsedJSON]
+            else
+              return false
         catch e
           # nop
       if jqXHR.status >= 400 and jqXHR.responseText
+        # try detect Rails raise message
         if raiseMatches = jqXHR.responseText.match /<\/h1>\n
(.+?)<\/pre>/
           thrownError = raiseMatches[1]
         else
-          thrownError = jqXHR.responseText if jqXHR.responseText.length < 200
+          # get short text message as error
+          thrownError = jqXHR.responseText  if jqXHR.responseText.length < 200
       else
-        thrownError = @settings.defaultThrownError if $.isString thrownError and not $.isEmptyString thrownError
-      text += ': ' if text
+        thrownError = @settings.defaultThrownError  if $.isString thrownError and not $.isEmptyString thrownError
+      text += ': '  if text
       text += "#{thrownError} [#{jqXHR.status}]"
     return @alert text

@@ -198,7 +208,7 @@
    * ajaxError       .ultimateFlash('ajaxError'[, String text = settings.defaultErrorText][, Arguments errorArgs = []])
   ###
   $.fn.ultimateFlash = ->
-    return @ unless @length
+    return @  unless @length
     jContainer = @eq 0
     widget = jContainer.data UltimateFlashWidget.defaults.constants.widgetDataKey
     argsLength = arguments.length
@@ -208,8 +218,8 @@
       if argsLength and typeof a[0] == 'string'
         command = a.shift()
       else
-        return widget if _returnWidget
-        return jContainer unless argsLength
+        return widget  if _returnWidget
+        return jContainer  unless argsLength
         command = 'updateSettings'
       if $.isFunction widget[command]
         return widget[command].apply widget, a


Remove invasive stubbing test

Remove invasive stubbing test

--- spec/LegacyNetwork.coffee
+++ spec/LegacyNetwork.coffee
@@ -355,75 +355,6 @@
             return done err if err
       , true

-  describe "Nodes are added first, then edges, then initializers (i.e. IIPs), and in order of definition order within each", ->
-    g = null
-    n = null
-    stubbed = {}
-    actual = []
-    expected = []
-
-    # Poor man's way of stubbing the Network. Investigate using
-    # [sinon-chai](https://github.com/domenic/sinon-chai) when we need stubbing
-    # for other parts of testing as well.
-    stub = ->
-      stubbed.addNode = noflo.Network::addNode
-      stubbed.addEdge = noflo.Network::addEdge
-      stubbed.addInitial = noflo.Network::addInitial
-
-      # Record the node/edge/initial and pass it along
-      noflo.Network::addNode = (node, cb) ->
-        actual.push node
-        stubbed.addNode.call this, node, cb
-      noflo.Network::addEdge = (edge, cb) ->
-        actual.push edge
-        stubbed.addEdge.call this, edge, cb
-      noflo.Network::addInitial = (initial, cb) ->
-        actual.push initial
-        stubbed.addInitial.call this, initial, cb
-
-    # Clean up after ourselves
-    restore = ->
-      noflo.Network::addNode = stubbed.addNode
-      noflo.Network::addEdge = stubbed.addEdge
-      noflo.Network::addInitial = stubbed.addInitial
-
-    before (done) ->
-      stub()
-      @timeout 6000
-
-      g = new noflo.Graph
-      g.baseDir = root
-      # Save the nodes/edges/initial for order testing later. The index numbers
-      # are the expected positions.
-      expected[0] = g.addNode "D", "Callback"
-      expected[10] = g.addInitial (->), "D", "callback"
-      expected[1] = g.addNode "A", "Split"
-      expected[11] = g.addInitial "Hello", "A", "in"
-      expected[2] = g.addNode "B1", "Merge"
-      expected[3] = g.addNode "B2", "Merge"
-      expected[5] = g.addEdge "A", "out", "B1", "in"
-      expected[6] = g.addEdge "A", "out", "B2", "in"
-      expected[4] = g.addNode "C", "Merge"
-      expected[7] = g.addEdge "B1", "out", "C", "in"
-      expected[12] = g.addInitial "World", "C", "in"
-      expected[8] = g.addEdge "B2", "out", "C", "in"
-      expected[9] = g.addEdge "C", "out", "D", "in"
-      noflo.createNetwork g, (err, nw) ->
-        return done err if err
-        nw.loader.components.Split = Split
-        nw.loader.components.Merge = Merge
-        nw.loader.components.Callback = Callback
-        n = nw
-        nw.connect (err) ->
-          return done err if err
-          nw.start done
-      , true
-
-    after restore
-
-    it "should add nodes, edges, and initials, in that order", ->
-      chai.expect(actual).to.deep.equal expected
-
   describe 'with an existing IIP', ->
     g = null
     n = null


Remove unused require

Remove unused require

--- spec/app/atom-spec.coffee
+++ spec/app/atom-spec.coffee
@@ -1,6 +1,5 @@
 RootView = require 'root-view'
 {$$} = require 'space-pen'
-Package = require 'package'

 describe "the `atom` global", ->
   describe ".loadPackage(name)", ->


Remove unused imports

Remove unused imports

--- spec/app/atom-spec.coffee
+++ spec/app/atom-spec.coffee
@@ -3,8 +3,6 @@
 {$$} = require 'space-pen'
 fsUtils = require 'fs-utils'
 Exec = require('child_process').exec
-_ = require 'underscore'
-Project = require 'project'

 describe "the `atom` global", ->
   beforeEach ->
@@ -346,4 +344,4 @@
         expect(coverage).toBeGreaterThan 80

         # stderr
-        expect(docRunner.argsForCall[0][2]).toBe ''+        expect(docRunner.argsForCall[0][2]).toBe ''


Fix version spec

Fix version spec

--- spec/app/atom-spec.coffee
+++ spec/app/atom-spec.coffee
@@ -249,7 +249,7 @@
         versionHandler.callCount > 0

       runs ->
-        expect(versionHandler.argsForCall[0][0]).toMatch /^\d+\.\d+\.\w+$/
+        expect(versionHandler.argsForCall[0][0]).toBeDefined()

   describe "modal native dialogs", ->
     beforeEach ->


Add comment about package specs label

Add comment about package specs label

--- spec/atom-reporter.coffee
+++ spec/atom-reporter.coffee
@@ -168,7 +168,9 @@
       @bundledArea.hide()
     if userPackageSpecs > 0
       if coreSpecs is 0 and bundledPackageSpecs is 0
-        packageFolderName = path.basename(path.dirname(specs[0].specDirectory))
+        # Package specs being run, show a more descriptive label
+        {specDirectory} = specs[0]
+        packageFolderName = path.basename(path.dirname(specDirectory))
         packageName = _.undasherize(_.uncamelcase(packageFolderName))
         @userHeader.text("#{packageName} Specs")
       else


Added spec for adding script using appendChild.

--- spec/browser-spec.coffee
+++ spec/browser-spec.coffee
@@ -65,14 +65,31 @@
   </html>
   """

-brains.get "/write", (req, res)-> res.send """
+brains.get "/script/write", (req, res)-> res.send """
   <html>
     <head>
       <script>document.write(unescape(\'%3Cscript src="/jquery.js"%3E%3C/script%3E\')</script>
     </head>
     <body>
       <script>
-        $(function() { document.title = "Script write" });
+        $(function() { document.title = "Script document.write" });
+      </script>
+    </body>
+  </html>
+  """
+
+brains.get "/script/append", (req, res)-> res.send """
+  <html>
+    <head>
+      <script>
+        var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;
+        s.src = '/jquery.js';
+        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s);
+      </script>
+    </head>
+    <body>
+      <script>
+        $(function() { document.title = "Script appendChild" });
       </script>
     </body>
   </html>
@@ -154,8 +171,11 @@
       "should process event": (browser)-> assert.equal browser.document.title, "Signed up"

-  "script write":
-    zombie.wants "http://localhost:3003/write"
-      "should run script": (browser)-> assert.equal browser.document.title, "Script write"
+  "adding script using document.write":
+    zombie.wants "http://localhost:3003/script/write"
+      "should run script": (browser)-> assert.equal browser.document.title, "Script document.write"
+  "adding script using appendChild":
+    zombie.wants "http://localhost:3003/script/append"
+      "should run script": (browser)-> assert.equal browser.document.title, "Script appendChild"

 ).export(module)


install-spec: Delete 'with a space' after test

The 'with a space' dir is a copy of the 'node-gyp' module,
just with spaces in the path (i.e. 'with a space/bin/node-gyp').

If this is still present on subsequent test runs,
the latter runs will fail. Deleting it allows subsequent runs to pass.

--- spec/install-spec.coffee
+++ spec/install-spec.coffee
@@ -546,6 +546,7 @@

       afterEach ->
         delete process.env.npm_config_node_gyp
+        fs.removeSync(path.join(nodeModules, 'with a space'))

       it 'builds native code successfully', ->
         callback = jasmine.createSpy('callback')


Use cross platform path in Project::replace spec

--- spec/project-spec.coffee
+++ spec/project-spec.coffee
@@ -208,13 +208,16 @@
     describe "when a file doesn't exist", ->
       it "calls back with an error", ->
         errors = []
-        waitsForPromise ->
-          atom.project.replace /items/gi, 'items', ['/not-a-file.js'], (result, error) ->
+        missingPath = path.resolve('/not-a-file.js')
+        expect(fs.existsSync(missingPath)).toBeFalsy()
+
+        waitsForPromise ->
+          atom.project.replace /items/gi, 'items', [missingPath], (result, error) ->
             errors.push(error)

         runs ->
           expect(errors).toHaveLength 1
-          expect(errors[0].path).toBe '/not-a-file.js'
+          expect(errors[0].path).toBe missingPath

     describe "when called with unopened files", ->
       it "replaces properly", ->


Add note about pending functionality

Add note about pending functionality

--- spec/vim-mode-spec.coffee
+++ spec/vim-mode-spec.coffee
@@ -129,14 +129,15 @@
           expect(editor.getText()).toBe "12345\nabcde"
           expect(editor.getCursorScreenPosition()).toEqual([1,0])

+        # FIXME: This functionality wasn't implemented previously.
         xdescribe "when the second d is prefixed by a count", ->
           it "deletes n lines, starting from the current", ->
             editor.setText("12345\nabcde\nABCDE\nQWERT")
             editor.setCursorScreenPosition([1,1])

-            editor.trigger keydownEvent('d')
-            editor.trigger keydownEvent('2')
-            editor.trigger keydownEvent('d')
+            keydown('d', element: editor[0])
+            keydown('2', element: editor[0])
+            keydown('d', element: editor[0])

             expect(editor.getText()).toBe "12345\nQWERT"
             expect(editor.getCursorScreenPosition()).toEqual([1,0])


Remove redundant getBuffer call in specs

--- spec/vim-mode-spec.coffee
+++ spec/vim-mode-spec.coffee
@@ -236,14 +236,14 @@
       it "inserts the contents of the default register", ->
         keydown('p', element: editor[0])

-        expect(editor.getBuffer().getText()).toBe "345\n012\n"
+        expect(editor.getText()).toBe "345\n012\n"

       it "inserts the contents of the 'a' register", ->
         keydown('"', element: editor[0])
         keydown('a', element: editor[0])
         keydown('p', element: editor[0])

-        expect(editor.getBuffer().getText()).toBe "a\n012\n"
+        expect(editor.getText()).toBe "a\n012\n"

     describe "basic motion bindings", ->
       beforeEach ->


Fix buffer-row/screen-row confusion in Move{Up,Down}

Fixes #532

--- lib/motions/general-motions.coffee
+++ lib/motions/general-motions.coffee
@@ -160,7 +160,7 @@

   moveCursor: (cursor, count=1) ->
     _.times count, =>
-      unless cursor.getBufferRow() is 0
+      unless cursor.getScreenRow() is 0
         cursor.moveUp()
         @ensureCursorIsWithinLine(cursor)

@@ -169,7 +169,7 @@

   moveCursor: (cursor, count=1) ->
     _.times count, =>
-      unless cursor.getBufferRow() is @editor.getEofBufferPosition().row
+      unless cursor.getScreenRow() is @editor.getLastScreenRow()
         cursor.moveDown()
         @ensureCursorIsWithinLine(cursor)


Barchart scaling is no longer obscured by label.

--- app/scripts/directives/compare-bar-chart.coffee
+++ app/scripts/directives/compare-bar-chart.coffee
@@ -34,7 +34,7 @@
           .attr('height', 30) # arbitrary

         x = d3.scale.linear()
-          .domain([-x0, x0])
+          .domain([-(x0+ (lwidth/2)), (x0+ (lwidth/2))])
           .range([0 , width])
           .nice()

@@ -53,11 +53,16 @@
             .duration(1000)
             .attr("width", (d, i) ->
               if i is 0
-                Math.abs(parseInt(x(d)) - parseInt(x(0) - (lwidth/2)))
-              else Math.abs(parseInt(x(d)) - parseInt(x(0) + (lwidth/2)))
+                return x(0) - x(d)
+              else
+                return x(d) - x(0)
             ).attr("x", (d, i) ->
-              if i is 0 then  x(Math.min(parseInt(x(0) - (lwidth/2)), d))
-              else x(0) + (lwidth/2))
+              if i is 0
+                return x(d) - (lwidth/2)
+              else
+                return x(0) + (lwidth/2)
+
+            )

         svg.selectAll('text')
           .data(this_data)


Fix open links for Android

Fix open links for Android

--- packages/rocketchat-ui/lib/cordova/urls.coffee
+++ packages/rocketchat-ui/lib/cordova/urls.coffee
@@ -10,9 +10,5 @@
 			url = $link.attr('href')

 			if /^https?:\/\/.+/.test(url) is true
-				switch platform
-					when 'ios'
-						window.open url, '_system'
-					when 'android'
-						navigator.app.loadUrl url, {openExternal: true}
-				e.preventDefault()+				window.open url, '_system'
+				e.preventDefault()


disable buy button after click

disable buy button after click

--- public/views/product_detail_view.coffee
+++ public/views/product_detail_view.coffee
@@ -139,6 +139,7 @@

   addLineItem: (event) ->
     event.preventDefault()
+    event.target.disabled = true # disable button

     if App.cart.isNew()
       App.cart.save().done =>


removed fat arrow, fixed oversized content issue (images clipping)

--- client/landing/app/Applications/Activity.kdapplication/ListItems/ActivityListItemStatusUpdate.coffee
+++ client/landing/app/Applications/Activity.kdapplication/ListItems/ActivityListItemStatusUpdate.coffee
@@ -17,17 +17,19 @@

     @embedBox = new EmbedBox embedOptions, data?.link

-  viewAppended:()=>
+  viewAppended:()->
     return if @getData().constructor is KD.remote.api.CStatusActivity
     super()
     @setTemplate @pistachio()
     @template.update()

     # If there is embed data in the model, use that!
-    if @getData()?.link
+    if @getData()?.link and link?.link_url is not ""
       if not ("embed" in @getData().link.link_embed_hidden_items)
         @embedBox.show()
-        @embedBox.embedExistingData @getData()?.link?.link_embed, {}
+        @embedBox.embedExistingData @getData()?.link?.link_embed, {
+          maxWidth: 720
+        }
       else
         # no need to show stuff if it should not be shown. not even in the code
         @embedBox.hide()
@@ -42,7 +44,8 @@
           firstUrl = $(url).attr "href"

       if firstUrl then @embedBox.embedUrl firstUrl, {}
-      else @embed
+      else
+        @embedBox.hide()

   render:=>
     super


fix for jasmine tests

fix for jasmine tests

--- js/tests/inner-tests.coffee
+++ js/tests/inner-tests.coffee
@@ -6,16 +6,19 @@
     min_parallelism: 1
     price: 19
     concurrency: 1
+    type: 'concurrency'
   p15:
     max_parallelism: 1
     min_parallelism: 1
     price: 49
     concurrency: 1
+    type: 'concurrency'
   p16:
     max_parallelism: 8
     min_parallelism: 2
     price: 149
     concurrency: 1
+    type: 'concurrency'

 testBilling = (plan, c, p, e) ->
   @expect((new CI.inner.Billing()).calculateCost(plan, c, p)).toEqual e


updated usage message.

updated usage message.

--- tron.coffee
+++ tron.coffee
@@ -4,21 +4,22 @@
   test:   (args...) ->
     usage = """

-     This simple function will define the way we test Socrenchus.
+     This simple function will define the way we test Socrenchus. You can do
+     things in most of the same ways you did them with the console.

      Call it with your test function like this:

-      console.test( ->
-        console.log( 'this writes to the log' )
-        console.info( 'this is an info message' )
-        console.warn( 'this is a warning' )
-        console.error( 'this is an error' )
+      tron.test( ->
+        tron.log( 'this writes to the log' )
+        tron.info( 'this is an info message' )
+        tron.warn( 'this is a warning' )
+        tron.error( 'this is an error' )
       )

     """
     for a in args
       unless typeof a == 'function'
-        console.warn(usage)
+        @warn(usage)
       else
         a()


Change 'not' to an exclamation mark and 'is' to '==' for consistency.

--- src/Bacon.coffee
+++ src/Bacon.coffee
@@ -443,12 +443,12 @@
       else
         @push event)

-  skipDuplicates: (isEqual = (a, b) -> a is b) ->
+  skipDuplicates: (isEqual = (a, b) -> a == b) ->
     withDescription(this, "skipDuplicates",
       @withStateMachine None, (prev, event) ->
         unless event.hasValue()
           [prev, [event]]
-        else if event.isInitial() or prev == None or not isEqual(prev.get(), event.value())
+        else if event.isInitial() or prev == None or !isEqual(prev.get(), event.value())
           [new Some(event.value()), [event]]
         else
           [prev, []])
@@ -819,7 +819,7 @@
       desc = []
     super(desc)
     assertFunction(subscribe)
-    if handler is true
+    if handler == true
       @subscribeInternal = subscribe
     else
       @subscribeInternal = new PropertyDispatcher(this, subscribe, handler).subscribe
@@ -924,7 +924,7 @@
       subscriptions = _.without(subscription, subscriptions)
     pushIt = (event) ->
       unless pushing
-        return if event is prevError
+        return if event == prevError
         prevError = event if event.isError()
         success = false
         try
@@ -1536,7 +1536,7 @@
     -1
   head: (xs) -> xs[0]
   always: (x) -> (-> x)
-  negate: (f) -> (x) -> not f(x)
+  negate: (f) -> (x) -> !f(x)
   empty: (xs) -> xs.length == 0
   tail: (xs) -> xs[1...xs.length]
   filter: (f, xs) ->
@@ -1592,7 +1592,7 @@
       else if isArray(obj)
         return "[..]" if recursionDepth > 5
         "[" + _.map(_.toString, obj).toString() + "]"
-      else if obj?.toString? and obj.toString!=Object.prototype.toString
+      else if obj?.toString? and obj.toString != Object.prototype.toString
         obj.toString()
       else if (typeof obj == "object")
         return "{..}" if recursionDepth > 5


Update upvotes and comments inputs based on cluster analysis


added alt+enter keybinding to trigger get-code-action

--- keymaps/omnisharp-atom.cson
+++ keymaps/omnisharp-atom.cson
@@ -32,6 +32,8 @@
   'ctrl-alt-up': 'omnisharp-atom:navigate-up'
   'ctrl-alt-down': 'omnisharp-atom:navigate-down'
   'ctrl-.': 'omnisharp-atom:get-code-actions'
+  'alt-enter': 'omnisharp-atom:get-code-actions'
+

 '.platform-darwin atom-text-editor:not([mini])[data-grammar~="cs"], atom-text-editor:not([mini])[data-grammar~="csx"]':
   'cmd-d': 'omnisharp-atom:go-to-definition'


Unused var.

Unused var.

--- src/Rickshaw.js.coffee
+++ src/Rickshaw.js.coffee
@@ -9,7 +9,6 @@
   version: "0.0.1"

   Templates: {}
-  Persistence: {}

   # Contains every single Rickshaw object, keyed by uuid. This means we keep
   # at least one reference to every single object, regardless if anything else


Don't return obj

Don't return obj

--- services/real-time/app/coffee/Router.coffee
+++ services/real-time/app/coffee/Router.coffee
@@ -100,7 +100,7 @@
 					# Called with 4 args, things are as expected
 				else
 					logger.error { arguments: arguments }, "unexpected arguments"
-					return {} # ????
+					return # ????

 				WebsocketController.joinDoc client, doc_id, fromVersion, options, (err, args...) ->
 					if err?


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/color.coffee
+++ src/color.coffee
@@ -41,7 +41,8 @@
     parsedColor = null

     if arguments.length == 2
-      parsedColor = [parseInt(arguments[0][0]), parseInt(arguments[0][1]), parseInt(arguments[0][2]), parseFloat(arguments[1])]
+      if Object.prototype.toString.call(arguments[0]) == '[object Array]'
+        parsedColor = [parseInt(arguments[0][0]), parseInt(arguments[0][1]), parseInt(arguments[0][2]), parseFloat(arguments[1])]
     else if arguments.length > 2
       alpha = if arguments[3]? then arguments[3] else 1
       parsedColor = [parseInt(arguments[0]), parseInt(arguments[1]), parseInt(arguments[2]), parseFloat(alpha)]


Remove timeout from root path

Remove timeout from root path

--- app._coffee
+++ app._coffee
@@ -56,8 +56,8 @@
 ## ROUTES:

 app.get '/', (req, res, _) ->
-    setTimeout _, 500   # mimic async operation
-    res.json 'Hello world.'
+    res.send 'ZoomHub'
+

 app.get '/content', (req, res, _) ->
     url = req.query?.url


preventDefault on touchstart events

preventDefault on touchstart events

--- lib/app.init.coffee
+++ lib/app.init.coffee
@@ -99,6 +99,7 @@
 exports.init = ()->
   initialCleanupAndTransform()
   setPresentationMode(MODES.AUDIENCE)
+  $("body").bind("touchstart", (ev) -> ev.preventDefault())
   Reveal.initialize(
     keyboard: false,
     rollingLinks: false


Add logging for debug

Add logging for debug

--- lib/arrivals.coffee
+++ lib/arrivals.coffee
@@ -34,6 +34,6 @@
         waiting_time: i.WAITING_TIME
     },{ upsert: true }
   # Empty out old data
-  Arrivals.remove {
-    next_arr: { $lt: moment().unix() }
-  }
+  #Arrivals.remove {
+  #  next_arr: { $lt: moment().unix() }
+  #}


Actully eff it, lets just run it manually

--- scripts/rtc.coffee
+++ scripts/rtc.coffee
@@ -40,7 +40,7 @@
         msg.send err
     )

-# module.exports = (robot) ->
-#   robot.hear /rtc #?(\d+)/ig, (msg) ->
-#     for bug in distinctBugs msg.match
-#       fetchSummary msg, bug
+module.exports = (robot) ->
+  robot.hear /rtc #?(\d+)/ig, (msg) ->
+    for bug in distinctBugs msg.match
+      fetchSummary msg, bug


improvements for object/class computed property name support

--- lib/compiler.coffee
+++ lib/compiler.coffee
@@ -1348,32 +1348,32 @@

                 # gather all properties so we can emit get+set as a single call to define_accessor_prop.
                 for property in n.properties
-                        if property.key.type is ComputedPropertyKey
-                                key = @visit property.key.expression
-                        else if property.key.type is Literal
-                                key = @getAtom String(property.key.value)
-                        else if property.key.type is Identifier
-                                key = @getAtom property.key.name
-
                         if property.kind is "get" or property.kind is "set"
-                                accessor_map.set(key, new Map) if not accessor_map.has(key)
-                                throw new SyntaxError "a '#{property.kind}' method for '#{key}' has already been defined." if accessor_map.get(key).has(property.kind)
-                                throw new SyntaxError "#{property.key.loc.start.line}: property name #{key} appears once in object literal." if accessor_map.get(key).has("init")
+                                accessor_map.set(property.key, new Map) if not accessor_map.has(property.key)
+                                throw new SyntaxError "a '#{property.kind}' method for '#{escodegen.generate property.key}' has already been defined." if accessor_map.get(property.key).has(property.kind)
+                                throw new SyntaxError "#{property.key.loc.start.line}: property name #{escodegen.generate property.key} appears once in object literal." if accessor_map.get(property.key).has("init")
                         else if property.kind is "init"
-                                throw new SyntaxError "#{property.key.loc.start.line}: property name #{key} appears once in object literal." if accessor_map.has(key)
-                                accessor_map.set(key, new Map)
+                                throw new SyntaxError "#{property.key.loc.start.line}: property name #{escodegen.generate property.key} appears once in object literal." if accessor_map.get(property.key)
+                                accessor_map.set(property.key, new Map)
                         else
                                 throw new Error("unrecognized property kind `#{property.kind}'")

-                        accessor_map.get(key).set(property.kind, property)
+                        accessor_map.get(property.key).set(property.kind, property)

                 accessor_map.forEach (prop_map, propkey) =>
                         # XXX we need something like this line below to handle computed properties, but those are broken at the moment
                         #key = if property.key.type is Identifier then @getAtom property.key.name else @visit property.key

+                        if propkey.type is ComputedPropertyKey
+                                propkey = @visit property.key.expression
+                        else if propkey.type is Literal
+                                propkey = @getAtom String(property.key.value)
+                        else if propkey.type is Identifier
+                                propkey = @getAtom property.key.name
+
                         if prop_map.has("init")
                                 val = @visit(prop_map.get("init").value)
-                                @createCall @ejs_runtime.object_define_value_prop, [obj, propkey, val, consts.int32 0x77], "define_value_prop_#{key}"
+                                @createCall @ejs_runtime.object_define_value_prop, [obj, propkey, val, consts.int32 0x77], "define_value_prop_#{propkey}"
                         else
                                 getter = prop_map.get("get")
                                 setter = prop_map.get("set")
@@ -1381,7 +1381,7 @@
                                 get_method = if getter then @visit(getter.value) else @loadUndefinedEjsValue()
                                 set_method = if setter then @visit(setter.value) else @loadUndefinedEjsValue()

-                                @createCall @ejs_runtime.object_define_accessor_prop, [obj, propkey, get_method, set_method, consts.int32 0x19], "define_accessor_prop_#{key}"
+                                @createCall @ejs_runtime.object_define_accessor_prop, [obj, propkey, get_method, set_method, consts.int32 0x19], "define_accessor_prop_#{propkey}"

                 obj


Updated the logs #gploy #stage #live

Updated the logs #gploy #stage #live

--- src/gploy.coffee
+++ src/gploy.coffee
@@ -9,6 +9,7 @@
 	connection	: null

 	constructor: ->
+
 		if process.argv[2] == "init"
 			new Generator()
 		else
@@ -28,5 +29,5 @@
 			@connection.completed.add @deploy
 			@servers.shift()
 		else
-			console.log "All Completed".green.bold
+			console.log "All Completed :)".green.bold
 			process.exit(code=0)


move ls -la from readstream

move ls -la from readstream

--- src/controllers/index.coffee
+++ src/controllers/index.coffee
@@ -46,14 +46,16 @@

     form_data = new FormData()
     #form_data.append 'photo', body
+
+    console.log 'read_stream is opened!!! executing ls -ls'
+    exec "ls -la", (error, stdout, stderr) ->
+      sys.puts stdout
+      console.log 'Error: ' + error
+      console.log 'Stdout: ' + stdout
+      console.log 'Stderr: ' + stderr
+
     read_stream = fs.createReadStream(__dirname + '/life_is_random.jpg')
     read_stream.on 'open', ->
-      console.log 'read_stream is opened!!! executing ls -ls'
-      exec "ls -la", (error, stdout, stderr) ->
-        sys.puts stdout
-        console.log 'Error: ' + error
-        console.log 'Stdout: ' + stdout
-        console.log 'Stderr: ' + stderr
       #console.log read_stream
       #form_data.append 'photo', read_stream
       #console.log form_data.getHeaders()


* [bug] recursive can work now. * remove config files from parent's dir list. + only frontMatter markdown text file.

--- src/index.coffee
+++ src/index.coffee
@@ -16,6 +16,13 @@
 setImmediate  = setImmediate || process.nextTick
 Promise.promisifyAll File, filter:(name,fn)->name in ['load']

+markdownExts = [
+  '.txt'
+  '.md', '.mdown', '.markdown', '.mkd','.mkdn'
+  '.mdwn', '.mdtext','.mdtxt'
+  '.text'
+]
+
 module.exports = class Resource
   inherits Resource, File
   @setFileSystem: CustomFile.setFileSystem
@@ -105,8 +112,9 @@
   # frontMatter('---\ntitle: 1\n---\nbody')
   # return {title:1, skipSize: 17, content: 'body', $compiled:[...]}
   frontMatter: (aText, aOptions)->
-    result = matter(aText, aOptions)
-    # TODO:whether export the non-enumerable $compiled attribute?
+    if @extname in markdownExts
+      result = matter(aText.toString(), aOptions)
+      # TODO:whether export the non-enumerable $compiled attribute?
     result

   convertVirtualFolder: (aContents)->
@@ -121,24 +129,29 @@
     processCfg = (err, aConfig)->
       return done(err) if err
       if aConfig
-        that.assign aConfig
+        that.assign aConfig, 'contents'
         if that.isDirectory()
           if aConfig.contents #virtual folder
-            that.convertVirtualFolder(result.contents)
-            aContents = result.contents
+            that.convertVirtualFolder(aConfig.contents)
+            aContents = aConfig.contents
           if aOptions.recursive
-            aContents = aContents.filter (f)->f.isDirectory()
-            Promise.map aContents, (f)->
-              f.load aOptions if f instanceof Resource
-            .nodeify (err, result)->
-              done(err, aConfig)
-            return
+            aContents.forEach (f)->
+              f.loadSync aOptions if (f instanceof Resource) and f.isDirectory()
+            #aContents = aContents.filter (f)->(f instanceof Resource) and f.isDirectory()
+            # can not work!!:
+            # Promise.map aContents, (f)->
+            #   f.load aOptions
+            # .nodeify (err, result)->
+            #   done(err, aConfig)
+            # return
       done(err, aConfig)
       return

     if !aOptions.stat.isDirectory()
-      vFrontConf = @frontMatter(aContents.toString(), aOptions)
-      loadCfgFile aOptions.path, aOptions, (err, result)->
+      vFrontConf = @frontMatter(aContents, aOptions)
+      vOptions = exclude: aOptions.path #avoid load twice.
+      vOptions.configurators = aOptions.configurators if aOptions.configurators
+      loadCfgFile aOptions.path, vOptions, (err, result)->
         return done(err) if err
         if vFrontConf and vFrontConf.skipSize
           result = {} unless isObject result
@@ -157,7 +170,9 @@
   loadConfigSync: (aOptions, aContents)->
     if !aOptions.stat.isDirectory()
       vFrontConf = @frontMatter(aContents.toString(), aOptions)
-      result = loadCfgFile aOptions.path, aOptions
+      vOptions = exclude: aOptions.path #avoid load twice.
+      vOptions.configurators = aOptions.configurators if aOptions.configurators
+      result = loadCfgFile aOptions.path, vOptions
       result = {} unless isObject result
       if vFrontConf and vFrontConf.skipSize
         result = extend result, vFrontConf
@@ -169,7 +184,7 @@
     else
       result = loadCfgFolder aOptions.path, aOptions
     if result
-      @assign result
+      @assign result, 'contents'
       @$cfgPath = result.$cfgPath if result.$cfgPath
       if @isDirectory()
         if result.contents #virtual folder
@@ -177,9 +192,9 @@
           aContents = result.contents
         if aOptions.recursive
           # TODO: it must be loaded first if the file treat as virtual folder.
-          aContents = aContents.filter (f)->f.isDirectory()
-          for vFile in aContents
-            vFile.loadSync aOptions if vFile instanceof Resource
+          aContents.forEach (f)->
+            if (f instanceof Resource) and f.isDirectory()
+              f.loadSync aOptions if result
     result

   _getBufferSync: (aFile)->
@@ -188,7 +203,10 @@
     if conf
       result = conf.contents if conf.contents
       if conf.$cfgPath
-        result = result.filter (f)->f.path isnt conf.$cfgPath
+        if @isDirectory()
+          result = result.filter (f)->f.path isnt conf.$cfgPath
+        else if (vDir = @parent)
+          vDir.contents = vDir.contents.filter (f)->f.path isnt conf.$cfgPath
     result

   _getBuffer: (aFile, done)->
@@ -200,4 +218,9 @@
         if conf
           #extend that, conf
           result = conf.contents if conf.contents
+          if conf.$cfgPath
+            if that.isDirectory()
+              result = result.filter (f)->f.path isnt conf.$cfgPath
+            else if (vDir = that.parent)
+              vDir.contents = vDir.contents.filter (f)->f.path isnt conf.$cfgPath
         done(err, result)


fix typo

fix typo

--- src/nodes.coffee
+++ src/nodes.coffee
@@ -922,7 +922,7 @@
   # then export it here
   icedToSlot : (i) ->
     return @base.icedToSlot i if @base instanceof Obj
-    sufffix = null
+    suffix = null
     if @properties and @properties.length
       suffix = @properties.pop()
     return new Slot i, this, suffix


Checks for empty message by trim()ing the input

Signed-off-by: Akash Manohar J <e4cf979cf717fd295f4e4edc427ee1aee78fa7dc@akash.im>

--- app/assets/javascripts/backbone/views/chatbox.js.coffee
+++ app/assets/javascripts/backbone/views/chatbox.js.coffee
@@ -16,8 +16,11 @@

   postMessage: (event)->
     $chatbox = $(event.target).parent().find(".chat-input")
+    chatInput = $chatbox.val()
+    return false if chatInput.trim().length==0
+
     activity = new Kandan.Models.Activity({
-      'content':    $chatbox.val(),
+      'content':    chatInput,
       'action':     'message',
       'channel_id': @channel.get('id')
     })


Fixed the "read all entries" feature.

Fixed the "read all entries" feature.

--- app/assets/javascripts/ng-services/ng-FindSvc.js.coffee
+++ app/assets/javascripts/ng-services/ng-FindSvc.js.coffee
@@ -18,6 +18,8 @@
   find_folder: (id)->
     if id == 'none'
       return null
+    else if id == "all"
+      return {id: "all"}
     else
       folders = $filter('filter') $rootScope.folders, {id: id}
       return folders[0]


avoid NaN in average implementation.

avoid NaN in average implementation.

--- web/site/src/javascript/status/StatusDrawer.coffee
+++ web/site/src/javascript/status/StatusDrawer.coffee
@@ -21,7 +21,7 @@
 do -> Array::filter ?= (callback) ->
   element for element in this when callback element
 do -> Array::sum ?= -> @reduce ((a, b) -> a + b), 0
-do -> Array::average ?= -> do @sum / @length
+do -> Array::average ?= -> if @length then do @sum / @length else 0

 # helper functions


image zoom working

image zoom working

--- app/assets/javascripts/spree/frontend/product.js.coffee
+++ app/assets/javascripts/spree/frontend/product.js.coffee
@@ -10,8 +10,6 @@
       ($ '#main-image').data 'selectedThumbId', ($ event.currentTarget).parent().attr('id')
       thumbnails.find('li').removeClass 'selected'
       ($ event.currentTarget).parent('li').addClass 'selected'
-
-
       false

     thumbnails.find('li').on 'mouseenter', (event) ->
@@ -21,6 +19,7 @@

     thumbnails.find('li').on 'mouseleave', (event) ->
       ($ '#main-image img').attr 'src', ($ '#main-image').data('selectedThumb')
+

   Spree.showVariantImages = (variantId) ->
     ($ 'li.vtmb').hide()


use utils.jsonp() in FileGroup

use utils.jsonp() in FileGroup

--- app/assets/javascripts/uploadcare/files/group.js.coffee
+++ app/assets/javascripts/uploadcare/files/group.js.coffee
@@ -106,13 +106,9 @@
           data =
             pub_key: @settings.publicKey
             files: (info.uuid for info in infos)
-          $.ajax("#{@settings.urlBase}/group/", {data, dataType: 'jsonp'})
+          utils.jsonp("#{@settings.urlBase}/group/", data)
             .fail(df.reject)
-            .done (data) ->
-              if data.error
-                df.reject()
-              else
-                df.resolve(data)
+            .done(df.resolve)
       else
         df.reject()
       return df.promise()
@@ -156,13 +152,10 @@
       data =
         pub_key: settings.publicKey
         group_id: id[0]
-      $.ajax("#{settings.urlBase}/group/info/", {data, dataType: 'jsonp'})
+      utils.jsonp("#{settings.urlBase}/group/info/", data)
         .fail(df.reject)
         .done (data) ->
-          if data.error
-            df.reject()
-          else
-            df.resolve new uploadcare.files.SavedFileGroup(data, settings).api()
+          df.resolve new uploadcare.files.SavedFileGroup(data, settings).api()
     else
       df.reject()
     df.promise()


Message previously posted by the same person should be appended by a new message.

--- app/assets/javascripts/web/views/message_view.js.coffee
+++ app/assets/javascripts/web/views/message_view.js.coffee
@@ -21,6 +21,9 @@
       @set('shouldScrollToMessage', false)
     , 100

+    if @get('context').get('hasSameAuthorAsPrevious')
+      @.$().prevAll('.message').first().removeClass('message-last')
+
     @.$('a[internal]').on('click', (e) =>
       event.preventDefault()
       @get('container')


changed verbiage in tests; moved some around

--- spec/public/specs/jquery.msgbox_spec.coffee
+++ spec/public/specs/jquery.msgbox_spec.coffee
@@ -3,7 +3,7 @@
   it "should be defined", ->
     expect($.msgbox).not.toEqual undefined

-  it "should not have a #msgbox div on the page before running $.msgbox", ->
+  it "should not have a #msgbox div on the page before calling $.msgbox", ->
     expect($("#msgbox").length).toEqual 0

   it "should create a new div with the id #msgbox", ->
@@ -11,7 +11,12 @@
     $.msgbox 'close'
     expect($("#msgbox").length).toEqual 1

-  it "should have created a .ui-dialog class", ->
+  it "should only have one #msgbox div after being reused", ->
+    $.msgbox 'hello', 'again'
+    expect($("#msgbox").length).toEqual 1
+    $.msgbox 'close'
+
+  it "should have a new jQuery UI dialog", ->
     expect($(".ui-dialog").length).toEqual 1

   it "should default to 'alert' icon", ->
@@ -25,12 +30,7 @@

   it "should have no icon when options.icon is null", ->
     $.msgbox 'hello','world', icon: null
-    $.msgbox 'close'
     expect($("#msgbox-icon").length).toEqual 0
-
-  it "should only have one #msgbox div after being reused", ->
-    $.msgbox 'hello', 'again'
-    expect($("#msgbox").length).toEqual 1
     $.msgbox 'close'

   it "should change the title after being reused", ->


JUser: code cleanup

JUser: code cleanup

--- workers/social/lib/social/models/user/index.coffee
+++ workers/social/lib/social/models/user/index.coffee
@@ -1028,27 +1028,9 @@
         res.forbidden = if username in @bannedUserList then yes else no
         callback null, res

-  confirmEmail:(callback)->
-    @update {$set:email:'confirmed'}, callback
-
-  fetchContextualAccount:(context, rest..., callback)->
-    # Relationship.one {
-    #   as          : 'owner'
-    #   sourceId    : @getId()
-    #   targetName  : 'JAccount'
-    #   'data.context': context
-    # }, (err, account)=>
-    #   if err
-    #     callback err
-    #   else if account?
-    #     callback null, account
-    #   else
-    #     @fetchOwnAccount rest..., callback

   fetchAccount:(context, rest...)->
     @fetchOwnAccount rest...
-    # if context is 'koding' then @fetchOwnAccount rest...
-    # else @fetchContextualAccount context, rest...

   setPassword:(password, callback)->
     salt = createSalt()


Call callback before creating the activity as much as fastest.

--- workers/social/lib/social/traits/followable.coffee
+++ workers/social/lib/social/traits/followable.coffee
@@ -62,7 +62,7 @@
             as        : 'follower'
           }, (err, count)->
             if err then callback err
-            else
+            else
               model.followee = count > 0
               callback null, model

@@ -121,7 +121,6 @@
           else
             Module::update.call @, $set: 'counts.followers': count, (err)->
               if err then log err
-            # callback err, count
             action = "follow"
             @emit 'FollowCountChanged'
               followerCount   : @getAt('counts.followers')
@@ -135,6 +134,9 @@
               action  : action

             follower.updateFollowingCount @, action
+
+            callback err, count
+
             Relationship.one {sourceId, targetId, as:'follower'}, (err, relationship)=>
               if err
                 callback err
@@ -143,11 +145,11 @@
                 if emitActivity
                   CBucket.addActivities relationship, @, follower, (err)->
                     if err
-                      # console.log "An Error occured: ", err
-                      callback err
-                    else
-                      callback null, count
-                else callback null, count
+                      console.log "An Error occured: ", err
+                      # callback err
+                #     else
+                #       callback null, count
+                # else callback null, count

   unfollow: secure (client,callback)->
     JAccount = require '../models/account'