Disable buggy error module.

Disable buggy error module.

--- app/javascripts/error.coffee
+++ app/javascripts/error.coffee
@@ -4,82 +4,87 @@
   # (cf. https://code.google.com/p/chromium/issues/detail?id=331971)
   # which truncates long error messages. This code is copied from
   # http://stackoverflow.com/a/22218280/674326.
-  window.onerror = (errorMsg, url, lineNumber, columnNumber, errorObject) ->
-    # Check the errorObject as IE and FF don't pass it through (yet).
-    if errorObject?
-      errMsg = errorObject.message
-    else
-      errMsg = errorMsg
-    alert('Error: ' + errMsg)
-
-  # The error handler module.
   #
-  # Note: testing this module is prohibitively difficult. Suggestions for
-  # disabling the Mocha error trap don't work. ngMockE2E could be used to
-  # build a pseudo-app and HTML test harness, but that is not worth the
-  # trouble. The work-around to test this module is to introduce an error
-  # in the qiprofile code and check that it is logged on the server.
+  # TODO - The handler breaks with error:
+  #     sourceMappingURL not found
+  #   Uncomment, induce an error and fix. See following TODO and FIXME items.
+  #
+  # window.onerror = (errorMsg, url, lineNumber, columnNumber, errorObject) ->
+  #   # Check the errorObject as IE and FF don't pass it through (yet).
+  #   if errorObject?
+  #     errMsg = errorObject.message
+  #   else
+  #     errMsg = errorMsg
+  #   alert('Error: ' + errMsg)
+  #
+  # # The error handler module.
+  # #
+  # # Note: testing this module is prohibitively difficult. Suggestions for
+  # # disabling the Mocha error trap don't work. ngMockE2E could be used to
+  # # build a pseudo-app and HTML test harness, but that is not worth the
+  # # trouble. The work-around to test this module is to introduce an error
+  # # in the qiprofile code and check that it is logged on the server.
   error = ng.module 'qiprofile.error', []
-
-  # Augment the Angular exception handler to print an error on both
-  # the console (the default behavior) and the server.
-  error.factory '$exceptionHandler', ['$log', '$window', ($log, $window) ->
-    (exception, cause) ->
-      # Print the error on the console.
-      $log.error.apply($log, arguments)
-      # Send the error to the server.
-      # TODO - given the FIXMEs below, revisit this module, look for good
-      #   usage examples and either fix or kill it.
-      try
-        message = "#{ exception }"
-        # FIXME - stacktrace.fromError returns an empty string in
-        #   E2E Session Detail testing when the download.isDisplayed
-        #   function is not found, with the following message:
-        #     Client error: TypeError: download.isDisplayed is not a function.
-        #   Don't know if that is always the case.
-        # TODO - Induce an error by replacing download.isDisplayed with
-        #   download.fooBar and isolate the problem.
-        #
-        # FIXME - after the AngularJS 1.4.9 upgrade, an error fetching
-        #   a REST object results in a JSON parser error which in turn
-        #   causes a secondary stackTrace.fromError error with the following
-        #   message:
-        #      TypeError('Given line number must be a positive integer')
-        #   deep in the obscure stackTrace code. Work-around is to pass
-        #   over the stack trace and handle the failed failure handler
-        #   gracefully.
-        try
-          stackTrace = stacktrace.fromError(exception)
-        catch TypeError
-          stackTrace = null
-        # The object to send.
-        payload =
-          url: $window.location.href
-          name: exception.name
-          message: message
-          stackTrace: stackTrace
-          cause: cause or ''
-        # Send the object to the server.
-        # Note: can't use the File service, since File depends on
-        # $exceptionHandler.
-        xhr = new window.XMLHttpRequest()
-        xhr.open('POST', '/error', true)
-        xhr.setRequestHeader('Content-type', 'application/json')
-        # The XHR request is retransmitted several times.
-        # Consequently, the error is logged multiple times on the server.
-        # Prevent this by throttling the send back to once per second
-        # (which usually means only once).
-        #
-        # FIXME - the lodash throttle below has no effect. Why not?
-        #   send = -> xhr.send(ng.toJson(payload))
-        #   throttled = _.throttle(send, 1000)
-        #   throttled()
-        # TODO - fix above to replace below and remove the guard in the
-        #   server.coffee /error handler.
-        xhr.send(ng.toJson(payload))
-      catch loggingError
-        # Can't send the error to the server;
-        # Log to the client only.
-        $log.warn 'Error logging failed'
-        $log.log loggingError
-  ]
+  #
+  # # Augment the Angular exception handler to print an error on both
+  # # the console (the default behavior) and the server.
+  # error.factory '$exceptionHandler', ['$log', '$window', ($log, $window) ->
+  #   (exception, cause) ->
+  #     # Print the error on the console.
+  #     $log.error.apply($log, arguments)
+  #     # Send the error to the server.
+  #     # TODO - given the FIXMEs below, revisit this module, look for good
+  #     #   usage examples and either fix or kill it.
+  #     try
+  #       message = "#{ exception }"
+  #       # FIXME - stacktrace.fromError returns an empty string in
+  #       #   E2E Session Detail testing when the download.isDisplayed
+  #       #   function is not found, with the following message:
+  #       #     Client error: TypeError: download.isDisplayed is not a function.
+  #       #   Don't know if that is always the case.
+  #       # TODO - Induce an error by replacing download.isDisplayed with
+  #       #   download.fooBar and isolate the problem.
+  #       #
+  #       # FIXME - after the AngularJS 1.4.9 upgrade, an error fetching
+  #       #   a REST object results in a JSON parser error which in turn
+  #       #   causes a secondary stackTrace.fromError error with the following
+  #       #   message:
+  #       #      TypeError('Given line number must be a positive integer')
+  #       #   deep in the obscure stackTrace code. Work-around is to pass
+  #       #   over the stack trace and handle the failed failure handler
+  #       #   gracefully.
+  #       try
+  #         stackTrace = stacktrace.fromError(exception)
+  #       catch TypeError
+  #         stackTrace = null
+  #       # The object to send.
+  #       payload =
+  #         url: $window.location.href
+  #         name: exception.name
+  #         message: message
+  #         stackTrace: stackTrace
+  #         cause: cause or ''
+  #       # Send the object to the server.
+  #       # Note: can't use the File service, since File depends on
+  #       # $exceptionHandler.
+  #       xhr = new window.XMLHttpRequest()
+  #       xhr.open('POST', '/error', true)
+  #       xhr.setRequestHeader('Content-type', 'application/json')
+  #       # The XHR request is retransmitted several times.
+  #       # Consequently, the error is logged multiple times on the server.
+  #       # Prevent this by throttling the send back to once per second
+  #       # (which usually means only once).
+  #       #
+  #       # FIXME - the lodash throttle below has no effect. Why not?
+  #       #   send = -> xhr.send(ng.toJson(payload))
+  #       #   throttled = _.throttle(send, 1000)
+  #       #   throttled()
+  #       # TODO - fix above to replace below and remove the guard in the
+  #       #   server.coffee /error handler.
+  #       xhr.send(ng.toJson(payload))
+  #     catch loggingError
+  #       # Can't send the error to the server;
+  #       # Log to the client only.
+  #       $log.warn 'Error logging failed'
+  #       $log.log loggingError
+  # ]


Use Workspace::addModalPanel to attach BookmarksView

--- lib/bookmarks-view.coffee
+++ lib/bookmarks-view.coffee
@@ -6,17 +6,31 @@
 class BookmarksView extends SelectListView
   initialize: ->
     super
-    @addClass('bookmarks-view overlay from-top')
+    @addClass('bookmarks-view')

   getFilterKey: ->
     'filterText'

+  attached: ->
+    @focusFilterEditor()
+
+  show: ->
+    @storeFocusedElement()
+    @panel ?= atom.workspace.addModalPanel(item: this)
+    @panel.show()
+
+  hide: ->
+    @panel.hide()
+
+  cancelled: ->
+    @hide()
+
   toggle: ->
-    if @hasParent()
-      @cancel()
+    if @isVisible()
+      @hide()
     else
       @populateBookmarks()
-      @attach()
+      @show()

   getFilterText: (bookmark) ->
     segments = []
@@ -68,8 +82,3 @@
     atom.workspace.open(buffer.getPath()).done (editor) ->
       editor.setSelectedBufferRange?(marker.getRange(), autoscroll: true)
     @cancel()
-
-  attach: ->
-    @storeFocusedElement()
-    atom.views.getView(atom.workspace).appendChild(@element)
-    @focusFilterEditor()


Fetch followed activities from clicking Followed on Activity

No limit, no sorting at the moment.

--- client/landing/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Activity.kdapplication/AppController.coffee
@@ -243,14 +243,27 @@
     controller.noActivityItem.hide()

     if show is 'private'
-      _counter = 0
-      controller._state = 'private'
-      controller.itemsOrdered.forEach (item)=>
-        if not controller.isInFollowing(item.data)
-          item.hide()
-          _counter++
-      if _counter is controller.itemsOrdered.length
-        controller.noActivityItem.show()
+      # _counter = 0
+      # controller._state = 'private'
+      # controller.itemsOrdered.forEach (item)=>
+      #   if not controller.isInFollowing(item.data)
+      #     item.hide()
+      #     _counter++
+      # if _counter is controller.itemsOrdered.length
+      #   controller.noActivityItem.show()
+      controller.removeAllItems()
+      controller.showLazyLoader no
+
+      KD.whoami().fetchFeeds (err, feeds) =>
+        for feed in feeds
+          continue unless feed.title is 'followed'
+          feed.fetchActivities (err, activities) =>
+            for activity in activities
+              @activityListController.addItem activity
+            controller.isLoading = no
+            controller.hideLazyLoader()
+            #callback?()
+
       return no

     else if show is 'public'


Revert "Revert "fix following facets, remove some of old cache stuff""

This reverts commit 0e2a7c04c23eebfc988a13d9a3e855cfa67c1c07.

--- client/landing/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Activity.kdapplication/AppController.coffee
@@ -108,17 +108,19 @@
     KD.time "Activity fetch took - "
     options = to : options.to or Date.now()

-    @fetchCachedActivity options, (err, cache)=>
+    @fetchActivity options, (err, teasers)=>
       @isLoading = no
-      if err or cache.length is 0
-        warn err  if err
-        @listController.hideLazyLoader()
+      @listController.hideLazyLoader()
+      KD.timeEnd "Activity fetch took"
+
+      if err or teasers.length is 0
+        warn "An error occured:", err  if err
         @listController.showNoItemWidget()
       else
-        @extractCacheTimeStamps cache
-        @sanitizeCache cache, (err, cache)=>
-          @listController.hideLazyLoader()
-          @listController.listActivitiesFromCache cache
+        @extractTeasersTimeStamps(teasers)
+        @listController.listActivities teasers
+
+      callback? err, teasers

   fetchActivitiesFromCache:(options = {})->
     @fetchCachedActivity options, (err, cache)=>
@@ -214,38 +216,17 @@
         createdAt : -1

     {CActivity}   = KD.remote.api
-    if KD.config.useNeo4j
-      options.feedType = @feedType
-
-      if options.facets is activityTypes
-        options.facets = ['Everything']
-
-      if @feedType is "Public"
-        options.groupId = KD.getSingleton("groupsController").getCurrentGroup().getId()
-        CActivity.fetchPublicContents options, callback
-      else
-        CActivity.fetchFolloweeContents options, callback
-
+    options.feedType = @feedType
+
+    if options.facets is activityTypes
+      options.facets = ['Everything']
+
+    if @feedType is "Public"
+      options.groupId = KD.getSingleton("groupsController").getCurrentGroup().getId()
+
+      @fetchActivitiesFromCache options, callback
     else
-      @isExempt (exempt)->
-        options.lowQuality = exempt
-        CActivity.fetchFacets options, (err, activities)->
-          if err
-            callback err
-          else if not exempt
-            KD.remote.reviveFromSnapshots clearQuotes(activities), callback
-          else
-            # trolls and admins in show troll mode will load data on request
-            # as the snapshots do not include troll comments
-            stack = activities.map (activity)-> (cb)->
-              activity.fetchTeaser (err, teaser)->
-                if err then console.warn 'could not fetch teaser'
-                else cb err, teaser
-                stack.fin()
-              , yes
-
-            dash stack, (err, res)->
-              callback null, res
+      CActivity.fetchFolloweeContents options, callback

   # Fetches activities that occured after the first entry in user feed,
   # used for minor disruptions.
@@ -293,23 +274,13 @@
         log "fetchSomeActivities timeout reached"

   fetchCachedActivity:(options = {}, callback)->
-    if KD.config.useNeo4j
-      options.timestamp or= options.to
-      options.groupName   = KD.getSingleton("groupsController").getCurrentGroup()?.slug or "koding"
-      options.facets      = @getFilter()
-
-      KD.remote.api.CStatusActivity.fetchPublicActivityFeed options, (err, result)=>
-        result.overview.reverse() if result?.overview
-        return callback err, result
-
-    else
-      $.ajax
-        url     : "/-/cache/#{options.slug or 'latest'}"
-        cache   : no
-        error   : (err)->   callback? err
-        success : (cache)->
-          cache.overview.reverse()  if cache?.overview
-          callback null, cache
+    options.timestamp or= options.to
+    options.groupName   = KD.getSingleton("groupsController").getCurrentGroup()?.slug or "koding"
+    options.facets      = @getFilter()
+
+    KD.remote.api.CStatusActivity.fetchPublicActivityFeed options, (err, result)=>
+      result.overview.reverse() if result?.overview
+      return callback err, result

   continueLoadingTeasers:->
     # fix me


fixed delete method

fixed delete method

--- src/index.coffee
+++ src/index.coffee
@@ -73,7 +73,7 @@

             delete: ()->
                 console.log("deleting")
-                if @id?
+                if @_id?
                     cb = (err, res) ->
                         #TODO handle error
                         console.log("deleted")


Get rid of logging

Get rid of logging

--- src/index.coffee
+++ src/index.coffee
@@ -7,5 +7,4 @@

   module.exports = Ubret
 else
-  console.log 'here'
   window.Ubret = {}


Fixed bug in action_create in src/index.coffee

--- src/index.coffee
+++ src/index.coffee
@@ -179,7 +179,7 @@
         if (not related.idParam of item) or (not item[related.idParam])
           item[related.idParam] = related_id
     item.save (err) =>
-      return res.send(500, { error: "#{err}", id: id })  if err
+      return res.send(500, { error: "#{err}" })  if err
       #console.log("created #{@name} with id:#{item.id}")
       if (req.body._format? and req.body._format == 'html') or (format == 'html')
         return res.redirect @_mount_info.url_prefix + "/#{item.id}" + ".html"


prevent exception when locale string doesn't match. fixes #5.

--- src/index.coffee
+++ src/index.coffee
@@ -13,9 +13,9 @@
   @default: new Locale process.env.LANG or "en_US"

   constructor: (str) ->
-    return unless str
+    return unless match = str?.match /[a-z]+/gi

-    [language, country] = str.match /[a-z]+/gi
+    [language, country] = match

     @language = do language.toLowerCase
     @country  = do country.toUpperCase if country


Checks for isReciprocated truth before reciprocating

--- src/index.coffee
+++ src/index.coffee
@@ -36,13 +36,16 @@
           .zadd("#{@namespace}:#{@followingKey}:#{fromId}", getEpoch(), toId)
           .zadd("#{@namespace}:#{@followersKey}:#{toId}", getEpoch(), fromId)
           .exec (err, replies) ->
+            console.log "Replies: #{replies.inspect}"
             self.isReciprocated fromId, toId, (result) ->
-              self.redis.multi()
-                .zadd("#{self.namespace}:#{self.reciprocatedKey}:#{fromId}", getEpoch(), toId)
-                .zadd("#{self.namespace}:#{self.reciprocatedKey}:#{toId}", getEpoch(), fromId)
-                .exec (err, replies) ->
-                  if callback?
-                    callback(true)
+              if result == true
+                self.redis.multi()
+                  .zadd("#{self.namespace}:#{self.reciprocatedKey}:#{fromId}", getEpoch(), toId)
+                  .zadd("#{self.namespace}:#{self.reciprocatedKey}:#{toId}", getEpoch(), fromId)
+                  .exec (err, replies) ->
+                    console.log "Replies: #{replies.inspect}"
+                    if callback?
+                      callback(true)

   unfollow: (fromId, toId, callback) ->
     if fromId == toId


Made express listen to a port

Made express listen to a port

Signed-off-by: Ian Macalinao <08370e385f4778cad8fe504ec5445edd3d45bd9a@gmail.com>

--- src/index.coffee
+++ src/index.coffee
@@ -2,3 +2,5 @@

 app.get '/', (req, res) ->
   res.send 'Hello, world!'
+
+app.listen 3000


Use suggested_topics passed as parameter, and fall back to collection with the single model

--- core/app/backbone/views/channels/add_channel_to_channels_button_view.coffee
+++ core/app/backbone/views/channels/add_channel_to_channels_button_view.coffee
@@ -19,14 +19,15 @@
     @$('.added-to-channel-button-label').toggle added
     @$('.add-to-channel-button-label').toggle not added

+  topic_suggestions: ->
+    @options.suggested_topics || new SuggestedTopics([@model.topic()])
+
   openAddToChannelModal: (e) ->
     e.stopImmediatePropagation()
     e.preventDefault()
-
-    suggestion_collection = @options.suggested_topics || new SuggestedTopics([@model.topic()])

     FactlinkApp.Modal.show 'Add to Channels',
       new AddChannelToChannelsModalView
             model: @model,
             collection: @collection
-            suggestions: suggestion_collection
+            suggestions: @topic_suggestions()


fix Twitter konnector

fix Twitter konnector

--- server/konnectors/twitter.coffee
+++ server/konnectors/twitter.coffee
@@ -121,7 +121,7 @@

                 if date > start

-                    twitterTweet = TwitterTweet
+                    twitterTweet =
                         date: date
                         text: tweet.text
                         id_str: tweet.id_str
@@ -130,8 +130,10 @@
                         isReplyTo: tweet.in_reply_to_status_id?
                         isRetweet: tweet.retweeted_status?

+                    console.log twitterTweet
+
                     numItems++
-                    twitterTweet.save (err) ->
+                    TwitterTweet.create twitterTweet, (err) ->
                         if err
                             cb err
                         else


uses extend in favor the spread syntax

uses extend in favor the spread syntax

--- lib/passport/callbacks.coffee
+++ lib/passport/callbacks.coffee
@@ -132,7 +132,7 @@
   else if msg.match('no account linked')?
     if (req?.session? && params?)
       { sign_up_intent, receive_emails, accepted_terms_of_service } = req.session
-      params = { ...params, ...{ sign_up_intent, receive_emails, accepted_terms_of_service } }
+      _.extend(params, { sign_up_intent, receive_emails, accepted_terms_of_service })

     req.artsyPassportSignedUp = true
     request


Added env to template context

Added env to template context

--- src/plugins/handlebars.coffee
+++ src/plugins/handlebars.coffee
@@ -20,6 +20,7 @@
         ctx = locals.page.serialize()
         ctx['contents'] = locals.contents
         ctx['locals'] = locals.env.locals
+        ctx['env'] = env
         rendered = @tpl ctx
         callback null, new Buffer rendered
       catch error


Remove menuCloseButton click event. Better handled in a Main Menu View.

--- js/flight.coffee
+++ js/flight.coffee
@@ -27,12 +27,6 @@

     @mainMenu = options.mainMenu if options.mainMenu?
     @mainMenu = document.querySelector @mainMenu if typeof @mainMenu is "string"
-
-    @menuCloseButton = options.menuCloseButton if options.menuCloseButton?
-    @menuCloseButton = document.querySelector @menuCloseButton if typeof @menuCloseButton is "string"
-
-    @menuCloseButton.addEventListener 'click', =>
-      @slideOutMenu()

     os = @detectUserAgent()
     @transitionAnimation = false if os.android and os.version <= '2.1'


getMerged: remove redundant code; bugfix

--- fetching.coffee
+++ fetching.coffee
@@ -397,7 +397,7 @@
             #       the logic, so there should not be any complications.
             #       We should try to merge $eq, $ne, $lt, $gt.
             if not _.isObject(expr1) and not _.isObject(expr2)
-                $in: [exp1, expr2]
+                $in: [expr1, expr2]
             else if _.isObject expr1
                 if expr1.$in is undefined
                     return { $ne: null }
@@ -431,29 +431,7 @@
                     if _.isObject(qs.selector) and _.isObject(selector) and
                             _.size(_.difference(_.keys(qs.selector), _.keys(selector))) is 0 # same selected fields
                         for s, val of qs.selector
-                            if _.isObject val
-                                if val.$in isnt undefined and _.keys(val).length is 1
-                                    # val is just { $in: ... }
-                                    if _.isObject selector[s]
-                                        if selector[s].$in isnt undefined and _.keys(selector[s]).length is 1
-                                            # selector[s] is also just { $in: ... }
-                                            selector[s].$in = selector[s].$in.concat val.$in
-                                        else
-                                            selector[s] = mergeSelectorExpressions selector[s], val
-                                    else # selector[s] is not an object
-                                        val.$in.push selector[s]
-                                        selector[s] = val
-                                else
-                                    selector[s] = mergeSelectorExpressions selector[s], val
-                            else # val is not an object
-                                if _.isObject selector[s]
-                                    if selector[s].$in isnt undefined and _.keys(selector[s]).length is 1
-                                        # selector[s] is just { $in: ... }
-                                        selector[s].$in.push val
-                                    else
-                                        selector[s] = mergeSelectorExpressions selector[s], val
-                                else # selector[s] is also not an object
-                                    selector[s] = $in: [selector[s], val]
+                            selector[s] = mergeSelectorExpressions selector[s], val
                         merged = true
                         break
                 if not merged


tweak: using `.` for separator (thanks @maxbrunsfeld)

--- lib/status-bar-manager.coffee
+++ lib/status-bar-manager.coffee
@@ -1,14 +1,14 @@
 {Disposable, CompositeDisposable} = require 'event-kit'

-# mode names can be combined with submode names with the `$` character
+# mode names can be combined with submode names with the `.` character
 # the order matters - the last matching entry wins
 ContentsByMode =
-  insert:           ["status-bar-vim-mode-insert", "Insert"]
-  insert$replace:   ["status-bar-vim-mode-insert", "Replace"]
-  command:          ["status-bar-vim-mode-command", "Command"]
-  visual:           ["status-bar-vim-mode-visual", "Visual"]
-  visual$linewise:  ["status-bar-vim-mode-visual", "Visual Line"]
-  visual$blockwise: ["status-bar-vim-mode-visual", "Visual Block"]
+  'insert':           ["status-bar-vim-mode-insert",  "Insert"]
+  'insert.replace':   ["status-bar-vim-mode-insert",  "Replace"]
+  'command':          ["status-bar-vim-mode-command", "Command"]
+  'visual':           ["status-bar-vim-mode-visual",  "Visual"]
+  'visual.linewise':  ["status-bar-vim-mode-visual",  "Visual Line"]
+  'visual.blockwise': ["status-bar-vim-mode-visual",  "Visual Block"]

 module.exports =
 class StatusBarManager
@@ -20,7 +20,7 @@
   initialize: (@statusBar) ->

   update: (currentMode, currentSubmode) ->
-    currentFullMode = currentMode + "$" + currentSubmode if currentSubmode?
+    currentFullMode = currentMode + "." + currentSubmode if currentSubmode?
     for mode, [klass, html] of ContentsByMode
       if mode is currentMode or mode is currentFullMode
         @element.classList.add(klass)


Update log.coffee

Update log.coffee

--- client/helpers/log.coffee
+++ client/helpers/log.coffee
@@ -1,2 +1,2 @@
-Blaze.registerHelper 'log', ->
-	console.log.apply console, arguments+Template.registerHelper 'log', ->
+	console.log.apply console, arguments


Fixed text box pointers being cut off from caching.

--- app/lib/surface/Label.coffee
+++ app/lib/surface/Label.coffee
@@ -172,7 +172,7 @@

     o.label.regX = background.regX - o.marginX
     o.label.regY = background.regY - o.marginY
-    background.cache(0, 0, w, h)
+    background.cache(-10, -10, w+20, h+20) # give a wide berth for speech box pointers

     g.endStroke()
     g.endFill()


Update fixture to empty data_units collection.

--- fixtures.coffee
+++ fixtures.coffee
@@ -30,9 +30,9 @@
                                                     if err
                                                         console.log('Error while emptying sensors')
                                                     else
-                                                        models.Sensor.remove({}, (err) ->
+                                                        models.DataUnit.remove({}, (err) ->
                                                             if err
-                                                                console.log('Error while emptying sensors')
+                                                                console.log('Error while emptying data_units')
                                                             else
                                                                 console.log('Database emptied: filling it with sample data')
                                                                 addContentAfterEmpty()


Fix xpub potential failure (shared array in Dongle's prototype)

--- app/src/dongle/dongle.coffee
+++ app/src/dongle/dongle.coffee
@@ -87,6 +87,7 @@

   constructor: (card) ->
     super
+    @_xpubs = _.clone(@_xpubs)
     @id = card.deviceId
     @deviceId = card.deviceId
     @productId = card.productId


Mention .atom is a folder

Mention .atom is a folder

--- src/browser/main.coffee
+++ src/browser/main.coffee
@@ -113,7 +113,7 @@
   options.boolean('profile-startup').describe('profile-startup', 'Create a profile of the startup execution time.')
   options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
   options.boolean('safe').describe('safe', 'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.')
-  options.boolean('portable').describe('portable', 'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom is not already there.')
+  options.boolean('portable').describe('portable', 'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom folder is not already there.')
   options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
   options.string('timeout').describe('timeout', 'When in test mode, waits until the specified time (in minutes) and kills the process (exit code: 130).')
   options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')


Fixing typo

Fixing typo

--- source/app/organism/aside.coffee
+++ source/app/organism/aside.coffee
@@ -3,8 +3,6 @@

   @template """<aside class="active"></aside>"""

-  areas: ["header", "section"]
-
   constructor: (@attributes)->
     attributes.method = "prepend"
     super


kucalc: only use sysfs memory.stat file to get rss, cache and total memory limits

--- src/smc-project/kucalc.coffee
+++ src/smc-project/kucalc.coffee
@@ -75,46 +75,23 @@
                 cb()

 # this grabs the memory stats directly from the sysfs cgroup files
-# the usage is compensated by the cache usage in the stat file ...
+# the actual usage is the sum of the rss values plus cache, but we leave cache aside
 cgroup_memstats = (status, cb) ->
-    async.parallel({
-
-        cache : (cb) ->
-            fs.readFile '/sys/fs/cgroup/memory/memory.stat', 'utf8', (err, data) ->
-                if err
-                    cb(err, 0)
-                    return
-                for line in data.split('\n')
-                    [key, value] = line.split(' ')
-                    if key == 'cache'
-                        cb(null, parseInt(value))
-                        return
-                    cb('entry "cache" not found', 0)
-
-        limit : (cb) ->
-            fs.readFile '/sys/fs/cgroup/memory/memory.limit_in_bytes', 'utf8', (err, data) ->
-                if err
-                    cb(err, 0)
-                else
-                    value = parseInt(data.split('\n')[0])
-                    cb(null, value)
-
-        usage : (cb) ->
-            fs.readFile '/sys/fs/cgroup/memory/memory.usage_in_bytes', 'utf8', (err, data) ->
-                if err
-                    cb(err, 0)
-                else
-                    value = parseInt(data.split('\n')[0])
-                    cb(null, value)
-
-    }, (err, res) ->
+    fs.readFile '/sys/fs/cgroup/memory/memory.stat', 'utf8', (err, data) ->
         if err
             cb(err)
-        else
-            status.memory.rss += (res.usage - res.cache) / 1024
-            status.memory.limit = res.limit / 1024
-            cb()
-    )
+            return
+        stats = {}
+        for line in data.split('\n')
+            [key, value] = line.split(' ')
+            try
+                stats[key] = parseInt(value)
+
+        kib = 1024 # convert to kibibyte
+        status.memory.rss += (stats.total_rss ? 0 + stats.total_rss_huge ? 0) / kib
+        status.memory.cache = (stats.cache ? 0) / kib
+        status.memory.limit = (stats.hierarchical_memory_limit ? 0) / kib
+        cb()

 disk_usage = (path, cb) ->


db: add projects.compute_image field to specify which one to run in kucalc

--- src/smc-util/db-schema.coffee
+++ src/smc-util/db-schema.coffee
@@ -785,6 +785,9 @@
         run_quota :
             type : 'map'
             desc : 'If project is running, this is the quota that it is running with.'
+        compute_image :
+            type : 'string'
+            desc : 'Specify the name of the underlying (kucalc) compute image (default: "latest")'

     pg_indexes : [
         'last_edited',
@@ -813,6 +816,7 @@
                 last_active    : null
                 action_request : null   # last requested action -- {action:?, time:?, started:?, finished:?, err:?}
                 course         : null
+                compute_image  : 'latest'
         set :
             fields :
                 project_id     : 'project_write'
@@ -822,6 +826,7 @@
                 invite_requests: true   # project collabs can modify this (e.g., to remove from it once user added or rejected)
                 users          : (obj, db, account_id) -> db._user_set_query_project_users(obj, account_id)
                 action_request : true   # used to request that an action be performed, e.g., "save"; handled by before_change
+                compute_image  : true

             before_change : (database, old_val, new_val, account_id, cb) ->
                 database._user_set_query_project_change_before(old_val, new_val, account_id, cb)


webapp: saving indicator for stripe keys, using event.target.value instead of DOM query

--- src/smc-webapp/r_account.cjsx
+++ src/smc-webapp/r_account.cjsx
@@ -1024,7 +1024,7 @@
                                 ref      = 'input'
                                 type     = 'text'
                                 value    = {@state.token}
-                                onChange = {=>@setState(token:ReactDOM.findDOMNode(@refs.input).value)}}
+                                onChange = {(e)=>@setState(token:e.target.value)}}
                             />
                         </FormGroup>
                     </form>
@@ -1054,7 +1054,7 @@
     displayName : 'Account-StripeKeys'

     getInitialState : ->
-        state           : 'view'   # view --> edit --> save --> view
+        state           : 'view'   # view --> edit --> save --> saved
         secret_key      : ''
         publishable_key : ''
         error           : undefined
@@ -1064,25 +1064,15 @@

     save : ->
         @setState(state:'save')
-        async = require('async')
-        query1 = server_settings : { name:"stripe_secret_key", value:@state.secret_key }
-        query2 = server_settings : { name:"stripe_publishable_key", value:@state.publishable_key }
-
-        async.series([
-            (cb) =>
-                salvus_client.query
-                    query : query1
-                    cb    : cb
-            (cb) =>
-                salvus_client.query
-                    query : query2
-                    cb    : cb
-        ], (err) =>
-            if err
-                @setState(state:'edit', error:err)
-            else
-                @setState(state:'view', error:'', secret_key:'', publishable_key:'')
-        )
+        f = (name, cb) =>
+        query = (server_settings : {name:"stripe_#{name}_key", value:@state["#{name}_key"]} for name in ['secret', 'publishable'])
+        salvus_client.query
+            query : query
+            cb    : (err) =>
+                if err
+                    @setState(state:'edit', error:err)
+                else
+                    @setState(state:'saved', error:'', secret_key:'', publishable_key:'')

     cancel : ->
         @setState(state:'view', error:'', secret_key:'', publishable_key:'')
@@ -1095,21 +1085,24 @@

     render_main :->
         switch @state.state
-            when 'view'
-                <Button bsStyle='warning' onClick={@edit}>Change stripe keys...</Button>
+            when 'view', 'saved'
+

+                    {"stripe keys saved!" if @state.state == 'saved'}
+                    <Button bsStyle='warning' onClick={@edit}>Change stripe keys...</Button>
+

             when 'save'

Saving stripe keys...

             when 'edit'
                 <Well>
                     <LabeledRow label='Secret key'>
                         <FormGroup>
-                            <FormControl type='text' value={@state.secret_key}
+                            <FormControl ref='input_secret_key' type='text' value={@state.secret_key}
                                 onChange={(e)=>@setState(secret_key:e.target.value)} />
                         </FormGroup>
                     </LabeledRow>
                     <LabeledRow label='Publishable key'>
                         <FormGroup>
-                            <FormControl type='text' value={@state.publishable_key}
+                            <FormControl ref='input_publishable_key' type='text' value={@state.publishable_key}
                                 onChange={(e)=>@setState(publishable_key:e.target.value)} />
                         </FormGroup>
                     </LabeledRow>


fix: strange behavior when latest version is not found

--- src/checkVersion.coffee
+++ src/checkVersion.coffee
@@ -21,7 +21,9 @@
                 dep.newVer = ver
                 strategy.version dep
             else
+                dep.newVer = dep.installedVer
                 dep.needUpdate = false
+            dep
     .then (deps) ->
         cache.record()
         deps


update imports

update imports

--- src/client/index.coffee
+++ src/client/index.coffee
@@ -1,10 +1,11 @@
 { json, log, p, pjson } = require 'lightsaber'
 graphviz = require 'nodesphere-graphviz'
+SpiralLayout = require 'nodesphere-graphviz/layout/spiral'
+

 jsonDataUri = 'https://rawgit.com/mbostock/4062045/raw/9653f99dbf6050b0f28ceafbba659ac5e1e66fbd/miserables.json'
-world = new graphviz.World
+world = new graphviz.core.World
 world.render
-  source: new graphviz.JsonAdaptor
+  source: new graphviz.adaptor.Json
   sourceUri: jsonDataUri
-  layout: new graphviz.SpiralLayout
-
+  layout: new graphviz.layout.Spiral


Update 'outerPages' so that features/integrations pages don't redirect to themselves

--- js/libs/github.coffee
+++ js/libs/github.coffee
@@ -1,5 +1,5 @@
 checkOuterPages = (url) =>
-  outerPages = ["docs", "about", "privacy", "pricing"]
+  outerPages = ["docs", "about", "privacy", "pricing", "integrations", "features"]
   for page in outerPages
     if (url.match "^/#{page}.*")
       return "/"


added "simplify" boolean to geo map

added "simplify" boolean to geo map

--- src/viz/methods/coords.coffee
+++ src/viz/methods/coords.coffee
@@ -20,6 +20,9 @@
                "conicEquidistant", "equirectangular", "gnomonic", "mercator",
                "orthographic", "stereographic", "transverseMercator", Function]
     value:    "mercator"
+  simplify:
+    accepted: [Boolean]
+    value:    true
   solo:      filter false
   threshold:
     accepted: [Number]


fix revert conflicts on oab embed

fix revert conflicts on oab embed

--- static/embed/oab_embed.coffee
+++ static/embed/oab_embed.coffee
@@ -608,11 +608,11 @@
           _L.set '#_oab_email', 'placeholder', ph
           _L.html '._oab_terms', tcs
         refs = ''
-        for p of this.f?.permissions?.permissions?.policy_full_text ? []
-          refs += ' [' + (parseInt(p)+1) + ']'
+        for p of this.f?.permissions?.best_permission?.provenance?.archiving_policy ? []
+          refs += ' [' + (parseInt(p)+1) + ']'
         _L.html '._oab_refs', refs
         paper = if this.f?.metadata?.doi then 'your paper' else 'your paper'
-        _L.html '._oab_your_paper', (if this.f?.permissions?.permissions?.version_allowed is 'publisher pdf' then 'the publisher pdf of ' else '') + paper
+        _L.html '._oab_your_paper', (if this.f?.permissions?.best_permission?.version is 'publishedVersion' then 'the publisher pdf of ' else '') + paper
         _L.html '._oab_journal', this.f?.metadata?.journal_short ? 'the journal'
         # set config by this.config.repo_name put name in ._oab_repo

@@ -625,18 +625,18 @@
           else
             this.file = true # no file required for oa deposit...
             _L.show '._oab_oa_deposit'
-        else if this.f?.permissions?.permissions?.archiving_allowed
+        else if this.f?.permissions?.best_permission?.can_archive
           # can be shared, depending on permissions info
-          _L.hide('#_oab_not_pdf') if this.f?.permissions?.permissions?.version_allowed is 'publisher pdf'
-          if typeof this.f?.permissions?.permissions?.licence_required is 'string' and this.f.permissions.permissions.licence_required.indexOf('other-') is 0
+          _L.hide('#_oab_not_pdf') if this.f?.permissions?.best_permission?.version is 'publishedVersion'
+          if typeof this.f?.permissions?.best_permission?.licence is 'string' and this.f.permissions.best_permission.licence.indexOf('other-') is 0
             _L.html '._oab_licence', 'under the publisher terms' + refs
           else
-            _L.html '._oab_licence', this.f?.permissions?.permissions?.licence_required ? 'CC-BY'
+            _L.html '._oab_licence', this.f?.permissions?.best_permission?.licence ? 'CC-BY'
           _L.show '._oab_archivable'
         else if this.config.dark_deposit_off
           # permission must be requested first
-          rm = 'mailto:' + (this.f.permissions?.ricks?.application?.can_archive_conditions?.permission_required_contact ? this.config.deposit_help ? this.cml()) + '?'
-          rm += 'cc=' + (this.config.deposit_help ? this.cml()) + '&' if this.f.permissions?.ricks?.application?.can_archive_conditions?.permission_required_contact
+          rm = 'mailto:' + (this.f.permissions?.best_permission?.permissions_contact ? this.config.deposit_help ? this.cml()) + '?'
+          rm += 'cc=' + (this.config.deposit_help ? this.cml()) + '&' if this.f.permissions?.best_permission?.permissions_contact
           rm += 'subject=Request%20to%20self%20archive%20' + (this.f.metadata?.doi ? '') + '&body=';
           rm += encodeURIComponent 'To whom it may concern,\n\n'
           rm += encodeURIComponent 'I am writing to request permission to deposit the full text of my paper "' + (this.f.metadata?.title ? this.f.metadata?.doi ? 'Untitled paper') + '" '
@@ -702,7 +702,7 @@
       _L.show '#_oab_findings'
       if this.f.ill?.error
         _L.show '#_oab_error', '
Please note, we encountered errors querying the following subscription services: ' + this.f.ill.error.join(', ') + '
'
-      if this.f.metadata?.title?
+      if this.f.metadata?.title? and (this.f.metadata.journal? or this.data.usermetadata)
         citation = '
' + this.f.metadata.title + '
'
         if this.f.metadata.year or this.f.metadata.journal or this.f.metadata.volume or this.f.metadata.issue
           citation += '
'
@@ -823,9 +823,9 @@
         data.metadata.journal = 'Proceedings of the 16th IFLA ILDS conference: Beyond the paywall - Resource sharing in a disruptive ecosystem'
         data.metadata.author = [{given: 'Mike', family: 'Paxton'}, {given: 'Gary', family: 'Maixner III'}, {given: 'Joseph', family: 'McArthur'}, {given: 'Tina', family: 'Baich'}]
         data.ill = {subscription: {findings:{}, uid: this.uid, lookups:[], error:[], url: 'https://scholarworks.iupui.edu/bitstream/handle/1805/20422/07-PAXTON.pdf?sequence=1&isAllowed=y'}}
-        data.permissions = { permissions: {
-          archiving_allowed: if this.data.doi is '10.1234/oab-syp-aam' then true else false,
-          version_allowed: if this.data.doi is '10.1234/oab-syp-aam' then "postprint" else undefined
+        data.permissions = { best_permission: {
+          can_archive: if this.data.doi is '10.1234/oab-syp-aam' then true else false,
+          version: if this.data.doi is '10.1234/oab-syp-aam' then "postprint" else undefined
         }, file: {archivable: true, archivable_reason: "Demo acceptance", version: "postprint", licence: "cc-by", same_paper: true, name: "example.pdf", format: "pdf", checksum: "example-checksum"}}
         if this.plugin is 'instantill' then this.findings(data) else this.permissions(data)
       else


fix current instruction indicator

fix current instruction indicator

--- graphics.coffee
+++ graphics.coffee
@@ -277,10 +277,11 @@
     temp_sym = mode.symbols
     current_symbol = null
     if mode == @game_state.current_mapping and
-       @game_state.current_program.length > 0 and
-       not (@game_state.current_program[0] in mode.symbols)
+       @game_state.current_program.length > 0
+
       current_symbol = @game_state.current_program[0]
-      temp_sym = mode.symbols.concat([current_symbol])
+      if not (@game_state.current_program[0] in mode.symbols)
+        temp_sym = mode.symbols.concat([current_symbol])

     len = temp_sym.length


Fix gulp typescript-compile path

Fix gulp typescript-compile path

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -13,7 +13,7 @@
 		.pipe gulp.dest './app/lib/web/views/'

 gulp.task 'typescript-compile', ->
-	gulp.src './src/lib/**.ts'
+	gulp.src './src/lib/**/*.ts'
 		.pipe ts
 			target: 'ES5'
 			removeComments: true


move to package.json

move to package.json

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -1,10 +0,0 @@
-gulp   = require 'gulp'
-coffee = require 'gulp-coffee'
-
-gulp.task 'compile', ->
-	gulp.src 'src/index.coffee'
-		.pipe coffee(bare: true)
-		.pipe gulp.dest('')
-
-gulp.task 'default', ['compile'], ->
-	gulp.watch 'src/index.coffee', ['compile']


remove dead code

remove dead code

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -161,7 +161,6 @@
 	description : 'Open app from browser-sync'
 	type        : 'boolean'

-appUrl         = "http://localhost:#{PORT}"
 env            = plugins.util.env
 firstRun       = true
 getBower       = getSwitchOption 'bower'


let gulp complies main js file

let gulp complies main js file

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -40,7 +40,7 @@
         .pipe coffee()
         .pipe gulp.dest "js/"

-gulp.task 'default', ['html', 'static', 'js', 'css', 'index-js'], ->
+gulp.task 'default', ['html', 'static', 'js', 'css', 'main-js'], ->
     # default task

 gulp.task 'watch', ['default'], ->


refactor

refactor

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -19,6 +19,14 @@
 sourcemaps = require 'gulp-sourcemaps'
 uglify = require 'gulp-uglify'
 watch = require 'gulp-watch'
+
+buildTitle = (entry) ->
+  titlePrefix = if entry?
+    date = moment(entry.pubdate).format 'YYYY-MM-DD'
+    date + ' ' + entry.title + ' - '
+  else
+    ''
+  titlePrefix + 'blog.bouzuya.net'

 loadEntries = (src) ->
   myjekyll = require 'myjekyll'
@@ -62,12 +70,7 @@
     hasNext: false
     searchText: null # entry?.date ? null
     searchVisible: false # entry?
-  titlePrefix = if entry?
-    date = moment(entry.pubdate).format 'YYYY-MM-DD'
-    date + ' ' + entry.title + ' - '
-  else
-    ''
-  title = titlePrefix + 'blog.bouzuya.net'
+  title = buildTitle entry
   doctype = '<!DOCTYPE html>'
   html = React.renderToStaticMarkup React.DOM.html null,
     React.DOM.head null,


Теперь тестовый вебсервер запускается сразу после сборки

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -8,7 +8,7 @@

 # основная джоба
 gulp.task 'build', (callback)->
-  sequence 'api', 'main', 'jquery', callback
+  sequence 'api', 'main', 'jquery', 'webserver', callback

 # джоба для компиляции alt_cadesplugin_api.coffee в alt_cadesplugin_api.js
 gulp.task 'api', (callback)->


project updated

project updated

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -14,7 +14,6 @@
   launchpad
   lint
   sfacg
-  sfacg-all

 ###

@@ -55,13 +54,4 @@
   m = require './source/module/sfacg.coffee'
   sf = new m()

-  yield sf.get url
-
-$$.task 'sfacg-all', co ->
-
-  m = require './source/module/sfacg.coffee'
-  sf = new m()
-
-  for i in [6752..1e4]
-
-    yield sf.get "http://book.sfacg.com/Novel/#{i}/MainIndex"+  yield sf.get url


[client][framework][utils] changed equals to semicolon

--- core/utils.coffee
+++ core/utils.coffee
@@ -707,7 +707,7 @@
     octal   = '' + @_permissionMap()[user] + @_permissionMap()[group] + @_permissionMap()[other]

   # private member for tracking z-indexes
-  zIndexContexts  = {}
+  zIndexContexts:{}

   # Get next highest Z-index
   getNextHighestZIndex:(context)->


KernelManager: Make linter happy

KernelManager: Make linter happy

--- lib/kernel-manager.coffee
+++ lib/kernel-manager.coffee
@@ -30,10 +30,9 @@

             unless kernelSpec?
                 message = "No kernel for language `#{language}` found"
-                options =
-                    detail: 'Check that the language for this file is set in Atom
-                             and that you have a Jupyter kernel installed for it.'
-                atom.notifications.addError message, options
+                detail = 'Check that the language for this file is set in Atom
+                         and that you have a Jupyter kernel installed for it.'
+                atom.notifications.addError message, detail: detail
                 return

             console.log 'startKernelFor:', language
@@ -58,7 +57,8 @@

         try
             rootDirectory = atom.project.rootDirectories[0].path
-            connectionFile = path.join rootDirectory, 'hydrogen', 'connection.json'
+            connectionFile = path.join rootDirectory, 'hydrogen',
+                'connection.json'
             data = fs.readFileSync connectionFile, 'utf8'
             config = JSON.parse data
             console.log 'KernelManager: Using connection file: ', connectionFile
@@ -119,7 +119,7 @@
         unless language?
             return null

-        @getAllKernelSpecsFor language, (kernelSpecs) ->
+        @getAllKernelSpecsFor language, (kernelSpecs) =>
             if kernelSpecs.length <= 1
                 callback kernelSpecs[0]
             else


Add staged condition to productProjections reference resolution query.

--- lib/product-import.coffee
+++ lib/product-import.coffee
@@ -77,10 +77,11 @@
       if product.masterVariant?.sku
         skus.push(product.masterVariant.sku)
       else @_summary.emptySKU++
-      for variant in product.variants
-        if variant.sku
-          skus.push(variant.sku)
-        else @_summary.emptySKU++
+      if product.variants and not _.isEmpty(product.variants)
+        for variant in product.variants
+          if variant.sku
+            skus.push(variant.sku)
+          else @_summary.emptySKU++
     return _.uniq(skus,false)

@@ -268,7 +269,10 @@
       if @_cache[refKey][ref.id]
         resolve(@_cache[refKey][ref.id])
       else
-        service.where(predicate).fetch()
+        request = service.where(predicate)
+        if refKey is 'productProjections'
+          request.staged(true)
+        request.fetch()
         .then (result) =>
           if result.body.count is 0
             reject "Didn't find any match while resolving #{refKey} (#{predicate})"


only setup "ready" teams

only setup "ready" teams

--- scripts/setup/setup-teams.coffee
+++ scripts/setup/setup-teams.coffee
@@ -28,7 +28,7 @@
 setupTeam = (next) ->
   return next() unless team
   console.log team.slug, 'setting up team...'
-  team.setup.log = ''
+  team.setup.log ?= ''

   setupData = (data) ->
     process.stdout.write data
@@ -56,10 +56,7 @@

 # atomically select a team that is not being setup
 selectTeam = (next) ->
-  query = {
-    'setup.status': null,
-    slug: { $in: ['organizers'] }
-  }
+  query = { 'setup.status': 'ready' }
   sort = []
   update = { $set: { 'setup.status': 'processing' }}
   options = {}


Strip whitespace from list of branches

Strip whitespace from list of branches

--- lib/branch-list-view.coffee
+++ lib/branch-list-view.coffee
@@ -9,10 +9,12 @@
     @parseData()

   parseData: ->
-    items = @data.split("\n ")
+    items = @data.split("\n")
     branches = []
     for item in items
-      branches.push {name: item}
+      item = item.replace(/\s/g, '')
+      unless item is ''
+        branches.push {name: item}
     @setItems branches
     atom.workspaceView.append this
     @focusFilterEditor()
@@ -22,7 +24,7 @@
   viewForItem: ({name}) ->
     current = false
     if name.startsWith "*"
-      name = name.slice(2)
+      name = name.slice(1)
       current = true
     # $$ is an alias for View.render
     $$ ->


Added : Create a new sensor entry when we receive data from an unknown sensor

--- express/routes/collector.coffee
+++ express/routes/collector.coffee
@@ -5,6 +5,22 @@
         throw new Error("Body request is not JSON.")

     jsonData = req.body
+    console.log "COunting sensor"
+    mongo.sensorCollection.count(
+        {sensor_id : jsonData.sensor_id}, (err, count) ->
+            if err
+                console.log(err)
+                res.send 500
+
+            else if  count < 1
+                console.log "Should add sensor"
+                mongo.sensorCollection.insert(
+                    {sensor_id : jsonData.sensor_id}, {w:1}, (err, collection) ->
+                        console.log "Request terminated"
+                        console.log(err)
+                )
+        )
+
     mongo.dataCollection.insert(
         jsonData, {w:1}, (err, collection) ->
             console.log "Request terminated"


Use atom.commands to find commands for assertions

--- spec/command-palette-spec.coffee
+++ spec/command-palette-spec.coffee
@@ -103,17 +103,15 @@
       atom.workspaceView.trigger 'command-palette:toggle'
       $(':focus').blur()
       atom.workspaceView.trigger 'command-palette:toggle'
+
       keyBindings = atom.keymap.findKeyBindings(atom.workspaceView.getActiveView())
-      for eventName, description of atom.workspaceView.events()
-        eventLi = palette.list.children("[data-event-name='#{eventName}']")
-        if description
-          expect(eventLi).toExist()
-          expect(eventLi.find('span')).toHaveText(description)
-          expect(eventLi.find('span').attr('title')).toBe(eventName)
-          for binding in keyBindings when binding.command is eventName
-            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()
-        else
-          expect(eventLi).not.toExist()
+      for {name, displayName} in atom.commands.findCommands(target: atom.workspaceView[0])
+        eventLi = palette.list.children("[data-event-name='#{name}']")
+        expect(eventLi).toExist()
+        expect(eventLi.find('span')).toHaveText(displayName)
+        expect(eventLi.find('span').attr('title')).toBe(name)
+        for binding in keyBindings when binding.command is eventName
+          expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()

   describe "when the body has focus", ->
     it "uses the root view as the element to display and trigger events for", ->
@@ -121,13 +119,10 @@
       $(document.body).focus()
       atom.workspaceView.trigger 'command-palette:toggle'
       keyBindings = atom.keymap.findKeyBindings(atom.workspaceView.getActiveView())
-      for eventName, description of atom.workspaceView.events()
-        eventLi = palette.list.children("[data-event-name='#{eventName}']")
-        if description
-          expect(eventLi).toExist()
-          expect(eventLi.find('span')).toHaveText(description)
-          expect(eventLi.find('span').attr('title')).toBe(eventName)
-          for binding in keyBindings when binding.command is eventName
-            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()
-        else
-          expect(eventLi).not.toExist()
+      for {name, displayName} in atom.commands.findCommands(target: atom.workspaceView[0])
+        eventLi = palette.list.children("[data-event-name='#{name}']")
+        expect(eventLi).toExist()
+        expect(eventLi.find('span')).toHaveText(displayName)
+        expect(eventLi.find('span').attr('title')).toBe(name)
+        for binding in keyBindings when binding.command is eventName
+          expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()


timer fix

timer fix

--- app/assets/javascripts/application.coffee
+++ app/assets/javascripts/application.coffee
@@ -10,8 +10,8 @@
     $input.focus()
     $saved.hide()

-    inputDelay = 2000
-    eraseDelay = 500
+    inputDelay = 3000
+    eraseDelay = 1000
     fadeOutDelay = 1000
     eraseInterval = 0
     eraseTimeout = 0


minification

minification

--- app/assets/javascripts/controllers.coffee
+++ app/assets/javascripts/controllers.coffee
@@ -1,14 +1,19 @@
 angular.module('myApp.controllers', [])

-  .controller "ModalInstanceCtrl", ($scope, $modalInstance, rumor) ->
-    console.log rumor
-    $scope.rumor = rumor
-    $scope.ok = ->
-      $modalInstance.close $scope.selected.item
+  .controller "ModalInstanceCtrl", [
+    '$scope'
+    '$modalInstance'
+    'rumor'

-    $scope.cancel = ->
-      $modalInstance.dismiss "cancel"
+    ($scope, $modalInstance, rumor) ->
+      console.log rumor
+      $scope.rumor = rumor
+      $scope.ok = ->
+        $modalInstance.close $scope.selected.item

+      $scope.cancel = ->
+        $modalInstance.dismiss "cancel"
+    ]


don't force animation existance

don't force animation existance

--- src/3d/JsonModelManager.coffee
+++ src/3d/JsonModelManager.coffee
@@ -23,9 +23,10 @@
         throw 'mesh already has animations. not overwriting default behaviour' if mesh.animations?

         mesh.animations = []
-        for anim in mesh.geometry.animations
-          animation = new THREE.Animation(mesh, anim, THREE.AnimationHandler.CATMULLROM)
-          mesh.animations.push animation
+        if mesh.geometry.animations?
+          for anim in mesh.geometry.animations
+            animation = new THREE.Animation(mesh, anim, THREE.AnimationHandler.CATMULLROM)
+            mesh.animations.push animation

         JsonModelManager.get().models[key] = mesh
         callback(mesh)


addes ajax for converstaion it doesnt work right now.

--- app/assets/javascripts/pms/show.js.coffee
+++ app/assets/javascripts/pms/show.js.coffee
@@ -0,0 +1,25 @@
+json_url = window.location.href.replace(/\.[^/]*$/,'')+".json"
+
+page_visited_pms = false
+starting_size_pms = 0
+update = (pms) ->
+	if !page_visited_pms
+		starting_size_pms = pms.conversation.count_messages
+		page_visited_pms = true
+
+	if pms.convesation.count_messages > starting_size_pms
+		window.location.reload true
+		return
+
+	console.log("hey we got here!")
+	console.log(starting_size_pms)
+	console.log(pms.convesation.count_messages)
+
+	setTimeout (->
+		$.ajax(url: json_url).done update
+		return
+	), 2000
+
+# Now kick off the whole process
+window.onload = ->
+	$.ajax(url: json_url).done update


Remove unnecessary

Remove unnecessary

--- app/assets/javascripts/sequence.js.coffee
+++ app/assets/javascripts/sequence.js.coffee
@@ -8,7 +8,6 @@
     localStorage.getItem('sequence')

   deleteSequenceSearchCondition = ->
-    $("input#fragment").val('')
     localStorage.removeItem('sequence')

   $(window).on "load", (e) ->


EDSC-149: Fix landing page behavior when transitioning using the enter key

--- app/assets/javascripts/util/url.js.coffee
+++ app/assets/javascripts/util/url.js.coffee
@@ -4,30 +4,35 @@
                         extend = jQuery.extend,
                         param = jQuery.param) ->

+  cleanPath = ->
+    # Remove everything up to the third slash
+    History.getState().cleanUrl.replace(/^[^\/]*\/\/[^\/]*/, '')
+
   pushPath = (path, title=document.title, data=null) ->
-    History.pushState(data, title, path + window.location.search)
+    # Replace everything before the first ?
+    path = cleanPath().replace(/^[^\?]*/, path)
+    History.pushState(data, title, path)

-  savedState = null
   savedPath = null

   saveState = (path, state, push = false) ->
     paramStr = param(state)
     paramStr = '?' + paramStr if paramStr.length > 0
+    path = path + paramStr

-    if window.location.pathname != path || window.location.search != paramStr
-      savedState = paramStr
+    if cleanPath() != path
       savedPath = path
       if push
-        History.pushState(state, document.title, path + paramStr)
+        History.pushState(state, document.title, path)
       else
-        History.replaceState(state, document.title, path + paramStr)
+        History.replaceState(state, document.title, path)
       true
     else
       false

   # Raise a new event to avoid getting a statechange event when we ourselves change the state
   $(window).on 'statechange anchorchange', ->
-    if window.location.search != savedState || window.location.pathname != savedPath
+    if cleanPath() != savedPath
       $(window).trigger('edsc.pagechange')

   exports =


Updated for recent API changes

Updated for recent API changes

--- app/assets/jax/controllers/wire.js.coffee
+++ app/assets/jax/controllers/wire.js.coffee
@@ -137,24 +137,22 @@
           @_p2verts = new Jax.Buffer GL_ARRAY_BUFFER, null, GL_STREAM_DRAW, buf2, 4
           @_p3verts = new Jax.Buffer GL_ARRAY_BUFFER, null, GL_STREAM_DRAW, buf3, 3
         mesh.data.set vars, vertices: 'position'
-        vars.set
-          WIN_SCALE: [context.canvas.width/2, context.canvas.height/2]
-          WIRE_COL: [0.7, 0.7, 0.8, 1]
-          FILL_COL: [0, 0, 0, 0]
-          MVP: context.matrix_stack.getModelViewProjectionMatrix()
-          # be sure to set these AFTER setting the mesh position above, or else
-          # the buffers below will bind new GL buffers and mess up the mesh data
-          # transfer.
-          p1_3d: @_p2verts
-          p2_3d: @_p3verts
+        vars.WIN_SCALE = [context.canvas.width/2, context.canvas.height/2]
+        vars.WIRE_COL = [0.7, 0.7, 0.8, 1]
+        vars.FILL_COL = [0, 0, 0, 0]
+        vars.MVP = context.matrix_stack.getModelViewProjectionMatrix()
+        # be sure to set these AFTER setting the mesh position above, or else
+        # the buffers below will bind new GL buffers and mess up the mesh data
+        # transfer.
+        vars.p1_3d = @_p2verts
+        vars.p2_3d = @_p3verts
     }, material
     tpmesh.material = material

-    # @world.addLight new Jax.Light.Directional
+    @world.addLight new Jax.Light.Directional direction: [-1, -1, -1]

-    @world.ambientColor = [1,1,1,1]
     @world.addObject new Jax.Framerate ema: no
     @world.addObject new Jax.Model
-      position: [0, 0, -3]
+      position: [0, 0, -5]
       mesh: tpmesh
-      update: (tc) -> @camera.rotate tc, 1, 0.75, 0.5
+      update: (tc) -> @camera.rotate tc * 0.25, 1, 0.75, 0.5


Fix linter error

Fix linter error

--- spec/package-manager-spec.coffee
+++ spec/package-manager-spec.coffee
@@ -59,12 +59,12 @@
         onWillThrowError: ->

     it "installs the latest version when a package version is not specified", ->
-      packageManager.install {name:'something'}, ->
+      packageManager.install {name: 'something'}, ->
       expect(packageManager.runCommand).toHaveBeenCalled()
       expect(runArgs).toEqual ['install', 'something']

     it "installs the package@version when a version is specified", ->
-      packageManager.install {name:'something', version: '0.2.3'}, ->
+      packageManager.install {name: 'something', version: '0.2.3'}, ->
       expect(packageManager.runCommand).toHaveBeenCalled()
       expect(runArgs).toEqual ['install', 'something@0.2.3']


Sort objects by keys

Sort objects by keys

--- lib/settings-panel.coffee
+++ lib/settings-panel.coffee
@@ -137,5 +137,5 @@
       @subview keyPath.replace(/\./g, ''), new EditorView(mini: true, attributes: {id: keyPath, type: 'array'})

 appendObject = (namespace, name, value) ->
-  for childName, childValue of value
-    appendSetting.call(this, namespace, "#{name}.#{childName}", childValue)
+  for key in _.keys(value).sort()
+    appendSetting.call(this, namespace, "#{name}.#{key}", value[key])


Add autoIndentOnPaste to scoped settings list

--- lib/settings-panel.coffee
+++ lib/settings-panel.coffee
@@ -11,6 +11,7 @@
       namespace = 'editor'
       scopedSettings = [
         'autoIndent'
+        'autoIndentOnPaste'
         'invisibles'
         'nonWordCharacters'
         'normalizeIndentOnPaste'


Confirm before song unpublish.

Confirm before song unpublish.

--- app/client/js/react/pages/editsong.coffee
+++ app/client/js/react/pages/editsong.coffee
@@ -180,21 +180,23 @@
           .then => yellowFade.on @refs['published-song-link']

       onUnpublishPointerUp: ->
+        return if !confirm EditSong.MSG_ARE_YOU_SURE_UNPUBLISH
         songsStore.unpublish song

   # PATTERN: String localization. Remember, every string has to be wrapped with
   # goog.getMsg method for later string localization.
+  @MSG_ARE_YOU_SURE_UNPUBLISH: goog.getMsg 'Are you sure you want to unpublish this song?'
   @MSG_CREATE_NEW_SONG: goog.getMsg 'Add New Song'
   @MSG_DELETE: goog.getMsg 'Delete'
   @MSG_HOW_TO_WRITE_LYRICS: goog.getMsg 'How to write lyrics'
+  @MSG_LOGIN_TO_PUBLISH: goog.getMsg 'You must be logged to publish song.'
+  @MSG_LYRICS_HISTORY: goog.getMsg 'Lyrics History'
   @MSG_LYRICS_HISTORY_P: goog.getMsg 'This is just MVP version. Formatting, cleaning, merging etc. will be implemented later. For now, you can merge with copy&paste :-P'
+  @MSG_PUBLISH: goog.getMsg 'Publish'
   @MSG_RESTORE: goog.getMsg 'Restore'
-  @MSG_LYRICS_HISTORY: goog.getMsg 'Lyrics History'
   @MSG_SONG_ARTIST: goog.getMsg 'Artist (or band)'
   @MSG_SONG_NAME: goog.getMsg 'Song name'
+  @MSG_SONG_WAS_PUBLISHED: goog.getMsg 'Song is published at'
+  @MSG_UNPUBLISH: goog.getMsg 'Unpublish'
+  @MSG_UNPUBLISH_BEFORE_DELETE: goog.getMsg 'Song is published. Unpublish it before delete.'
   @MSG_WRITE_LYRICS_HERE: goog.getMsg '[F]Michelle [Bmi7]ma belle...'
-  @MSG_PUBLISH: goog.getMsg 'Publish'
-  @MSG_UNPUBLISH: goog.getMsg 'Unpublish'
-  @MSG_LOGIN_TO_PUBLISH: goog.getMsg 'You must be logged to publish song.'
-  @MSG_SONG_WAS_PUBLISHED: goog.getMsg 'Song is published at'
-  @MSG_UNPUBLISH_BEFORE_DELETE: goog.getMsg 'Song is published. Unpublish it before delete.'


:memo: Fix documentation to match code changes

--- lib/tabs-to-spaces.coffee
+++ lib/tabs-to-spaces.coffee
@@ -10,9 +10,7 @@
   activate: ->
     atom.workspaceView.command 'tabs-to-spaces:untabify', => @untabify()

-  # Converts all leading tabs to spaces in the current editor window.
-  #
-  # Sets the cursor position to the top of the file when complete.
+  # Converts all leading tabs to spaces in the current editor.
   untabify: ->
     editor = atom.workspace.getActiveEditor()
     return unless editor?
@@ -31,10 +29,10 @@
   multiplyText: (text, count) ->
     Array(count + 1).join(text)

-  # Replaces all leading tabs with spaces in the given selection.
+  # Replaces all leading tabs with spaces in the given buffer.
   #
   # @private
-  # @param [Selection] selection Selection within which to replace tabs with spaces.
+  # @param [TextBuffer] buffer Buffer within which to replace tabs with spaces.
   replaceTabsWithSpaces: (buffer) ->
     buffer.transact =>
       buffer.scan /^\t+/g, (obj) =>


Actually create a project

Actually create a project

--- spec/CreateProject.coffee
+++ spec/CreateProject.coffee
@@ -18,7 +18,29 @@
   it 'dialog shouldn\'t be shown before a click', ->
     dialogs = doc.querySelectorAll 'noflo-new-project'
     chai.expect(dialogs.length).to.equal 0
-  it 'clicking the button should show the dialog', (done) ->
+  describe 'Opening and closing the dialog', ->
+    it 'clicking the button should show the dialog', (done) ->
+      Syn.click button
+      setTimeout ->
+        dialogs = doc.querySelectorAll 'noflo-new-project'
+        chai.expect(dialogs.length).to.equal 1
+        dialog = dialogs[0]
+        chai.expect(dialog.shadowRoot).to.be.an 'object'
+        done()
+      , 10
+    it 'initially the submit button should be disabled', ->
+      submit = dialog.shadowRoot.querySelector '.toolbar button'
+      chai.expect(submit).to.be.an 'object'
+      chai.expect(submit.classList.contains('disabled')).to.equal true
+    it 'clicking the cancel button should close the dialog', (done) ->
+      cancel = dialog.shadowRoot.querySelector '.toolbar a'
+      Syn.click cancel
+      setTimeout ->
+        dialogs = doc.querySelectorAll 'noflo-new-project'
+        chai.expect(dialogs.length).to.equal 0
+        done()
+      , 10
+  it 'clicking the button should show the dialog again', (done) ->
     Syn.click button
     setTimeout ->
       dialogs = doc.querySelectorAll 'noflo-new-project'
@@ -26,16 +48,27 @@
       dialog = dialogs[0]
       chai.expect(dialog.shadowRoot).to.be.an 'object'
       done()
-    , 10
-  it 'initially the submit button should be disabled', ->
+  it 'typing values to the required input fields should enable submission', (done) ->
+    inputs = dialog.shadowRoot.querySelectorAll 'input'
+    chai.expect(inputs.length).to.equal 2
+    Syn.click(inputs[0])
+    .type('foo')
+    Syn.click(inputs[1])
+    .type('Foo')
+    setTimeout ->
+      submit = dialog.shadowRoot.querySelector '.toolbar button'
+      chai.expect(submit.classList.contains('disabled')).to.equal false
+      done()
+    , 100
+  it 'should redirect to the project after clicking submit', (done) ->
     submit = dialog.shadowRoot.querySelector '.toolbar button'
-    chai.expect(submit).to.be.an 'object'
-    chai.expect(submit.classList.contains('disabled')).to.equal true
-  it 'clicking the cancel button should close the dialog', (done) ->
-    cancel = dialog.shadowRoot.querySelector '.toolbar a'
-    Syn.click cancel
+    Syn.click submit
     setTimeout ->
-      dialogs = doc.querySelectorAll 'noflo-new-project'
-      chai.expect(dialogs.length).to.equal 0
+      chai.expect(win.location.hash.indexOf('project/foo')).to.not.equal -1
       done()
-    , 10
+    , 1000
+  it 'should have closed the dialog', ->
+    dialogs = doc.querySelectorAll 'noflo-new-project'
+    chai.expect(dialogs.length).to.equal 0
+  it 'should have registered the project to noflo-main', ->
+    chai.expect(main.localProjects.length).to.be.above 0


domready require fix

domready require fix

--- src/extras/ender.coffee
+++ src/extras/ender.coffee
@@ -1,7 +1,9 @@
 !(($) ->
     vows = require('vows')
-    ready = require('domready').ready
+    ready = require('domready')

-    ready () -> vows.run()
+    ready () ->
+        vows.run()
+        return

 )(ender)


Update clan query selectors

Update clan query selectors

--- server/clans/clan_handler.coffee
+++ server/clans/clan_handler.coffee
@@ -102,7 +102,7 @@
       return @sendDatabaseError(res, err) if err
       return @sendNotFoundError(res) unless clan
       memberIDs = _.map clan.get('members') ? [], (memberID) -> memberID.toHexString?() or memberID
-      EarnedAchievement.find {user: {$in: memberIDs}}, (err, documents) =>
+      EarnedAchievement.find {user: {$in: memberIDs}}, 'achievementName user', (err, documents) =>
         return @sendDatabaseError(res, err) if err?
         cleandocs = (EarnedAchievementHandler.formatEntity(req, doc) for doc in documents)
         @sendSuccess(res, cleandocs)
@@ -113,7 +113,7 @@
       return @sendDatabaseError(res, err) if err
       return @sendNotFoundError(res) unless clan
       memberIDs = clan.get('members') ? []
-      User.find {_id: {$in: memberIDs}}, (err, users) =>
+      User.find {_id: {$in: memberIDs}}, 'name', (err, users) =>
         return @sendDatabaseError(res, err) if err
         cleandocs = (UserHandler.formatEntity(req, doc) for doc in users)
         @sendSuccess(res, cleandocs)
@@ -125,7 +125,7 @@
       return @sendDatabaseError(res, err) if err
       return @sendNotFoundError(res) unless clan
       memberIDs = _.map   clan.get('members') ? [], (memberID) -> memberID.toHexString?() or memberID
-      LevelSession.find {creator: {$in: memberIDs}}, 'creatorName levelName codeLanguage submittedCodeLanguage', (err, documents) =>
+      LevelSession.find {creator: {$in: memberIDs}}, 'changed codeLanguage creator creatorName levelName playtime state submittedCodeLanguage', (err, documents) =>
         return @sendDatabaseError(res, err) if err?
         cleandocs = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
         @sendSuccess(res, cleandocs)


Fix minigraph Y scale

Fix minigraph Y scale

[#115792249]

--- src/code/views/node-svg-graph-view.coffee
+++ src/code/views/node-svg-graph-view.coffee
@@ -18,8 +18,8 @@
     {x: point.x, y: @props.height - point.y}

   graphMapPoint: (point) ->
-    x = point.x * (@props.width + 1)
-    y = point.y * (@props.height + 1)
+    x = point.x * @props.width
+    y = (@props.strokeWidth-1) + point.y * (@props.height - (@props.strokeWidth+1))
     @invertPoint x:x, y:y

   pointsToPath: (points)->


resin sync/ssh: always display selection dialog, even for a single online device

Closes #373

--- lib/utils/patterns.coffee
+++ lib/utils/patterns.coffee
@@ -161,9 +161,6 @@
 		if _.isEmpty(devices)
 			throw new Error('You don\'t have any devices')

-		if devices.length is 1
-			return _.first(devices).uuid
-
 		return form.ask
 			message: 'Select a device'
 			type: 'list'


Remove unused require

Remove unused require

--- spec/snippets-spec.coffee
+++ spec/snippets-spec.coffee
@@ -1,6 +1,6 @@
 path = require 'path'

-{_, WorkspaceView} = require 'atom'
+{WorkspaceView} = require 'atom'
 fs = require 'fs-plus'
 temp = require 'temp'


Bump load timeout to 30s

Bump load timeout to 30s

These are occasionally timing out on CI so bump the time out to see
if they are legit failures or not.

--- spec/snippets-spec.coffee
+++ spec/snippets-spec.coffee
@@ -242,7 +242,7 @@
       snippets.loaded = false
       snippets.loadAll()

-      waitsFor "all snippets to load", 5000, -> snippets.loaded
+      waitsFor "all snippets to load", 30000, -> snippets.loaded

       runs ->
         expect(syntax.getProperty(['.test'], 'snippets.test')?.constructor).toBe Snippet
@@ -257,7 +257,7 @@
       snippets.loaded = false
       snippets.loadAll()

-      waitsFor "all snippets to load", 5000, -> snippets.loaded
+      waitsFor "all snippets to load", 30000, -> snippets.loaded

       runs ->
         snippet = syntax.getProperty(['.source.js'], 'snippets.fun')


use i18n to show hero name in hero-select-view

--- app/views/core/HeroSelectView.coco.coffee
+++ app/views/core/HeroSelectView.coco.coffee
@@ -28,7 +28,7 @@
     # @heroes = new ThangTypes({}, { project: ['original', 'name', 'heroClass, 'slug''] })
     # @supermodel.trackRequest @heroes.fetchHeroes()

-    api.thangTypes.getHeroes({ project: ['original', 'name', 'shortName', 'heroClass', 'slug', 'ozaria'] }).then (heroes) =>
+    api.thangTypes.getHeroes({ project: ['original', 'name', 'shortName', 'i18n', 'heroClass', 'slug', 'ozaria'] }).then (heroes) =>
       @heroes = heroes.filter((h) => !h.ozaria)
       @debouncedRender()


Disable background simulations while playing levels for now

--- app/views/play/level/PlayLevelView.coffee
+++ app/views/play/level/PlayLevelView.coffee
@@ -424,6 +424,7 @@
     @simulator.fetchAndSimulateOneGame()

   shouldSimulate: ->
+    return false  # Performance is too bad right now, gotta fix it first.
     # Crude heuristics are crude.
     defaultCores = 2
     cores = window.navigator.hardwareConcurrency or defaultCores  # Available on Chrome/Opera, soon Safari


indentation / tag fix

indentation / tag fix

--- secondary-pages/team.coffee
+++ secondary-pages/team.coffee
@@ -17,7 +17,7 @@

-
#{translate 'h1', 'team.organizations.keen.name'}

+            #{translate 'h1', 'team.organizations.keen.name'}

             #{translate 'p', 'team.organizations.keen.description'}


Fix dashboard

Fix dashboard

--- server/api/dashboard.coffee
+++ server/api/dashboard.coffee
@@ -22,7 +22,7 @@
         delete res.fullSubmit.sourceRaw
         delete res.fullSubmit.results
     tableNamePromises = []
-    if res.fullTable
+    if res.fullTable?.tables?
         for table in res.fullTable.tables
             tableNamePromises.push(Table.findById(table))
         tableNames = (await awaitAll(tableNamePromises)).map((table) -> table.name)


updated docs

updated docs

--- assets/js/directive/stub-directive.coffee
+++ assets/js/directive/stub-directive.coffee
@@ -1,6 +1,7 @@
 # This is a stub directive. It does nothing.
 define [
   'config'
+  # Load up the base directive, all controllers inherit from it. All hail the base directive. Such meta.
   # Jump to [`directive/radian-directive.coffee`](radian-directive.html) ☛
   'directive/radian-directive'
 ], (cfg, RD) ->


revert added lines now registers one action for editor undo

--- lib/line-diff-worker.coffee
+++ lib/line-diff-worker.coffee
@@ -46,13 +46,12 @@
         messageBubble = null
         marker = @editor.markBufferRange([startPoint, startPoint], {name: "line-diff"})
         if details.isRemoving
-            messageBubble = new MessageBubble(details.originalContent, ->
+            messageBubble = new MessageBubble(details.originalContent, =>
                 buffer.insert([details.newStart, 0], details.originalContent)
             )
         else if details.isAdding
-            messageBubble = new MessageBubble(details.originalContent, ->
-                for i in [0...details.newLines]
-                    buffer.deleteRow(details.newStart - 1)
+            messageBubble = new MessageBubble(details.originalContent, =>
+                buffer.deleteRows(details.newStart - 1, newEndBufferRow)
             )
         else
             messageBubble = new MessageBubble(details.originalContent, =>


restore markdownConvert function

restore markdownConvert function

--- lib/markdown-convert.coffee
+++ lib/markdown-convert.coffee
@@ -66,15 +66,12 @@

   text

-# callback(error, markdown)
-markdownConvert = (text, {projectDirectoryPath, fileDirectoryPath}, config={}, callback)->
+markdownConvert = (text, {projectDirectoryPath, fileDirectoryPath}, config={})->
   if !config.path
-    atom.notifications.addError('{path} has to be specified')
-    return callback(true)
+    return atom.notifications.addError('{path} has to be specified')

   if !config.image_dir
-    atom.notifications.addError('{image_dir} has to be specified')
-    return callback(true)
+    return atom.notifications.addError('{image_dir} has to be specified')

   # dest
   if config.path[0] == '/'
@@ -109,12 +106,8 @@
     # mermaid / viz / wavedrom graph
     processGraphs text, {fileDirectoryPath, projectDirectoryPath, imageDirectoryPath, imageFilePrefix: encrypt(outputFilePath), useAbsoluteImagePath}, (text, imagePaths=[])->
       fs.writeFile outputFilePath, text, (err)->
-        if error
-          atom.notifications.addError('failed to generate markdown')
-          return callback(true)
-
+        return atom.notifications.addError('failed to generate markdown') if err
         atom.notifications.addInfo("File #{path.basename(outputFilePath)} was created", detail: "path: #{outputFilePath}")
-        return callback(false)

 module.exports = markdownConvert


Fix debug output

Fix debug output

--- server/models/submit.coffee
+++ server/models/submit.coffee
@@ -56,7 +56,7 @@

 submitsSchema.methods.equivalent = (other) ->
     if @user == "394891"
-        logger.log "Compare submits ", @this, other, Math.abs(@time - other.time)
+        logger.log "Compare submits ", @_id, other._id, @comments.length > 0, @outcome == "AC" or @outcome == "IG" or @outcome == "DQ", @force, @user == other.user, @problem == other.problem, outcomeType(@outcome) == outcomeType(other.outcome), @source == other.source, Math.abs(@time - other.time)
     if @comments.length > 0
         return false
     if @outcome == "AC" or @outcome == "IG" or @outcome == "DQ"


HUB-41 : update hRelevantMessages

HUB-41 : update hRelevantMessages

--- test/hRelevantMessages.coffee
+++ test/hRelevantMessages.coffee
@@ -106,13 +106,12 @@
         done()

-    it "should return hResult error INVALID_ATTR with actor not a channel", (done) ->
+    it "should return hResult error NOT_AVAILABLE with actor not a channel", (done) ->
       hActor.createChild "hactor", "inproc", {actor: config.logins[0].urn}, (child) =>
         cmd.actor = child.actor
         child.h_onMessageInternal cmd, (hMessage) ->
           hMessage.should.have.property "ref", cmd.msgid
           hMessage.payload.should.have.property "status", status.NOT_AVAILABLE
-          hMessage.payload.should.have.property('result').and.match(/Command/)
           done()


Better sensible defaults for the data path

--- bin/recipes/config.workshop.template.cson
+++ bin/recipes/config.workshop.template.cson
@@ -15,24 +15,13 @@
   asana:
     key: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/asana"
     output_formats: ["csv","xlsx"]
   basecamp:
     email: ""
     password: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
-    output_formats: ["csv","xlsx"]
-  open_exchange_rates:
-    app_id: '='
-    currencies: []
-    datafile_pattern: ""
-    data_path: "_workshop/data"
-    output_formats: ["csv","xlsx"]
-  mailchimp:
-    token: ""
-    datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/basecamp"
     output_formats: ["csv","xlsx"]
   fogbugz:
     host: "{{subdomain}}.fogbugz.com"
@@ -40,44 +29,55 @@
     password: ""
     filter: "etl"
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/fogbugz"
     output_formats: ["csv","xlsx"]
   freshbooks:
     api_url: "https://{{subdomain}}.freshbooks.com/api/2.1/xml-in"
     api_token: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/freshbooks"
     output_formats: ["csv","xlsx"]
   github:
     token: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/github"
     output_formats: ["csv","xlsx"]
   google_analytics:
     user: ""
     password: ''
     profile: ''
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/google_analytics"
     output_formats: ["csv","xlsx"]
   harvest:
     subdomain: ""
     email: ""
     password: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/harvest"
     output_formats: ["csv","xlsx"]
   highrise:
     username: ''
     token: ''
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/highrise"
     output_formats: ["csv","xlsx"]
+  mailchimp:
+    token: ""
+    datafile_pattern: ""
+    data_path: "_data/mailchimp"
+    output_formats: ["csv","xlsx"]
+  open_exchange_rates:
+    app_id: '='
+    currencies: []
+    datafile_pattern: ""
+    data_path: "_data/open-exchange-rates"
+    output_formats: ["csv","xlsx"]
   trello:
     key: ""
     token: ""
     datafile_pattern: ""
-    data_path: "_workshop/data"
+    data_path: "_data/trello"
     output_formats: ["csv","xlsx"]
 databases:
   drivers:


Fix typos

Fix typos

--- app/facebook.coffee
+++ app/facebook.coffee
@@ -34,7 +34,7 @@
 	throw new Error('facebook module config missing')

 fb = require 'fb'
-db = require 'db'
+db = require './db'

 fb.options
 	appId: config.appId
@@ -63,7 +63,7 @@
 # @param [string] url
 # @return [string] id modulename-type-id
 # @private
-_createId: (url) ->
+_createId = (url) ->
 	# The Facebook module only handles event ids anyway
 	return "facebook-event-#{_getEventId(url)}"

@@ -87,7 +87,7 @@
 			else
 				db.set
 					events: [
-						id: @_createId(query.url)
+						id: _createId(query.url)
 						title: res.name
 						raw: res
 						source: query.url


fix(reply-area): Remove animated height from message list reply-area - looks strange since the removal of a draft is not otherwise animated

--- internal_packages/message-list/lib/message-list.cjsx
+++ internal_packages/message-list/lib/message-list.cjsx
@@ -256,27 +256,13 @@
     labels.map (label) =>
       <MailLabel label={label} key={label.id} onRemove={ => @_onRemoveLabel(label) }/>

-  _renderReplyArea: ({noTransition}={}) =>
-    if @_hasReplyArea()
-      styles =
-        "height": 63
-        "borderTop": "1px dashed #ddd"
-    else
-      styles =
-        "height": 0
-        "border": 0
-    unless noTransition
-      styles["transition"] = "height 150ms"
-
-

+  _renderReplyArea: =>
+

         <RetinaImg name="#{@_replyType()}-footer.png" mode={RetinaImg.Mode.ContentIsMask}/>
         Write a reply…

-
-  _hasReplyArea: =>
-    not _.last(@state.messages)?.draft

   # Either returns "reply" or "reply-all"
   _replyType: =>
@@ -297,6 +283,7 @@
   _messageElements: =>
     elements = []

+    hasReplyArea = not _.last(@state.messages)?.draft
     messages = @_messagesWithMinification(@state.messages)
     messages.forEach (message, idx) =>

@@ -306,7 +293,7 @@

       collapsed = !@state.messagesExpandedState[message.id]
       isLastMsg = (messages.length - 1 is idx)
-      isBeforeReplyArea = isLastMsg and @_hasReplyArea()
+      isBeforeReplyArea = isLastMsg and hasReplyArea

       localId = @state.messageLocalIds[message.id]

@@ -322,7 +309,8 @@
                               onRequestScrollTo={@_onChildScrollRequest} />
       )

-    elements.push @_renderReplyArea(noTransition: _.last(messages)?.draft)
+    if hasReplyArea
+      elements.push(@_renderReplyArea())

     return elements


better test for unknown columns

better test for unknown columns

--- bokehjs/src/coffee/tool/hover_tool.coffee
+++ bokehjs/src/coffee/tool/hover_tool.coffee
@@ -147,8 +147,8 @@
               value = value.replace("$sy", "#{ e.bokehY }")
               while value.indexOf("@") >= 0
                 [match, unused, column_name] = value.match(/(@)(\w*)/)
-                columns = ds.columns()
-                if column not in columns
+                column = ds.getcolumn(column_name)
+                if not column?
                   value = value.replace(column_name, "#{ column_name } unknown")
                   break
                 column = ds.getcolumn(column_name)


Blender Internal: Correctly read uniforms from buggy Blender versions (2.77)

--- engine/loader.coffee
+++ engine/loader.coffee
@@ -122,7 +122,9 @@
             input_names = ['', 'diffuse_color', 'diffuse_intensity', 'specular_color', 'specular_intensity', 'specular_hardness', 'emit', 'ambient', 'alpha', 'mir']
             input_types = [1, 3, 1, 3, 1, 1, 1, 1, 1, 3]
             for u in data.uniforms
-                if u.material
+                # We don't check "u.material" so buggy versions of blender with
+                # undefined material are interpreted as having the material named "undefined"
+                if (u.type>>16) == 7 # GPU_DYNAMIC_GROUP_MAT
                     is_blender278 = true
                     prefix = ''
                     if u.material != data.name


Send outputFile to done() in os.download

--- lib/actions/os.coffee
+++ lib/actions/os.coffee
@@ -91,7 +91,7 @@
 		], (error) ->
 			return done(error) if error?
 			console.info("\nFinished downloading #{outputFile}")
-			return done()
+			return done(null, outputFile)

 exports.install =
 	signature: 'os install <image> [device]'


Moved dom_events as they are not used in CreateButton

--- js-library/app/js/jail_iframe/classes/buttons.coffee
+++ js-library/app/js/jail_iframe/classes/buttons.coffee
@@ -1,12 +1,9 @@
 class Button
-  constructor: (dom_events={}) ->
+  constructor: ->
     @frame = new FactlinkJailRoot.ControlIframe()
     @frame.setContent($.parseHTML(@content.trim())[0])
     @$el = $(@frame.frameBody.firstChild)
     @$el.on 'mouseenter', => @_addClass 'fl-button-state-hovered'
-
-    for event, callback of dom_events
-      @$el.on event, callback

   startLoading: => @_addClass 'fl-button-state-loading'
   stopLoading: => @_removeClass 'fl-button-state-loading fl-button-state-hovered'
@@ -54,10 +51,13 @@
     </div>
   """

-  constructor: ->
+  constructor: (dom_events={}) ->
     super
     @$el.on 'mouseleave', => @_removeClass 'fl-button-state-hovered'
     $(document).on 'mousemove', => @_removeClass 'fl-button-state-hovered'
+
+    for event, callback of dom_events
+      @$el.on event, callback

   _textContainer: ($el) ->
     for el in $el.parents()


Config change

Config change

--- etc/atom/config.cson
+++ etc/atom/config.cson
@@ -11,6 +11,7 @@
   'showIndentGuide': true
   'softWrapAtPreferredLineLength': true
   'fontSize': 14
+  'invisibles': {}
 'core':
   'themes': [
     'atom-dark-ui'


Add `ruby` as a known matrix key

Add `ruby` as a known matrix key

--- assets/scripts/travis.coffee
+++ assets/scripts/travis.coffee
@@ -99,6 +99,7 @@
     compiler:    'Compiler'
     ghc:         'GHC'
     os:          'OS'
+    ruby:        'Ruby'
   }

   QUEUES: [


gulpfile: remove errant lines

gulpfile: remove errant lines

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -64,7 +64,6 @@
 gulp.task 'browserify kite', ->
   browserify
     entries     : ['./src/kite/kite.coffee']
-    extensions  : ['./coffee']
     debug       : no
   .require 'events'
   .require './src/kite/kite.coffee', expose: 'kite'
@@ -77,7 +76,6 @@
 gulp.task 'browserify kite as promised', ->
   browserify
     entries     : ['./src/kite-as-promised/kite.coffee']
-    extensions  : ['./coffee']
     debug       : no
   .require 'events'
   .require './src/kite/kite.coffee'


updated

updated

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -19,7 +19,7 @@

 module =
   filename : "#{pkg.name}.js"
-  shorcut  : "#{pkg.name}"
+  shortcut  : "#{pkg.name}"
   dist     : 'dist'

 banner = [
@@ -36,7 +36,7 @@
   browserify
       extensions: ['.coffee', '.js']
     .transform coffeeify
-    .require(src.main, { expose: module.shorcut})
+    .require(src.main, { expose: module.shortcut})
     .ignore('coffee-script')
     .bundle()
   .pipe source module.filename


Do not use full paths in js bundle ¬_¬U

Do not use full paths in js bundle ¬_¬U

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -51,7 +51,7 @@
 bundleIt = (watch = false) ->
   bundler = browserify
       # Required watchify args
-      cache: {}, packageCache: {}, fullPaths: true,
+      cache: {}, packageCache: {}, fullPaths: false,
       entries: ['./src/index.coffee'],
       extensions: ['.coffee'],
       debug: true,


static fix

static fix

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -117,12 +117,13 @@
 compileTemplates = (src, options)->
   startTime = Date.now()
   env = {}
+  getAsset = helpers.noop

   gulp.src(src)
     .pipe(jade(
       pretty: true
       compileDebug: false
-      locals: { config, env, _, helpers }
+      locals: { config, env, _, helpers, getAsset }
     ))
     .pipe(gulp.dest(options.dest))
     .on('end', -> benchmarkReporter("Jadeified #{src}", startTime))


Make Firefox run on Windows

Make Firefox run on Windows

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -228,19 +228,38 @@
     .pipe shell '../node_modules/jpm/bin/jpm xpi',
       cwd: './firefox'

-gulp.task 'ff-run', ['firefox'], () ->
+dosify = (path) ->
+  if process.platform == 'win32'
+    path.replace /\//g, '\\'
+  else
+    path
+
+gulp.task 'ff-run', ['firefox'], (callback) ->
+  # If the directory already exists, that's OK
+  try
+    fs.mkdirSync './firefox/.profile'
+
   binaryPath = '/Applications/Internet/Firefox.app'
   binaryFlag =
     if fs.existsSync(binaryPath) then "--binary #{binaryPath}" else  ""

-  command = """
-    ../node_modules/jpm/bin/jpm run
-    #{binaryFlag}
-    --profile ./.profile
-  """.replace(/[\r\n]/g, " ")
-
-  gulp.src ''
-    .pipe shell command,
-      cwd: './firefox'
-
-
+  #command = dosify "node ../node_modules/jpm/bin/jpm"
+  command = 'node'
+
+  args = []
+  args.push dosify '../node_modules/jpm/bin/jpm'
+  args.push 'run'
+  if fs.existsSync(binaryPath)
+    args.push '--binary'
+    args.push binaryPath
+  args.push '--profile'
+  args.push dosify './.profile'
+  args.push '--no-copy'
+
+  ps = child_process.spawn command, args,
+    cwd: './firefox'
+    stdio: 'inherit'
+
+  ps.on 'close', (exitCode) -> callback()
+  #callback()
+


added mustache example

added mustache example

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -118,7 +118,18 @@
     .pipe gulp.dest('example/dest/resolve-reference')

 #
+# Demonstrates mustache renderEngine
+#
+gulp.task 'mustache', ->
+  gulp.src('example/src/mustache.src.html')
+    .pipe i18n
+      langDir: 'example/src/mustache'
+      renderEngine: 'mustache'
+      trace: true
+    .pipe gulp.dest('example/dest')
+
+#
 # Calling `gulp` will compile
 #
 gulp.task 'default', ['compile']
-gulp.task 'example', ['normal', 'inline', 'dirs', 'failure', 'fallback', 'escape', 'commonjs', 'filename-i18n', 'jsfile']
+gulp.task 'example', ['normal', 'inline', 'dirs', 'failure', 'fallback', 'escape', 'commonjs', 'filename-i18n', 'jsfile', 'mustache']


compile spec helpers too

compile spec helpers too

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -19,7 +19,7 @@

 gulp.task 'coffee:spec', ->
   gulp
-    .src("#{SPEC}/**/*.spec.coffee")
+    .src("#{SPEC}/**/*.coffee")
     .pipe(coffee(bare: true))
     .pipe(gulp.dest(SPEC))


.sassと.scssの両方を監視するようにした

.sassと.scssの両方を監視するようにした

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -19,7 +19,7 @@
 # Sass
 gulp.task 'sass', ->
   gulp
-    .src 'css/*.sass'
+    .src 'css/*.{sass,scss}'
     .pipe $.plumber()
     .pipe $.rubySass
       style: 'expanded'
@@ -52,6 +52,6 @@
 # Watch
 gulp.task 'default', ['browserSync', 'sass', 'coffee', 'imagemin'], ->
   gulp.watch './**/*.html', ['browserSync-Reload']
-  gulp.watch 'css/**/*.sass', ['sass']
+  gulp.watch 'css/**/*.{sass,scss}', ['sass']
   gulp.watch 'js/**/*.coffee', ['coffee']
   gulp.watch 'img/**/*.{png,jpg,gif}', ['imagemin']


Adding string_var and ar_construct type constants

--- grammars/geck.cson
+++ grammars/geck.cson
@@ -18,7 +18,8 @@
       End|\
       Reference|\
       Ref|\
-      ScriptName|Scn\
+      ScriptName|Scn|\
+      String_Var\
     )\\b'
     'name': 'keyword'
   }
@@ -67,7 +68,11 @@
     'name': 'constant.numeric'
   }
   {
-    'match': '(?i)\\b(\
+    'match': '(?i)"(array|map|stringmap)"'
+    'name': 'constant.string'
+  }
+  {
+    'match': '(?i)[_]?\\b(\
       GameMode|\
       MenuMode|\
       OnActivate|\


__END__ should be handled same as __DATA__

--- grammars/perl.cson
+++ grammars/perl.cson
@@ -721,11 +721,11 @@
     'name': 'string.regexp.replace.perl'
   }
   {
-    'match': '\\b(__FILE__|__LINE__|__PACKAGE__|__SUB__|__END__)\\b'
+    'match': '\\b(__FILE__|__LINE__|__PACKAGE__|__SUB__)\\b'
     'name': 'constant.language.perl'
   }
   {
-    'begin': '\\b(__DATA__)\\n?'
+    'begin': '\\b(__DATA__|__END__)\\n?'
     'captures':
       '1':
         'name': 'constant.language.perl'


Revise scope-lists of macro definition requests

Using `function` as a scope-name was a bad idea; ordinary text-lines are
being hinted like keywords in some themes. Nested `.de` blocks have also
been screwing with document highlighting, especially in macro packages.

--- grammars/roff.cson
+++ grammars/roff.cson
@@ -508,7 +508,7 @@
 		patterns: [{

 			# No terminator specified
-			name: "meta.function.definition.request.$2.roff"
+			name: "meta.macro.definition.$2.roff"
 			begin: "^([.'])[ \t]*((dei?1?)|(ami?1?))\\s+(\\S+?)?\\s*(\\\\[\"#].*)?$"
 			end:   "^(?:[ \t]*\\x5C{2})?\\.[ \t]*\\."
 			beginCaptures:
@@ -524,7 +524,7 @@
 		},{

 			# Terminator included
-			name: "meta.function.definition.request.with-terminator.$2.roff"
+			name: "meta.macro.definition.with-terminator.$2.roff"
 			begin: "^([.'])[ \t]*((dei?1?)|(ami?1?))\\s+(\\S+)\\s*(\"[^\"]+\"?|\\S+?(?=\\s|\\\\[\"#]))?(.*)$"
 			end:   "^(\\.)[ \t]*((\\6)(?=$|\\s|\\\\(?:$|\")))"
 			beginCaptures:


identation problem fixed

identation problem fixed

--- mrfogg-front/app/coffee/controllers/main.coffee
+++ mrfogg-front/app/coffee/controllers/main.coffee
@@ -57,7 +57,7 @@
     if trip_unset or changed
         resource.getTrips($rootScope.userid).then (result) ->
             $scope.triplist = result
-        $scope.mytrips = _.remove($scope.triplist, (trip) ->
+            $scope.mytrips = _.remove($scope.triplist, (trip) ->
                 return trip.id == $rootScope.tripId
             )
             $rootScope.mytrip = $scope.mytrips[0]


chore(build): Fix watched files paths.

chore(build): Fix watched files paths.

--- grunt/watch.coffee
+++ grunt/watch.coffee
@@ -2,5 +2,5 @@
 # @see https://github.com/gruntjs/grunt-contrib-watch
 module.exports =
   server:
-    files: ['app/**/*.js','app/**/*.coffee']
+    files: ['src/**/*.js','src/**/*.coffee']
     tasks: ['coffeelint', 'jshint', 'mochaTest:unit']


activity: expose byParticipants endpoint to client

--- client/app/lib/socialapicontroller.coffee
+++ client/app/lib/socialapicontroller.coffee
@@ -825,6 +825,20 @@

     revive               : mapChannel

+    byParticipants: (options, callback) ->
+
+      serialized = options.participants
+        .map (id) -> "participants=#{id}"
+        .join "&"
+
+      doXhrRequest
+        endPoint: "/api/social/channel/by/participants?#{serialized}"
+        type: 'GET'
+      , (err, result) ->
+        return callback err  if err
+        return callback null, mapChannels result
+
+
   moderation:
     link     : (options, callback) ->
       doXhrRequest


Do not clear incident report form

Do not clear incident report form

--- client/controllers/incidentReports.coffee
+++ client/controllers/incidentReports.coffee
@@ -70,11 +70,11 @@
     Meteor.call("addIncidentReport", templateInstance.data.userEvent._id, article, allLocations, e.target.incidentType.value, incidentCount, e.target.date.value, (error, result) ->
       if not error
         countId = result
-        $articleSelect.select2('val', '')
-        e.target.date.value = ""
-        e.target.incidentType.value = ""
-        templateInstance.incidentType.set("")
-        templateInstance.$("#count-location-select2").select2('val', '')
+        # $articleSelect.select2('val', '')
+        # e.target.date.value = ""
+        # e.target.incidentType.value = ""
+        # templateInstance.incidentType.set("")
+        # templateInstance.$("#count-location-select2").select2('val', '')
         toastr.success("Incident report added to event.")
       else
         toastr.error(error.reason)


removed weboscket connection mesage

removed weboscket connection mesage

--- src/main/app/index/FSAppController.coffee
+++ src/main/app/index/FSAppController.coffee
@@ -38,8 +38,8 @@
       _settings.resolution *=-1
       angular.copy(_settings, $scope.settings)
       FSScanService.setScannerState(data['state'])
-      $log.debug("Show Server connection message")
-      toastr.info(FSi18nService.translateKey('main','CONNECTED_TO_SERVER'))
+      $log.debug("WebSocket connection ready...")
+      #toastr.info(FSi18nService.translateKey('main','CONNECTED_TO_SERVER'))
       $scope.$apply()
     )


invitations: remove escaping regexp, other minor bug fix

--- client/landing/Login/AppController.coffee
+++ client/landing/Login/AppController.coffee
@@ -18,15 +18,15 @@
     KD.utils.defer -> new KDNotificationView title: "Login restricted"

   handleRestriction = (handler) ->
-    ({params: {token : token }})->
-      for url in ['localhost', 'https:\/\/koding.com'] when (new RegExp url).test window.location
+    ({params: {token : token}})->
+      for url in ['localhost', 'https://koding.com'] when (new RegExp url).test window.location
         return do handler()

       return handleFailureOfRestriction()  unless token

       KD.remote.api.JInvitation.byCodeForBeta token, (err, invite)->
         if err or !invite?
-          return handleFailureOfRestriction()  unless token
+          return handleFailureOfRestriction()

         do handler()


statusLEDS: social worker error fix

statusLEDS: social worker error fix

--- client/landing/app/MainApp/monitor.coffee
+++ client/landing/app/MainApp/monitor.coffee
@@ -87,7 +87,7 @@
             if item.indexOf(key.replace('*','')) isnt -1
               @socialWorkers++
               socialWorker = @monitorData[item]
-          socialWorker.count = @socialWorkers
+          socialWorker?.count = @socialWorkers or 0
           return socialWorker

   getOnlineServices:->


Update navigation.cjsx

Update navigation.cjsx

Add a link to the FAQ post on Talk

--- app/navigation.cjsx
+++ app/navigation.cjsx
@@ -51,6 +51,7 @@
         {links}
         Discuss
         Blog
+        FAQ