generate: Use absolute includes in generated files

--- lib/generate.coffee
+++ lib/generate.coffee
@@ -225,7 +225,7 @@
   sourceOutput += "\n\n"
   sourceOutput += generateComponentFactory(componentLib, factoryMethodName)
   fs.writeFileSync baseDir + "/componentlib-source.hpp", sourceOutput
-  all = "\n#include \"microflo.h\"\n" + ids + ports + sourceOutput
+  all = ids + ports + sourceOutput
   fs.writeFileSync baseDir + "/componentlib.hpp", all
   fs.writeFileSync baseDir + "/componentlib-map.json", generateComponentMap componentLib

@@ -391,16 +391,15 @@
     if target == 'linux-mqtt' # FIXME: generalize, allow specifying explicitly, and have default based on target name
         includes += "#define MICROFLO_MAIN_FILE \"linux_mqtt_main.hpp\"\n"

-    includes += """
-    #define MICROFLO_EMBED_GRAPH 1
-    #include \"microflo.h\"
-    #include \"main.hpp\"
-    #include \"./componentlib.hpp\"
-
-    """
+    microfloDir = path.join __dirname, '..', 'microflo'
+
+    includes += "#define MICROFLO_EMBED_GRAPH 1" + '\n'
+    includes += include(path.join microfloDir, 'microflo.h') + '\n'
+    includes += include(path.join microfloDir, 'main.hpp') + '\n'
+    includes += include('./componentlib.hpp') + '\n'

     fs.writeFile outputFile, cmdStreamToCDefinition(data, target) + includes, (err) ->
-      throw err  if err
+      throw err if err

 module.exports =
   updateDefinitions: updateDefinitions


Make git tile support multiple git repositories

--- lib/git-view.coffee
+++ lib/git-view.coffee
@@ -1,3 +1,5 @@
+{CompositeDisposable} = require "atom"
+
 class GitView extends HTMLElement
   initialize: ->
     @classList.add('git-view')
@@ -9,8 +11,8 @@
     @activeItemSubscription = atom.workspace.onDidChangeActivePaneItem =>
       @subscribeToActiveItem()
     @projectPathSubscription = atom.project.onDidChangePaths =>
-      @subscribeToRepo()
-    @subscribeToRepo()
+      @subscribeToRepositories()
+    @subscribeToRepositories()
     @subscribeToActiveItem()

   createBranchArea: ->
@@ -56,39 +58,47 @@

     @update()

-  subscribeToRepo: ->
-    @statusChangedSubscription?.dispose()
-    @statusesChangedSubscription?.dispose()
+  subscribeToRepositories: ->
+    @repositorySubscriptions?.dispose()
+    @repositorySubscriptions = new CompositeDisposable

-    if repo = atom.project.getRepositories()[0]
-      @statusChangedSubscription = repo.onDidChangeStatus ({path, status}) =>
+    for repo in atom.project.getRepositories() when repo?
+      @repositorySubscriptions.add repo.onDidChangeStatus ({path, status}) =>
         @update() if path is @getActiveItemPath()
-      @statusesChangedSubscription = repo.onDidChangeStatuses =>
+      @repositorySubscriptions.add repo.onDidChangeStatuses =>
         @update()

   destroy: ->
     @activeItemSubscription?.dispose()
     @projectPathSubscription?.dispose()
-
     @savedSubscription?.dispose()
-    @statusChangedSubscription?.dispose()
-    @statusesChangedSubscription?.dispose()
+    @repositorySubscriptions?.dispose()

   getActiveItemPath: ->
     @getActiveItem()?.getPath?()
+
+  getRepositoryForActiveItem: ->
+    [rootDir] = atom.project.relativizePath(@getActiveItemPath())
+    rootDirIndex = atom.project.getPaths().indexOf(rootDir)
+    if rootDirIndex >= 0
+      atom.project.getRepositories()[rootDirIndex]
+    else
+      for repo in atom.project.getRepositories() when repo
+        return repo

   getActiveItem: ->
     atom.workspace.getActivePaneItem()

   update: ->
-    @updateBranchText()
-    @updateAheadBehindCount()
-    @updateStatusText()
+    repo = @getRepositoryForActiveItem()
+    @updateBranchText(repo)
+    @updateAheadBehindCount(repo)
+    @updateStatusText(repo)

-  updateBranchText: ->
+  updateBranchText: (repo) ->
     @branchArea.style.display = 'none'
     if @showBranchInformation()
-      head = atom.project.getRepositories()[0]?.getShortHead(@getActiveItemPath()) or ''
+      head = repo?.getShortHead(@getActiveItemPath()) or ''
       @branchLabel.textContent = head
       @branchArea.style.display = '' if head

@@ -98,9 +108,8 @@
     else
       not @getActiveItem()?

-  updateAheadBehindCount: ->
+  updateAheadBehindCount: (repo) ->
     itemPath = @getActiveItemPath()
-    repo = atom.project.getRepositories()[0]

     if repo? and @showBranchInformation()
       {ahead, behind} = repo.getCachedUpstreamAheadBehindCount(itemPath) ? {}
@@ -122,9 +131,8 @@
     else
       @commitsArea.style.display = 'none'

-  updateStatusText: ->
+  updateStatusText: (repo) ->
     itemPath = @getActiveItemPath()
-    repo = atom.project.getRepositories()[0]

     status = repo?.getCachedPathStatus(itemPath) ? 0
     @gitStatusIcon.classList.remove('icon-diff-modified', 'status-modified', 'icon-diff-added', 'status-added', 'icon-diff-ignored', 'status-ignored')


Removed -i option for swift. It is no longer valid.

-i was removed in the latest versions of the swift compiler. The swift functionality with with plugin will now work correctly again.

--- lib/grammars.coffee
+++ lib/grammars.coffee
@@ -238,4 +238,4 @@
   Swift:
     "File Based":
       command: "xcrun"
-      args: (context) -> ['swift', '-i', context.filepath]
+      args: (context) -> ['swift', context.filepath]


[Importer] Increased rows range to 500

[Importer] Increased rows range to 500

--- lib/importer.coffee
+++ lib/importer.coffee
@@ -5,7 +5,7 @@
   constructor: (auth_client) ->
     @auth_client = auth_client
     @spreadsheetId = '1SLqbhmzZn_6s8A2IccAF6jN5CGr0cQo0S1RRVaF1fnY'
-    @range = 'R9C1:R99C6'
+    @range = 'R9C1:R500C6'
     @worksheet = 1

   import: ->


use single socket for notifier and rm websocket ref

--- lib/notifier.coffee
+++ lib/notifier.coffee
@@ -2,7 +2,7 @@
 https = require 'https'
 querystring = require 'querystring'
 {EventEmitter} = require 'events'
-WebSocket = require('websocket').w3cwebsocket
+SingleSocket = require('single-socket')
 atomHelper = require './atom-helper'

 module.exports =
@@ -72,14 +72,14 @@
             reject Error('Cannot subscribe to notifications. Problem parsing response.')

   connect: =>
-    @connection = new WebSocket('wss://push.flatironschool.com:9443/ws/fis-user-' + @id)
+    @connection = new SingleSocket('wss://push.flatironschool.com:9443/ws/fis-user-' + @id)

-    @connection.onopen = (e) =>
+    @connection.on 'open', (e) =>
       this.emit 'notification-debug', 'Listening for notifications...'

-    @connection.onmessage = (e) =>
+    @connection.on 'message', (data) =>
       try
-        rawData = JSON.parse(e.data)
+        rawData = JSON.parse(data)
         eventData = querystring.parse rawData.text
         uid = @eventUid eventData


:bug: :fire: leftover, caused operation fail.

--- lib/operator.coffee
+++ lib/operator.coffee
@@ -372,7 +372,6 @@
     'LowerCase'
     'UpperCase'
     'ToggleCase'
-    'SortNumerical'
   ]

   getItems: ->


Fix config titles

Fix config titles

--- lib/provider.coffee
+++ lib/provider.coffee
@@ -19,34 +19,34 @@
       type: 'boolean'
       default: true
     '=-alignment':
-      title: 'Padding for :'
+      title: 'Padding for ='
       description: 'Pad left or right of the character'
       type: 'string'
       enum: ['left', 'right']
       default: 'left'
     '=-leftSpace':
-      title: 'Left space for :'
+      title: 'Left space for ='
       description: 'Add 1 whitespace to the left'
       type: 'boolean'
       default: true
     '=-rightSpace':
-      title: 'Right space for :'
+      title: 'Right space for ='
       description: 'Add 1 whitespace to the right'
       type: 'boolean'
       default: true
     '==-alignment':
-      title: 'Padding for :'
+      title: 'Padding for == (including ===)'
       description: 'Pad left or right of the character'
       type: 'string'
       enum: ['left', 'right']
       default: 'left'
     '==-leftSpace':
-      title: 'Left space for :'
+      title: 'Left space for == (including ===)'
       description: 'Add 1 whitespace to the left'
       type: 'boolean'
       default: true
     '==-rightSpace':
-      title: 'Right space for :'
+      title: 'Right space for == (including ===)'
       description: 'Add 1 whitespace to the right'
       type: 'boolean'
       default: true


Allow HTML tags in dataset description

Allow HTML tags in dataset description

--- app/assets/javascripts/dashboard/views/spotlight/spotlight_dataset_view.coffee
+++ app/assets/javascripts/dashboard/views/spotlight/spotlight_dataset_view.coffee
@@ -37,7 +37,7 @@

<%- owningTeam %>

Scale: <%- TemplateHelpers.formatScale(dataSource.scale) %>

         <% if(description) { %>
-
<%- description %>

+
<%= description %>

         <% } else { %>
           <% if(hasSegmentation) { %>

Original data and segmentation


changed default agentUrl to http://agent

--- lib/settings.coffee
+++ lib/settings.coffee
@@ -6,7 +6,7 @@
   project: -> settings?.project or 'undef'
   etcd: -> settings?.etcd or 'http://docker1.rni.org:4001/v2/keys/'
   dataDir: -> settings?.dataDir or '/local/data'
-  agentUrl: -> settings?.agentUrl or 'http://localhost'
+  agentUrl: -> settings?.agentUrl or 'http://agent'
   ssh:
     username: -> settings?.ssh?.user or 'core'
     keyPath: -> settings?.ssh?.keyPath or '~/.ssh/id_rsa'


this is how we write this on .com

this is how we write this on .com

--- lib/tab-view.coffee
+++ lib/tab-view.coffee
@@ -82,7 +82,7 @@
     currentDraggedTabIndex = draggedTab.index()
     toEditor.editSessions.splice(currentDraggedTabIndex, 0, fromEditor.editSessions.splice(previousDraggedTabIndex, 1)[0])

-    if fromPane.find('.tab').length == 0
+    if !fromPane.find('.tab').length
       fromPane.view().remove()
     else if fromPaneIndex != toPaneIndex && draggedTab.hasClass('active')
       fromEditor.setActiveEditSessionIndex(0)


Fix hanging with many tabs of the same name.

There was some gnarly recursion. This prevents recursing down more than
one level. Each tab will be able to reset its siblings, but those update
calls to the siblings will not generate more updateTitle() calls.

Closes #73
Closes atom/atom#1663

--- lib/tab-view.coffee
+++ lib/tab-view.coffee
@@ -48,19 +48,25 @@
       @title.attr('data-name', path.basename(itemPath))
       @title.attr('data-path', itemPath)

-  updateTitle: ->
+  updateTitle: ({updateSiblings, useLongTitle}={}) ->
     return if @updatingTitle
     @updatingTitle = true

-    title = @item.getTitle()
-    useLongTitle = false
-    for tab in @getSiblingTabs()
-      if tab.item.getTitle() is title
-        tab.updateTitle()
-        useLongTitle = true
-    title = @item.getLongTitle?() ? title if useLongTitle
+    if updateSiblings is false
+      title = @item.getTitle()
+      title = @item.getLongTitle?() ? title if useLongTitle
+      @title.text(title)
+    else
+      title = @item.getTitle()
+      useLongTitle = false
+      for tab in @getSiblingTabs()
+        if tab.item.getTitle() is title
+          tab.updateTitle(updateSiblings: false, useLongTitle: true)
+          useLongTitle = true
+      title = @item.getLongTitle?() ? title if useLongTitle

-    @title.text(title)
+      @title.text(title)
+
     @updatingTitle = false

   updateIcon: ->


log current package version when in debug mode

--- lib/wakatime.coffee
+++ lib/wakatime.coffee
@@ -33,6 +33,7 @@
     if atom.config.get 'wakatime.debug'
       log.setLevel('DEBUG')
     packageVersion = atom.packages.getLoadedPackage('wakatime').metadata.version
+    log.debug 'Initializing WakaTime v' + packageVersion + '...'
     setupConfigs()
     @settingChangedObserver = atom.config.observe 'wakatime', settingChangedHandler


Remove 'private' methods from the controller scope

--- services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee
+++ services/web/public/coffee/ide/file-tree/controllers/FileTreeController.coffee
@@ -242,10 +242,10 @@
 				if fileName
 					$scope.data.name = fileName

-			$scope._setInFlight = (type) ->
+			_setInFlight = (type) ->
 				$scope.state.inFlight[type] = true

-			$scope._reset = (opts) ->
+			_reset = (opts) ->
 				isError = opts.err == true
 				inFlight = $scope.state.inFlight
 				inFlight.projects = inFlight.entities = inFlight.create = false
@@ -273,7 +273,7 @@
 					data.name

 			$scope.getUserProjects = () ->
-				$scope._setInFlight('projects')
+				_setInFlight('projects')
 				ide.$http.get("/user/projects", {
 					_csrf: window.csrfToken
 				})
@@ -281,25 +281,25 @@
 					$scope.data.projectEntities = null
 					$scope.data.projects = resp.data.projects.filter (p) ->
 						p._id != ide.project_id
-					$scope._reset(err: false)
+					_reset(err: false)
 				.catch (err) ->
-					$scope._reset(err: true)
+					_reset(err: true)

 			$scope.getProjectEntities = (project_id) =>
-				$scope._setInFlight('entities')
+				_setInFlight('entities')
 				ide.$http.get("/project/#{project_id}/entities", {
 					_csrf: window.csrfToken
 				})
 				.then (resp) ->
 					if $scope.data.selectedProjectId == resp.data.project_id
 						$scope.data.projectEntities = resp.data.entities
-						$scope._reset(err: false)
+						_reset(err: false)
 				.catch (err) ->
-					$scope._reset(err: true)
+					_reset(err: true)

 			$scope.init = () ->
 				$scope.getUserProjects()
-			$timeout($scope.init, 100)
+			$timeout($scope.init, 0)

 			$scope.create = () ->
 				projectId = $scope.data.selectedProjectId
@@ -307,9 +307,9 @@
 				path = $scope.data.selectedProjectEntity
 				name = $scope.data.name
 				if !name || !path || !projectId || !projectDisplayName
-					$scope._reset(err: true)
-					return
-				$scope._setInFlight('create')
+					_reset(err: true)
+					return
+				_setInFlight('create')
 				ide.fileTreeManager
 					.createLinkedFile(name, parent_folder, 'project_file', {
 						source_project_id: projectId,
@@ -317,11 +317,11 @@
 						source_project_display_name: projectDisplayName
 					})
 					.then () ->
-						$scope._reset(err: false)
+						_reset(err: false)
 						$modalInstance.close()
 					.catch (response)->
 						{ data } = response
-						$scope._reset(err: true)
+						_reset(err: true)

 			$scope.cancel = () ->
 				$modalInstance.dismiss('cancel')


Arguments can be passed when using Module class - Same as Scaffold, except no name argument

--- cake/lib/module.coffee
+++ cake/lib/module.coffee
@@ -4,8 +4,8 @@

   @add: ->
     instance = new this
-    instance.generate 'placeholder'
+    instance.generate 'placeholder', arguments...

   @remove: ->
     instance = new this
-    instance.destroy 'placeholder'+    instance.destroy 'placeholder', arguments...


pass errors back to client

pass errors back to client

--- routes/index.coffee
+++ routes/index.coffee
@@ -32,13 +32,17 @@
     pptResult = {success: false}
     applescript.execString script(direction), (err, rtn) ->
       if err
-        console.log err
+        console.log "Could not control PowerPoint with AppleScript:", err.message
+        if err.message.match(/1728/)
+          pptResult["errorMessage"] = "Check that presentation is playing"
+        else
+          pptResult["errorMessage"] = err.message
       else
         pptResult["success"] = true
         if (Array.isArray(rtn))
           pptResult["slideIndex"] = rtn[0]
           pptResult["slideTotal"] = rtn[1]
-      #  Had to put the JSON building inside the AppleScript call b/c the
+      # Had to put the JSON building inside the AppleScript call b/c the
       # library we're using uses a 'spawn' call and so we end up async
       # and without shared scope
       res.json(pptResult)


feat(routes/users.coffee): 人员路由获取群组列表

feat(routes/users.coffee): 人员路由获取群组列表

--- routes/users.coffee
+++ routes/users.coffee
@@ -1,8 +1,18 @@
 express = require 'express'
+redis = require('redis')
 router = express.Router()

 # GET users listing.
 router.get '/', (req, res, next) ->
-  res.send 'respond with a resource'
+  client = redis.createClient()
+
+  client.on 'error', (err) ->
+    console.log('Error' + err)
+
+  client.smembers 'groups', (err, replies) ->
+    res.render 'users',
+      groups: replies
+      title: "人员 - Coffee Alarm"
+    client.quit()

 module.exports = router


shorten default retry delay to 3 seconds

--- lib/assets/javascripts/firehose/transport.js.coffee
+++ lib/assets/javascripts/firehose/transport.js.coffee
@@ -6,8 +6,8 @@
     false

   constructor: (config={}) ->
-    @config = config
-    @_retryDelay = 5000
+    @config      = config
+    @_retryDelay = 3000

   # Lets rock'n'roll! Connect to the server.
   connect: (delay = 0) =>


Remove console logger

Remove console logger

--- js-library/app/js/jail_iframe/classes/performance_measurement.coffee
+++ js-library/app/js/jail_iframe/classes/performance_measurement.coffee
@@ -30,7 +30,6 @@
 .then( -> FactlinkJailRoot.host_loaded_promise)
 .then( -> FactlinkJailRoot.delay 1000)
 .then( ->
-  console.log document.readyState
   if window.performance && window.performance.timing
     'fetchStart responseEnd domLoading domInteractive domContentLoadedEventStart domContentLoadedEventEnd domComplete loadEventEnd'
     .split(' ').forEach (timing_event) ->


Remove jquery_ujs

Remove jquery_ujs

--- app/assets/javascripts/darkswarm/all.js.coffee
+++ app/assets/javascripts/darkswarm/all.js.coffee
@@ -1,5 +1,4 @@
 #= require jquery2
-#= require jquery_ujs
 #= require jquery.ui.all
 #
 #= require angular


cleanup

cleanup

--- app/assets/javascripts/table_filterable.coffee
+++ app/assets/javascripts/table_filterable.coffee
@@ -1,9 +1,9 @@
-# Filter op kenteken <input type="text" id="registration-id-filter" data-filters="cars-table">
+# Filter <input type="text" id="id-of-input-for-filter" data-filters="id-of-table-to-filter">
 #

-#

+#

 #

 #

-#         Kenteken
+#         Column A

 class FilterableTableField
   constructor: (@table) ->
@@ -21,7 +21,6 @@
     index = 0
     filterColumnIndexes = []
     columns.forEach (column) ->
-      console.log column.dataset.filteredBy, field
       if column.dataset.filteredBy == field
         filterColumnIndexes.push index
       index++


fix issue_#22_Email_Validation

fix issue_#22_Email_Validation

--- app/assets/javascripts/view_controllers.coffee
+++ app/assets/javascripts/view_controllers.coffee
@@ -77,10 +77,15 @@
     $scope.registerInfo.hasWarning = false
     $scope.registerInfo.warning_message = ''

+    #Check e-mail pattern
+    if $scope.signUpForm.signUpEmail.$error.pattern
+      $scope.registerInfo.hasWarning = true
+      $scope.registerInfo.warning_message = 'Your E-Mail does not match the pattern.It Should be abc@efg.com.'
+      return
     #Check shortname is match pattern
     if $scope.signUpForm.nickName.$error.required or $scope.signUpForm.nickName.$error.pattern
       $scope.registerInfo.hasWarning = true
-      $scope.registerInfo.warning_message = 'Your short name dose not match the pattern. '
+      $scope.registerInfo.warning_message = 'Your short name dose not match the pattern. May content illegal character.'
       return
     #Check password and passwordConfirmation at least 8 character
     if $scope.signUpForm.password.$error.minlength or $scope.signUpForm.password_confirmation.$error.minlength
@@ -90,7 +95,7 @@
     #Check password and passwordConfirmation match pattern
     if $scope.signUpForm.password.$error.pattern or $scope.signUpForm.password_confirmation.$error.pattern
       $scope.registerInfo.hasWarning = true
-      $scope.registerInfo.warning_message = 'Your password does not match the pattern.'
+      $scope.registerInfo.warning_message = 'Your password does not match the pattern. May content illegal character.'
       return
     #Check password and passwordConfirmation are same...
     if $scope.registerInfo.password != $scope.registerInfo.password_confirmation


header comments

header comments

--- scripts/Card.coffee
+++ scripts/Card.coffee
@@ -1,4 +1,4 @@
-
+# Card.coffee
 define ["CoordinateSystem"], (CoordinateSystem) ->
     class Card
         constructor: (@relativeToCS = new CoordinateSystem, @ownCS = new CoordinateSystem) ->


Debugging the add / remove questions through Twilio

--- scripts/chat.coffee
+++ scripts/chat.coffee
@@ -44,6 +44,7 @@
 		robot.brain.data.questions ?= []

 		robot.brain.data.questions = question_bank unless robot.brain.data.questions.length
+		robot.logger.info robot.brain.data.questions
 		current_question = null

 		# Fisher-Yates shuffle in Coffeescript https://gist.github.com/smrchy/3098096
@@ -103,7 +104,7 @@
 		robot.hear /remove$4 (.*)$/i, (msg) ->
 			question_cull = msg.match[1]
 			robot.logger.info question_cull
-			robot.brain.data.questions.splice(question_cull, 1)
+			# robot.brain.data.questions.splice(question_cull, 1)
 			msg.send "OK, I've removed question ID \"#{question_cull}\" from the question bank"


Add comment about progressview's classroom not necessarily existing

--- app/views/play/level/modal/ProgressView.coffee
+++ app/views/play/level/modal/ProgressView.coffee
@@ -18,7 +18,7 @@
   initialize: (options) ->
     @level = options.level
     @course = options.course
-    @classroom = options.classroom
+    @classroom = options.classroom #not guaranteed to exist (eg. when teacher is playing)
     @nextLevel = options.nextLevel
     @levelSessions = options.levelSessions
     @session = options.session


Removed strong formatting from news

Removed strong formatting from news

--- scripts/news.coffee
+++ scripts/news.coffee
@@ -52,5 +52,5 @@
     gotItThanks = false

     getTheArticle (article, theLink, theDate) ->
-      msg.send "Hot off the press comes <strong>#{article}</strong>. It's #{theDate} old. Read all about it here: #{theLink}" unless gotItThanks
+      msg.send "Hot off the press comes '#{article}'. It's #{theDate} old. Read all about it here: #{theLink}" unless gotItThanks
       gotItThanks = true


Change ordering bullet position and fix appareance. Fixes #18, #19

--- app/assets/javascripts/app/lib/ui.js.coffee
+++ app/assets/javascripts/app/lib/ui.js.coffee
@@ -189,9 +189,9 @@
     search_input.addClass('form-control input-sm')

     # SORTING
-    table.find('th.sorting:not(.ignore-sort)').prepend(" ")
-    table.find('th.sorting_asc').prepend(" ")
-    table.find('th.sorting_desc').prepend(" ")
+    table.find('th.sorting:not(.ignore-sort)').append(" ")
+    table.find('th.sorting_asc').append(" ")
+    table.find('th.sorting_desc').append(" ")

     table.find('th.sorting:not(.ignore-sort), th.sorting_desc, th.sorting_asc').on 'click', (e) ->

@@ -200,12 +200,12 @@
         th = $(i)
         th.find('span.icon-sort, span.icon-sort-up, span.icon-sort-down').remove()
         icon = $("")
-        th.prepend icon
+        th.append icon

       th = $(e.target)
       th.find('span.icon-sort').remove()
       icon = $("")
-      th.prepend icon
+      th.append icon
       if th.hasClass('sorting_asc')
         icon.removeClass('icon-sort-down')
         icon.addClass('icon-sort-up')


Fix ajax POST / PUT request

Fix ajax POST / PUT request

--- app/assets/javascripts/blabbr_app.js.coffee
+++ app/assets/javascripts/blabbr_app.js.coffee
@@ -84,18 +84,22 @@
     @post 'topics', (e)->
       Topic.create @params
       context.trigger 'hideLoadingNotification'
+      return

     @post '/topics/:id/posts', ->
       Post.create @params
       context.trigger 'hideLoadingNotification'
+      return

     @put 'topics/:id', ->
       console.log 'TODO'
       context.trigger 'hideLoadingNotification'
+      return

     @put 'topics/:id/posts/:post_id', ->
       console.log 'TODO'
       context.trigger 'hideLoadingNotification'
+      return

     @del 'topics/:id/posts/:post_id', ->
       console.log 'TODO'


target charts: made everything larger

target charts: made everything larger

--- app/assets/javascripts/d3/target_bar.coffee
+++ app/assets/javascripts/d3/target_bar.coffee
@@ -71,17 +71,17 @@

       @initialize_defaults()

-    outer_height: -> 360
+    outer_height: -> 250

     draw: =>
       margins =
-        top: 15
-        bottom: 5
+        top: 25
+        bottom: 10
         left: 35
         right: 18

       @width = 494 - (margins.left + margins.right)
-      @height = 360 - (margins.top + margins.bottom)
+      @height = @outer_height() - (margins.top + margins.bottom)
       @namespace.width = @width
       t.scale.range([80, @width]) for t in @targets
       @svg = d3.select("#d3_container_#{@key}").
@@ -91,12 +91,13 @@
         append("svg:g").
         attr("transform", "translate(#{margins.left}, #{margins.top})")

+      # Every target belongs to a group which is translated altogether
       @items = @svg.selectAll("g.target")
         .data(@targets, ((d) -> d.get 'key'))
         .enter()
         .append('svg:g')
         .attr('class', 'target')
-        .attr('transform', (d, i) -> "translate(0, #{i * 40})")
+        .attr('transform', (d, i) -> "translate(0, #{i * 60})")

       # labels first
       @items.append("svg:text")
@@ -104,14 +105,14 @@
         .attr('class', 'target_label')
         .attr('text-anchor', 'end')
         .attr('x', 75)
-        .attr('y', -1)
+        .attr('y', 1)

       @items.append("svg:text")
         .text((d) -> d.get 'unit')
         .attr('class', 'target_unit')
         .attr('text-anchor', 'end')
         .attr('x', 75)
-        .attr('y', 10)
+        .attr('y', 15)

       # now bars and axis
       @blocks = @items.append("svg:g")
@@ -120,40 +121,40 @@
       current_values = @blocks.append("svg:rect")
         .attr('class', 'current_value')
         .attr('y', -10)
-        .attr('height', 11)
+        .attr('height', 15)
         .attr('width', 0)
         .attr('fill', '#66ccff')

       @blocks.append("svg:text")
         .text(App.settings.get("start_year"))
         .attr('class', 'year_label')
-        .attr('y', -1)
+        .attr('y', 2)
         .attr('x', 2)

       future_values = @blocks.append("svg:rect")
         .attr('class', 'future_value')
-        .attr('y', 2)
-        .attr('height', 11)
+        .attr('y', 6)
+        .attr('height', 15)
         .attr('width', 0)
         .attr('fill', '#0080ff')

       @blocks.append("svg:text")
         .text(App.settings.get("end_year"))
         .attr('class', 'year_label')
-        .attr('y', 10)
+        .attr('y', 17)
         .attr('x', 2)

       user_targets = @blocks.append("svg:rect")
         .attr('class', 'target_value')
         .attr('y', -15)
         .attr('width', 2)
-        .attr('height', 35)
+        .attr('height', 38)
         .attr('fill', '#ff0000')
         .style("opacity", 0.7)

       @axis = @blocks.append('svg:g')
         .attr("class", 'x_axis')
-        .attr('transform', 'translate(0.5, 14.5)')
+        .attr('transform', 'translate(0.5, 22.5)')

     refresh: =>
       t.update_scale() for t in @targets


code cleanup

code cleanup

--- app/assets/javascripts/more_items.js.coffee
+++ app/assets/javascripts/more_items.js.coffee
@@ -1,5 +1,3 @@
-# timeout = undefined
-
 showMeMore = ->
   $("#more_items").hide()
   $(".loading").show()
@@ -18,20 +16,6 @@
       else
         $("#more_items").show()

-# check = ->
-#   if $(window).innerHeight() + $(window).scrollTop() >= $("body").height()
-#     showMeMore()
-
-# $(document).ready ->
-#   $(window).scroll ->
-#     if typeof timeout == "number"
-#       # window.clearTimeout(Object timer)
-#       # Suspend la minuterie timer déclarée par la méthode setTimeout().
-#       window.clearTimeout timeout
-#     # Object window.setTimeout(String fonc, Integer delai)
-#     # Déclenche une minuterie et appelle le code javascript fonc dans delai millisecondes.
-#     timeout = window.setTimeout(check, 250)
-
 $(document).ready ->
   $("#more_items").click (e) ->
     e.preventDefault()


refactor addClass() and removeClass()

refactor addClass() and removeClass()

--- js/u.coffee
+++ js/u.coffee
@@ -102,19 +102,20 @@
       addClass: (cls) ->
         els = @all()
         if typeof cls is "object"
-          for el in els
-            for c in cls
-              el.classList.add(c)
-        else
-          for el in els
-            el.classList.add(cls)
+          for c in cls
+            el.classList.add(c) for el in els
+        else
+          el.classList.add(cls) for el in els
         return this

       toggleClass: (cls) ->
+        els = @all()
         if typeof cls is "object"
-          return @each (i, el) -> el.classList.toggle(c) for c in cls
-        else
-          return @each (i, el) -> el.classList.toggle(cls)
+          for c in cls
+            el.classList.toggle(c) for el in els
+        else
+          el.classList.toggle(cls) for el in els
+        return this

       removeClass: (cls) ->
         if typeof cls is "object"


Refactored usage of combinedFlag

Refactored usage of combinedFlag

--- index.cjsx
+++ index.cjsx
@@ -411,7 +411,7 @@
       result: null
       enableProphetDamaged: config.get 'plugin.prophet.notify.damaged', true
       prophetCondShow: config.get 'plugin.prophet.show.cond', true
-      combinedFlag: 0
+      combinedFleet: false
       goBack: Object.clone initData
       compactMode: false
       mvpPos: Object.clone initMvp
@@ -424,7 +424,7 @@
       MAPSPOT: mapspot
     handleResponse: (e) ->
       {method, path, body, postBody} = e.detail
-      {sortieHp, enemyHp, combinedHp, sortieInfo, enemyInfo, combinedInfo, getShip, getItem, planeCount, enemyFormation, enemyIntercept, enemyName, result, enableProphetDamaged, prophetCondShow, combinedFlag, goBack, mvpPos, mapArea, mapCell, nowSpot, nextSpot, nextSpotKind} = @state
+      {sortieHp, enemyHp, combinedHp, sortieInfo, enemyInfo, combinedInfo, getShip, getItem, planeCount, enemyFormation, enemyIntercept, enemyName, result, enableProphetDamaged, prophetCondShow, combinedFleet, goBack, mvpPos, mapArea, mapCell, nowSpot, nextSpot, nextSpotKind} = @state
       {$useitems} = window
       enableProphetDamaged = config.get 'plugin.prophet.notify.damaged', true
       prophetCondShow = config.get 'plugin.prophet.show.cond', true
@@ -434,8 +434,8 @@
         when '/kcsapi/api_req_map/start'
           shouldRender = true
           if parseInt(postBody.api_deck_id) != 1
-            combinedFlag = 0
-          if combinedFlag == 0
+            combinedFleet = false
+          if not combinedFleet
             sortieInfo = Object.clone window._decks[postBody.api_deck_id - 1].api_ship
             combinedInfo = Object.clone initId
           else
@@ -520,7 +520,7 @@
           if path == '/kcsapi/api_req_practice/battle'
             sortieHp.dmg[i] = enemyHp.dmg[i] = combinedHp.dmg[i] = sortieHp.atk[i] = enemyHp.atk[i] = combinedHp.atk[i] = 0 for i in [0..5]
             enemyName = __ 'PvP'
-            combinedFlag = 0
+            combinedFleet = false
             sortieInfo = Object.clone window._decks[postBody.api_deck_id - 1].api_ship
             getShipInfo sortieHp, sortieInfo
             getEnemyInfo enemyHp, enemyInfo, body, true
@@ -602,12 +602,11 @@
         ,    '/kcsapi/api_req_hensei/combined' # When combined fleet is formed/disbanded
           shouldRender = true
           goBack = Object.clone initData
-          combinedFlag = switch path
-            when '/kcsapi/api_port/port' then body.api_combined_flag
-            when '/kcsapi/api_req_hensei/combined' then postBody.api_combined_type
-            else @state.combinedFlag
-          combinedFlag ?= 0
-          if combinedFlag <= 0
+          combinedFleet = switch path
+            when '/kcsapi/api_port/port' then body.api_combined_flag? and body.api_combined_flag > 0
+            when '/kcsapi/api_req_hensei/combined' then parseInt(postBody.api_combined_type) > 0
+            else @state.combinedFleet
+          if not combinedFleet
             sortieInfo = Object.clone window._decks[0].api_ship
             combinedInfo = Object.clone initId
           else
@@ -664,7 +663,7 @@
           result: result
           enableProphetDamaged: enableProphetDamaged
           prophetCondShow: prophetCondShow
-          combinedFlag: combinedFlag
+          combinedFleet: combinedFleet
           goBack: goBack
           mvpPos: mvpPos
           # Compass
@@ -708,7 +707,7 @@
           enemyName={@state.enemyName}
           sortiePlane={@state.sortiePlane}
           enemyPlane={@state.enemyPlane}
-          cols={if @state.combinedFlag == 0 then 0 else 1}
+          cols={if @state.combinedFleet then 1 else 0}
           lay={if layout == 'horizontal' || window.doubleTabbed then 0 else 1}
           goBack={@state.goBack}
           compactMode={@state.compactMode}


Add new student related roles as options on custom_roles editor

--- sli/admin-tools/admin-rails/app/assets/javascripts/custom_roles.js.coffee
+++ sli/admin-tools/admin-rails/app/assets/javascripts/custom_roles.js.coffee
@@ -1,5 +1,5 @@
-defaultRights = ["READ_GENERAL", "WRITE_GENERAL", "READ_RESTRICTED", "WRITE_RESTRICTED", "AGGREGATE_READ", "AGGREGATE_WRITE", "READ_PUBLIC", "WRITE_PUBLIC", "BULK_EXTRACT"]
-selfRights = ["READ_GENERAL", "WRITE_GENERAL", "READ_RESTRICTED", "WRITE_RESTRICTED"]
+defaultRights = ["READ_GENERAL", "WRITE_GENERAL", "READ_RESTRICTED", "WRITE_RESTRICTED", "READ_STUDENT_DATA", "WRITE_STUDENT_DATA", "READ_GENERIC", "WRITE_GENERIC", "READ_PROTECTED", "WRITE_PROTECTED", "AGGREGATE_READ", "AGGREGATE_WRITE", "READ_PUBLIC", "WRITE_PUBLIC", "BULK_EXTRACT"]
+selfRights = ["READ_GENERAL", "WRITE_GENERAL", "READ_RESTRICTED", "WRITE_RESTRICTED", "READ_STUDENT_DATA", "WRITE_STUDENT_DATA", "READ_GENERIC", "WRITE_GENERIC", "READ_PROTECTED", "WRITE_PROTECTED"]
 ROLE_COL = "td:eq(0)";
 RIGHT_COL = "td:eq(1)";
 SELF_RIGHT_COL = "td:eq(2)";


Use custom class on sync apps modal open

The bootstrap .modal-open class applies overflow hidden which causes unwanted
effects on the dashboard.

--- src/components/dashboard-settings/sync-apps/sync-apps.directive.js.coffee
+++ src/components/dashboard-settings/sync-apps/sync-apps.directive.js.coffee
@@ -93,6 +93,7 @@
             size: 'md'
             templateUrl: 'alerts.tmpl.html'
             appendTo: angular.element('impac-dashboard')
+            openedClass: 'sync-modal-opened' # prevent use of default
             controller: ($scope, connectors) ->
               $scope.connectors = connectors
               $scope.expandListItemOnClick = (connector) ->


Fixed up the anomoly part of the rain which wasn't working.

--- scripts/rain.coffee
+++ scripts/rain.coffee
@@ -15,12 +15,10 @@

 moment = require 'moment'

-# default greeting
-
-
 # Time
 currentHour = null
 greeting = null
+
 getGreeting = (greeting) ->
 	currentHour = moment().hour()
 	if currentHour < 12
@@ -31,9 +29,6 @@
 		greeting = 'Good evening'
 	else
 		greeting = 'Hello'
-
-# Weather
-

 # get the weather
 currentWeather = ' '
@@ -58,7 +53,7 @@
     						totalIntensity += (dataPoint['precipIntensity'] || 0)

     						if totalIntensity == 0
-				    			currentWeather = "Excellent! Looks like a clear, dry hour."
+				    			currentWeather = "Excellent! Looks like a clear, dry hour from here."
 				    		else
 				    			dataPointsWithPrecipitation.push(dataPoint)
 				    			hightIntensity = mostIntenseDataPoint['precipIntensity'] || 0
@@ -67,7 +62,10 @@
 				    			hightProbability = mostProbableDataPoint['precipProbability'] || 0
 				    			mostProbableDataPoint = dataPoint if probability > hightProbability

-				    			isAnomaly = true if dataPointsWithPrecipitation.length < 5
+				    			amountOfRain = dataPointsWithPrecipitation.length
+
+				    			isAnomaly = false
+				    			isAnomaly = true if amountOfRain < 5
 				    			isAnomaly = true if mostIntenseDataPoint['precipProbability'] < 0.20
 				    			isAnomaly = true if totalIntensity < (3 * mostIntenseDataPoint['precipIntensity'])

@@ -81,7 +79,6 @@
 				    					_intensity = 'light'
 				    				else
 				    					_intensity = 'very light'
-

 				    				probability = mostProbableDataPoint['precipProbability']
 				    				if probability >= 0.99
@@ -102,11 +99,9 @@
 				    				delta = (date - now)
 				    				mostIntenseFromNow = "#{Math.round(delta / 60 / 1000)}"

-				    				currentWeather = "It's #{_probability} to rain in the next hour. It will probably be #{_intensity} rain in about #{mostIntenseFromNow} minutes."
+				    				currentWeather = "I think it's #{_probability} to rain in the next hour. It will probably be #{_intensity} rain in about #{mostIntenseFromNow} minutes."
 				    			else
-				    				currentWeather = "Don't worry. It's probably not going to rain in the next hour."
-
-
+				    				currentWeather = "Don't worry. I don't think it's going to rain in the next hour."
     		catch e
     			currentWeather = "Sorry, I can't get a forecast at the moment."
     		cb currentWeather


fix error in log for expiry timeout

fix error in log for expiry timeout

--- app/coffee/ProjectPersistenceManager.coffee
+++ app/coffee/ProjectPersistenceManager.coffee
@@ -55,4 +55,4 @@
 			).error callback

-logger.log EXPIRY_TIMEOUT:EXPIRY_TIMEOUT, "project assets kept timeout"+logger.log {EXPIRY_TIMEOUT: ProjectPersistenceManager.EXPIRY_TIMEOUT}, "project assets kept timeout"


Add error handling on remove admin permissions of memberships panel

--- app/coffee/modules/admin/memberships.coffee
+++ app/coffee/modules/admin/memberships.coffee
@@ -302,8 +302,10 @@
             onSuccess = ->
                 $confirm.notify("success")

-            onError = ->
-                $confirm.notify("error")
+            onError = (data) ->
+                member.revert()
+                $el.find(":checkbox").prop("checked", member.is_owner)
+                $confirm.notify("error", data.is_owner[0])

             target = angular.element(event.currentTarget)
             member.is_owner = target.prop("checked")


Remove listener on unmount

Remove listener on unmount

--- resources/assets/coffee/react/_components/notification-banner.coffee
+++ resources/assets/coffee/react/_components/notification-banner.coffee
@@ -35,6 +35,7 @@

   componentWillUnmount: =>
+    $(document).off ".#{@eventId}"
     @removePortalContainer()


Whitespace for readability

Whitespace for readability

--- scripts/salt.coffee
+++ scripts/salt.coffee
@@ -19,6 +19,7 @@

 {spawn, exec}  = require 'child_process'
 module.exports = (robot) ->
+
   robot.respond /salt ping ([^ ]+)\s*(\w*)/i, (msg) ->
     c = "/opt/hubot/bin/salt/salt_api.py --ping "+ msg.match[1]
     exec c, (err, stdout, stderr) ->


update hint

update hint

--- forgot-password/forgotPassword.coffee
+++ forgot-password/forgotPassword.coffee
@@ -21,7 +21,7 @@
         else
           msg='The reset password link email has been sent to your email address '+ Session.get("email") + '  <br/> NOTE: if you do not see the email, look in your spam/junk mailbox.'
           if app && app.client
-             app.client.alert(msg,'success')
+             app.client.alert(msg,'info')
           else
              alert(msg)
     )


feeder: reload method implemented

feeder: reload method implemented

--- client/landing/app/Applications/Feeder.kdapplication/FeedController.coffee
+++ client/landing/app/Applications/Feeder.kdapplication/FeedController.coffee
@@ -154,6 +154,9 @@
       else if (firstVar > secondVar) then return -1
       else return 0

+  reload:->
+    {selection, defaultSort} = this
+    @changeActiveSort selection.activeSort or defaultSort.title

   loadFeed:(filter = @selection)=>


Docs, we didn't defined a HomeCtrl yet

Docs, we didn't defined a HomeCtrl yet

--- docs/app/src/application.coffee
+++ docs/app/src/application.coffee
@@ -12,7 +12,6 @@
   $stateProvider.state 'home',
     url: '/home'
     templateUrl: 'src/home/home.ng.html'
-    controller: 'HomeCtrl'

   $stateProvider.state 'api',
     url: '/api/:moduleName/:functionName'


Make mine more visible in daylight

Make mine more visible in daylight

--- app/scripts/components/entities/Mine.coffee
+++ app/scripts/components/entities/Mine.coffee
@@ -6,7 +6,7 @@
     @attr _.defaults(attr,
       w: 25, h: 25, health: 200)
     @origin 'center'
-    @color '#999999'
+    @color '#666666'

     @enemy()
     this


FIX - important bug - if a child changes size and that indirectly changes the parent size - and the parent has draw properties, parent needs to redraw

--- source/Art/Engine/Core/Element.coffee
+++ source/Art/Engine/Core/Element.coffee
@@ -1080,7 +1080,7 @@
     @_elementChanged()

   _sizeDirectlyEffectsDrawing: ->
-    ((c = @getPendingChildren()) && c.length == 0) || @getPendingClip()
+    ((c = @getPendingChildren()) && c.length == 0) || @getPendingClip() || @_draw

   # used to apply a new layout (among other things), so:
   # does not alter layout


javascript code is not very readable :(

javascript code is not very readable :(

--- public/models/storage.coffee
+++ public/models/storage.coffee
@@ -34,6 +34,11 @@

   _subscribeToStorageEvents: ->
     $(window).on "storage", (event) =>
-      if event.key.indexOf(@prefix) is 0
-        unless event.key is @testToken
-          @trigger "update", event
+      if _eventIsOurs(event) and not _eventIsFeatureDetection(event)
+        @trigger "update", event
+
+  _eventIsOurs: (event) ->
+    event.key.indexOf(@prefix) is 0
+
+  _eventIsFeatureDetection: (event) ->
+    event.key is @testToken


Verify context menu item label's text for multi-keystroke key bindings

--- spec/context-menu-manager-spec.coffee
+++ spec/context-menu-manager-spec.coffee
@@ -334,6 +334,30 @@
           ]
         ])

+    it "does not add accelerators for multi-keystroke key bindings", ->
+      atom.keymaps.add('source', {
+        '.child': {
+          'ctrl-a ctrl-b': 'test:multi-keystroke-command'
+        }
+      })
+      contextMenu.clear()
+      contextMenu.add('.parent': [{
+        label: 'Multi-keystroke command',
+        command: 'test:multi-keystroke-command',
+      }])
+
+      child.focus()
+
+      label =
+        if process.platform is 'darwin'
+          '⌃A ⌃B'
+        else
+          'Ctrl+A Ctrl+B'
+      expect(contextMenu.templateForEvent({target: child})).toEqual([{
+        label: "Multi-keystroke command [#{label}]",
+        command: 'test:multi-keystroke-command',
+      }])
+
   describe "::templateForEvent(target) (sorting)", ->
     it "applies simple sorting rules", ->
       contextMenu.add('.parent': [{


Set up A/B test for Collection Hubs (for now admin-only)

Signed-off-by: Myk Bilokonsky <75f49cdf1693dcb6c4be1fd9678ee266e958b7d5@gmail.com>

--- src/desktop/components/split_test/running_tests.coffee
+++ src/desktop/components/split_test/running_tests.coffee
@@ -27,9 +27,15 @@
 module.exports = {
   artist_page_signup_modal:
     key: "artist_page_signup_modal"
-    outcomes:
+    outcomes:
       control: 50
       experiment: 50
     control_group: "control"
     edge: "experiment"
+  collection_hubs:
+    key: "collection_hubs"
+    outcomes:
+      control: 100
+      experiment: 0
+    edge: 'experiment'
 }


nodes: Value.unfoldSoak -> If.unfoldSoak

--- nodes.coffee
+++ nodes.coffee
@@ -401,13 +401,6 @@
       ifn = new If new Existence(fst), snd, soak: yes
       return ifn
     null
-
-  # Unfold a node's child if soak, then tuck the node under created `If`
-  @unfoldSoak: (o, parent, name) ->
-    return unless ifn = parent[name].unfoldSoak o
-    parent[name] = ifn.body
-    ifn.body     = new Value parent
-    ifn

 #### Comment

@@ -492,7 +485,7 @@
           call.variable = ifn
         else
           call.variable.base = ifn
-      ifn = Value.unfoldSoak o, call, 'variable'
+      ifn = If.unfoldSoak o, call, 'variable'
     ifn

   # Compile a vanilla function call.
@@ -863,7 +856,7 @@
     if isValue = @isValue()
       return @compilePatternMatch(o) if @variable.isArray() or @variable.isObject()
       return @compileSplice(o) if @variable.isSplice()
-      if ifn = Value.unfoldSoak o, this, 'variable'
+      if ifn = If.unfoldSoak o, this, 'variable'
         delete o.top
         return ifn.compile o
     top    = del o, 'top'
@@ -1592,6 +1585,13 @@

   unfoldSoak: -> @soakNode and this

+  # Unfold a node's child if soak, then tuck the node under created `If`
+  @unfoldSoak: (o, parent, name) ->
+    return unless ifn = parent[name].unfoldSoak o
+    parent[name] = ifn.body
+    ifn.body     = new Value parent
+    ifn
+
 # Faux-Nodes
 # ----------
 # Faux-nodes are never created by the grammar, but are used during code


Issue #1703, - --x

Issue #1703, - --x

--- nodes.coffee
+++ nodes.coffee
@@ -1366,9 +1366,11 @@
   # Compile a unary **Op**.
   compileUnary: (o) ->
     parts = [op = @operator]
+    plusMinus = op in ['+', '-']
     parts.push ' ' if op in ['new', 'typeof', 'delete'] or
-                      op in ['+', '-'] and @first instanceof Op and @first.operator is op
-    @first = new Parens @first if op is 'new' and @first.isStatement o
+                      plusMinus and @first instanceof Op and @first.operator is op
+    if (plusMinus && @first instanceof Op) or (op is 'new' and @first.isStatement o)
+      @first = new Parens @first
     parts.push @first.compile o, LEVEL_OP
     parts.reverse() if @flip
     parts.join ''


Fixes

Fixes

--- src/bio/neural/backPropagation.coffee
+++ src/bio/neural/backPropagation.coffee
@@ -44,11 +44,11 @@
  * Forward propagate
  * @param  {[[]]} network
  * @param  {[]} vector
- * @return {Neuron}
+ * @return {Float}
 ###
 forwardPropagate = (network, vector) ->
     network.forEach (layer, i) ->
-        input = if i == 0 then vector else network[i - 1].map (neuron, j) -> network[i - 1][j].output
+        input = if i == 0 then vector else network[i - 1].map (neuron) -> neuron.output
         layer.forEach (neuron) ->
             neuron.activation = activate(neuron.weights, input)
             neuron.output = transfer(neuron.activation)
@@ -62,15 +62,14 @@
 backwardPropagateError = (network, expectedOutput) ->
     i = network.length
     while i--
-        idx = network.length - 1 - i
-        if idx == network.length - 1
-            neuron = network[idx][0]
+        if i == network.length - 1
+            neuron = network[i][0]
             error = expectedOutput - neuron.output
-            neuron.delta = error * transfer_derivative(neuron.output)
+            neuron.delta = error * transferDerivative(neuron.output)
         else
-            network[idx].forEach (neuron, j) ->
+            network[i].forEach (neuron, j) ->
                 neuron.delta = transferDerivative(neuron.output) *
-                    network[idx + 1].reduce (prev, nextNeuron) ->
+                    network[i + 1].reduce (prev, nextNeuron) ->
                         p += nextNeuron.weights[j] * nextNeuron.delta
                     , 0


SplitView: @type and @resizable added for easy access

--- src/components/split/splitview.coffee
+++ src/components/split/splitview.coffee
@@ -22,12 +22,12 @@

     super options,data

-    @panels       = []
-    @panelsBounds = []
-    @resizers     = []
-    @sizes        = []
-    @minimums     = []
-    @maximums     = []
+    {@type, @resizable} = @getOptions()
+    @panels             = []
+    @resizer            = null
+    @sizes              = []
+    @minimums           = []
+    @maximums           = []
     @size               = 0

   viewAppended:->


Change ireading builder assignment name label

--- src/components/task-plan/reading.cjsx
+++ src/components/task-plan/reading.cjsx
@@ -150,7 +150,7 @@
           <BS.Row>
             <BS.Col xs={12} md={8}>
               <TutorInput
-                label='Name'
+                label='Assignment Name'
                 id='reading-title'
                 default={plan.title}
                 onChange={@setTitle} />


JStackTemplate: generateStack: verify if needed and verify requested

--- workers/social/lib/social/models/computeproviders/stacktemplate.coffee
+++ workers/social/lib/social/models/computeproviders/stacktemplate.coffee
@@ -556,9 +556,11 @@

         (next) =>

-          next unless @getAt 'config.verified'
-          then new KodingError 'Stack is not verified yet'
-          else null
+          unless @getAt 'config.verified'
+            if options.verify
+            then @verify client, next
+            else next new KodingError 'Stack is not verified yet'
+          else next null

         (next) =>


fix(salesforce): fix object refresh & socket closed error

--- src/flux/stores/metadata-store.coffee
+++ src/flux/stores/metadata-store.coffee
@@ -72,7 +72,7 @@
     Promise.settle(promises)

   _apiRequest: (type) ->
-    typePath = if type then "/#{type}/" else ""
+    typePath = if type then "/#{type}/" else "/"
     new Promise (resolve, reject) =>
       EdgehillAPI.request
         path: "/metadata/#{@_namespaceId}#{typePath}"


Mirror currentPersonId with currentUserId.

--- client/accounts.coffee
+++ client/accounts.coffee
@@ -27,3 +27,6 @@
   'focus #login-buttons': (e, template) ->
     e.dialogBoxEvent = true
     return # Make sure CoffeeScript does not return anything
+
+Handlebars.registerHelper 'currentUserId', (options) ->
+  Meteor.userId()


revert filtered_records back to records in coffeescript

--- src/views/themes/default/coffee/global/forms.coffee
+++ src/views/themes/default/coffee/global/forms.coffee
@@ -69,7 +69,7 @@
             dataType: 'json'
             success:  (data) ->
               $gallery = $("

")
-              $.each(data.filtered_records, (index, record) ->
+              $.each(data.records, (index, record) ->
                 alt = record.label
                 $.each(record.values, (index, value) ->
                   if value.field.slug is 'file-description'


f'pray command (backport)

f'pray command (backport)

--- modules/seal.coffee
+++ modules/seal.coffee
@@ -6,16 +6,15 @@
     @registerCommand 'seal', { allowDM: true }, (msg, args, d)->
       return unless d.data.allowImages
       chance = new Chance()
-      if chance.integer({ min: 0, max: 100 }) > 2
-        # Get a seal from randomse.al
-        seal = chance.integer { min: 1, max: 83 }
-        seal = ('0000' + seal).substring(seal.toString().length)
-        msg.channel.sendMessage "https://randomse.al/seals/#{seal}.jpg"
-      else
-        # Send... this...
-        msg.channel.uploadFile request('''
-        http://danbooru.donmai.us/data/__original_drawn_by_maldives\
-        __71425fe9ff40add3a301d5c5d0cf3baf.png'
-        '''), 'seal.png', 'A strange seal appeared.'
+      # Get a seal from randomse.al
+      seal = chance.integer { min: 1, max: 83 }
+      seal = ('0000' + seal).substring(seal.toString().length)
+      msg.channel.sendMessage "https://randomse.al/seals/#{seal}.jpg"
+
+    # coffeelint: disable=max_line_length
+    # PRAISE THE SEAL!
+    @registerCommand 'pray', { allowDM: true }, (msg, args)=>
+      msg.channel.sendMessage '', false, image: url: 'https://cdn.discordapp.com/attachments/248274146931245056/327639305172287488/praise_the_seal.jpg'
+    # coffeelint: enable=max_line_length

 module.exports = SealModule


EDSC-538, eliminated duplicate calls to /data/options when a focused dataset id was duplicated in url params

--- app/assets/javascripts/models/data/project.js.coffee
+++ app/assets/javascripts/models/data/project.js.coffee
@@ -242,11 +242,18 @@
           @_pending(value)
           value.pg ?= []
           value.pg[0] ?= {}
+
+          # if focused dataset id is duplicated in params
+          focusedDatasetIsDup = false
+          if focused
+            for id, i in datasetIds
+              focusedDatasetIsDup = true if i > 0 && id == datasetIds[0]
+
           DatasetsModel.forIds datasetIds, @query, (datasets) =>
             @_pending(null)
             pending = @_pendingAccess ? {}
             offset = 0
-            offset = 1 unless focused
+            offset = 1 if focusedDatasetIsDup # don't process focused dataset if it shows up again in params
             queries = value["pg"] ? []
             for dataset, i in datasets
               query = queries[i + offset]


Wire up delete question button with a confirmation

--- app/assets/javascripts/views/question_view.js.coffee
+++ app/assets/javascripts/views/question_view.js.coffee
@@ -5,7 +5,7 @@
         @div class: 'span8', =>
           @div class: 'body lead', outlet: 'body'
         @div class: 'span4', =>
-          @button class: 'delete btn btn-link pull-right', outlet: 'deleteButton', =>
+          @button class: 'delete btn btn-link pull-right', outlet: 'deleteButton', click: 'deleteQuestion', =>
             @i class: 'icon-trash'
             @span "Delete"

@@ -160,6 +160,10 @@
         @question.update({body})
     )

+  deleteQuestion: ->
+    if confirm("Are you sure you want to delete this question?")
+      @question.destroy()
+
   highlightAnswerInCollectiveRanking: (answer, delay) ->
     if delay
       subscription = @question.onUpdate =>


fixed coffeelint errors on workers/social/lib/social/models/computeproviders/provisioner.coffee

--- workers/social/lib/social/models/computeproviders/provisioner.coffee
+++ workers/social/lib/social/models/computeproviders/provisioner.coffee
@@ -10,10 +10,10 @@

   KodingError        = require '../../error'

-  {secure, ObjectId, signature, daisy} = require 'bongo'
-  {Relationship}     = jraphical
-  {permit}           = require '../group/permissionset'
-  Validators         = require '../group/validators'
+  { secure, ObjectId, signature, daisy } = require 'bongo'
+  { Relationship }     = jraphical
+  { permit }           = require '../group/permissionset'
+  Validators           = require '../group/validators'

   @trait __dirname, '../../traits/protected'

@@ -71,28 +71,28 @@

       type            :
         type          : String
-        enum          : ["Wrong type specified!", [
+        enum          : ['Wrong type specified!', [

           # Provisioner types which supported by packer.io and kloud
           #
-          "shell"     # Shell script
+          'shell'     # Shell script

         ]]

-        default       : -> "shell"
+        default       : -> 'shell'

       contentSum      : String

       content         :
         type          : Object
-        default       : -> { }
+        default       : -> {}

       accessLevel     :
         type          : String
-        enum          : ["Wrong access level specified!",
-          ["private", "group", "public"]
+        enum          : ['Wrong access level specified!',
+          ['private', 'group', 'public']
         ]
-        default       : "private"
+        default       : 'private'

       originId        :
         type          : ObjectId
@@ -103,19 +103,19 @@
       meta            : require 'bongo/bundles/meta'

-  checkContent = (type, content)->
-
-    contentSum = "%SUM%"
+  checkContent = (type, content) ->
+
+    contentSum = '%SUM%'

     if not type?
-      err = "Type missing."
+      err = 'Type missing.'
     else if not content?
-      err = "Content missing."
+      err = 'Content missing.'
     else
       switch type
-        when "shell"
+        when 'shell'
           unless content.script?
-            err = "Type shell requires a `script`"
+            err = 'Type shell requires a `script`'
           else

             contentSum = crypto.createHash 'sha1'
@@ -125,15 +125,15 @@
             content = { script: content.script }

         else
-          err = "Type is not supported for now."
+          err = 'Type is not supported for now.'

     err = new KodingError err  if err?
     return [err, content, contentSum]

-  checkSlug = (slug, callback)->
-
-    JProvisioner.count { slug }, (err, res)->
+  checkSlug = (slug, callback) ->
+
+    JProvisioner.count { slug }, (err, res) ->
       return callback err  if err?
       if not res? or res > 0
       then callback new KodingError \
@@ -141,9 +141,9 @@
       else callback null

-  checkData = (delegate, data, callback)->
-
-    {type, content, slug, label, accessLevel} = data
+  checkData = (delegate, data, callback) ->
+
+    { type, content, slug, label, accessLevel } = data

     [err, content, contentSum] = checkContent type, content
     if err? then return callback err
@@ -153,7 +153,7 @@
     slug ?= (require 'hat') 32
     slug  = "#{delegate.profile.nickname}/#{slug}"

-    checkSlug slug, (err)->
+    checkSlug slug, (err) ->
       return callback err  if err?
       callback null, {
         type, slug, label, content, contentSum
@@ -163,24 +163,24 @@

   @create = permit 'create provisioner',

-    success: (client, data, callback)->
-
-      {delegate} = client.connection
-
-      checkData delegate, data, (err, data)->
+    success: (client, data, callback) ->
+
+      { delegate } = client.connection
+
+      checkData delegate, data, (err, data) ->

         if err? then return callback err

         data.group = client.context.group

         provisioner = new JProvisioner data
-        provisioner.save (err)->
+        provisioner.save (err) ->

           return callback err  if err
           callback null, provisioner

-  someHelper = (client, selector, options, callback)->
+  someHelper = (client, selector, options, callback) ->

     [options, callback] = [callback, options]  unless callback
     options ?= {}
@@ -188,7 +188,7 @@
     { delegate } = client.connection

     unless typeof selector is 'object'
-      return callback new KodingError "Invalid query"
+      return callback new KodingError 'Invalid query'

     selector.$and ?= []
     selector.$and.push
@@ -203,20 +203,21 @@
         }
       ]

-    JProvisioner.some selector, options, (err, templates)->
+    JProvisioner.some selector, options, (err, templates) ->
       callback err, templates

-  @some$ = permit 'list provisioners', success: someHelper
+  @some$ = permit 'list provisioners', { success: someHelper }

   @one$  = permit 'list provisioners',

-    success: (client, selector, callback)->
-
-      someHelper client, selector, limit: 1, (err, provisioners)->
+    success: (client, selector, callback) ->
+
+      someHelper client, selector, { limit: 1 }, (err, provisioners) ->
         callback err, (provisioners[0]  if provisioners?)

-
+  # due to a bug in coffeelint 1.10.1
+  # coffeelint: disable=no_implicit_braces
   delete: permit

     advanced: [
@@ -224,7 +225,7 @@
       # { permission: 'delete provisioner' }
     ]

-    success: (client, callback)-> @remove callback
+    success: (client, callback) -> @remove callback

   setAccess: permit
@@ -234,7 +235,7 @@
       # { permission: 'update provisioner' }
     ]

-    success: (client, accessLevel, callback)->
+    success: (client, accessLevel, callback) ->

       @update $set: { accessLevel }, callback

@@ -246,14 +247,14 @@
       # { permission: 'update provisioner' }
     ]

-    success: (client, data, callback)->
-
-      {content, slug, label, type} = data
+    success: (client, data, callback) ->
+
+      { content, slug, label, type } = data

       unless content or label or slug
-        return callback new KodingError "Nothing to update"
-
-      fieldsToUpdate = { "meta.modifiedAt" : new Date }
+        return callback new KodingError 'Nothing to update'
+
+      fieldsToUpdate = { 'meta.modifiedAt' : new Date }

       if content?

@@ -268,7 +269,7 @@
         slug  = "#{delegate.profile.nickname}/#{slug}"
         fieldsToUpdate.slug = slug

-      @update $set : fieldsToUpdate, (err)->
+      @update $set : fieldsToUpdate, (err) ->

         if slug and err and err.name is 'MongoError' and err.code is 11001
           return callback new KodingError \
@@ -277,3 +278,5 @@
         return callback err  if err?

         callback null
+
+


Unhide add professional button when new partner is created

--- app/views/admin/invitations/create_partner.js.coffee
+++ app/views/admin/invitations/create_partner.js.coffee
@@ -2,6 +2,7 @@
 $("#user_partner_id options:selected").removeAttr("selected")
 $("#user_partner_id").append("<option selected='selected' value='<%= @partner.id %>'><%= @partner.name %></option>")

+#TODO: Make a better sort, this has some bugs.
 #Sort the select field
 $("#user_partner_id").html($("#user_partner_id option").sort( (a, b)->
   a.text == b.text ? 0 : a.text < b.text ? -1 : 1
@@ -11,5 +12,6 @@
 #Remove the New partner form
 $("#new_partner_form").fadeOut(()->
   $("#new_partner_form").children().remove()
+  $("#add_professional_button").show()
   $("#invitation_form").fadeIn()
   )


Fix bugs

Fix bugs

--- views/services/layout.cjsx
+++ views/services/layout.cjsx
@@ -217,8 +217,11 @@
 window.addEventListener 'game.payitem', adjustPayitem
 window.addEventListener 'game.response', (e) ->
   if e?.detail?.path == '/kcsapi/api_start2' && config.get poi.stopLoadingOnGameLoaded, false
+    stopOnLoad = true
+  if e?.detail?.path == '/kcsapi/api_port/port' && stopOnLoad
     try
-      $('webview').stop()
+      $('kan-game webview').stop()
+      stopOnLoad = false

 document.addEventListener 'DOMContentLoaded', ->
   $('kan-game webview').src = config.get 'poi.homepage', 'http://www.dmm.com/netgame/social/application/-/detail/=/app_id=854854/'


Fixed error reporting: #1.

Fixed error reporting: #1.

--- APIBlueprintImporter.coffee
+++ APIBlueprintImporter.coffee
@@ -181,10 +181,7 @@
       @importBlueprint context, blueprint
       return true

-    # TODO Handle failed request
-    console.log("HTTP Request failed: " + http_request.responseStatusCode)
-
-    return false
+    throw new Error "HTTP Request failed: " + http_request.responseStatusCode

   return


github-commit-link: Add support for repo@<SHA> and user/repo@<SHA>

Based on similar parsing in github-issue-link.coffee.  The main change
in the logic is that the initial .* is now the non-greedy .*?, so it
doesn't gobble up the repo-part of the regexp [1].  The user/repo
portion is [^\s@]+, which matches one or more characters that are
neither whitespace [2] nor @.

The non-capturing (?:...) block [3] around the optional repo@ or
user/repo@ qualifier allows us to group the qualifier with its @, even
though we only need the repo or user/repo (without the @) in our
internal logic.

I use CoffeeScript's block regular expressions to comment the regexp
[4], and CoffeeScript's existential operator '?' to check if
'msg.match[1]' is defined [5].

I also document the fact that lines matching 'commit/' are ignored.

[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-questionmark
[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-white-space
[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-non-capturing-parentheses
[4]: http://coffeescript.org/#regexes
[5]: http://coffeescript.org/#operators

--- src/scripts/github-commit-link.coffee
+++ src/scripts/github-commit-link.coffee
@@ -8,6 +8,8 @@
 # Configuration:
 #   HUBOT_GITHUB_REPO
 #     The `user/repository` that you want to connect to. example: github/hubot-scripts
+#   HUBOT_GITHUB_USER
+#     The `user` that you want to connect to. example: github
 #   HUBOT_GITHUB_TOKEN
 #     You can retrieve your github token via:
 #       curl -i https://api.github.com/authorizations -d '{"scopes":["repo"]}' -u "yourusername"
@@ -21,18 +23,33 @@
 #     http[s]://yourdomain.com/api/v3/ for Enterprise installations.
 #
 # Commands:
-#   Listens for <SHA> and links to the commit for your default repo on github
+#   Listens for <SHA>s with at least seven characters:
+#     <SHA>            links to that commit in HUBOT_GITHUB_REPO
+#     repo@<SHA>       links to that commit in HUBOT_GITHUB_USER's repo
+#     user/repo@<SHA>  links to that commit in user/repo
+#   Unless the string 'commit/' shows up in the line, in which case it
+#   is ignored.
 #
 # Author:
 #   achiu

 module.exports = (robot) ->
   github = require("githubot")(robot)
-  robot.hear /.*(\b[0-9a-f]{7,40}\b).*/i, (msg) ->
+  robot.hear ///
+      ^.*?              # non-greedy pre-commit-reference text
+      \b                # word boundary before the commit reference
+      (?:([^\s@]+)@)?   # optional repo@ or user/repo@ qualifier
+      ([0-9a-f]{7,40})  # commit hash (>= 7 and <= 40 hex digits long)
+      \b                # word boundary after the commit reference
+      .*$               # post-commit-reference text
+      ///i, (msg) ->
     if process.env.HUBOT_GITHUB_REPO && process.env.HUBOT_GITHUB_TOKEN
       if !(msg.message.text.match(/commit\//))
-        commit_sha = msg.match[1].replace /\b/, ""
-        bot_github_repo = github.qualified_repo process.env.HUBOT_GITHUB_REPO
+        commit_sha = msg.match[2]
+        if msg.match[1]?
+          bot_github_repo = github.qualified_repo msg.match[1]
+        else
+          bot_github_repo = github.qualified_repo process.env.HUBOT_GITHUB_REPO
         issue_title = ""
         base_url = process.env.HUBOT_GITHUB_API || 'https://api.github.com'
         github.get "#{base_url}/repos/#{bot_github_repo}/commits/" + commit_sha, (commit_obj) ->


FrameChunker: Fix time loss issue

FrameChunker: Fix time loss issue

Converting to date loses precision on non-integer numbers, so we've been
losing clock sync by approximately seven seconds per hour. Keep track of the
extra time and re-add it in integer amounts.

--- src/streammachine/sources/base.coffee
+++ src/streammachine/sources/base.coffee
@@ -135,6 +135,7 @@
         constructor: (@duration,@initialTime = new Date()) ->
             @_chunk_queue       = []
             @_queue_duration    = 0
+            @_remainders        = 0

             @_last_ts           = null

@@ -144,6 +145,7 @@

         resetTime: (ts) ->
             @_last_ts       = null
+            @_remainders    = 0
             @initialTime    = ts

         #----------
@@ -172,9 +174,17 @@
                 # what's the timestamp for this chunk? If it seems reasonable
                 # to attach it to the last chunk, let's do so.

+                simple_dur = Math.floor(duration)
+                @_remainders += duration - simple_dur
+
+                if @_remainders > 1
+                    simple_rem = Math.floor(@_remainders)
+                    @_remainders = @_remainders - simple_rem
+                    simple_dur += simple_rem
+
                 ts =
                     if @_last_ts
-                        new Date( Number(@_last_ts) + duration )
+                        new Date( Number(@_last_ts) + simple_dur )
                     else
                         @initialTime


Created utils test

Created utils test

--- test/app/lib/utils.spec.coffee
+++ test/app/lib/utils.spec.coffee
@@ -0,0 +1,43 @@
+describe 'utils library', ->
+  require 'lib/utils'
+
+  beforeEach ->
+    fixture1 = {
+      "text": "G'day, Wizard! Come to practice? Well, let's get started...",
+      "i18n": {
+        "es-419": {
+          "text": "¡Buenas, Hechicero! ¿Vienes a practicar? Bueno, empecemos..."
+        },
+        "es-ES": {
+          "text": "¡Buenas Mago! ¿Vienes a practicar? Bien, empecemos..."
+        },
+        "es": {
+          "text": "¡Buenas Mago! ¿Vienes a practicar? Muy bien, empecemos..."
+        },
+        "fr": {
+          "text": "S'lut, Magicien! Venu pratiquer? Ok, bien débutons..."
+        },
+        "pt-BR": {
+          "text": "Bom dia, feiticeiro! Veio praticar? Então vamos começar..."
+        },
+        "de": {
+          "text": "'N Tach auch, Zauberer! Kommst Du zum Üben? Dann lass uns anfangen..."
+        },
+        "tr": {
+          "text": "İyi günler, Büyücü! Antremana mı geldin? Güzel, hadi başlayalım..."
+        },
+        "sv": {
+          "text": "Godagens, trollkarl! Kommit för att öva? Nå, låt oss börja..."
+        },
+        "en": {
+          "text": "Ohai Magician!"
+        }
+      },
+      "sound": {
+        "mp3": "db/level/52740644904ac0411700067c/gday_wizard_come_to_practice.mp3",
+        "ogg": "db/level/52740644904ac0411700067c/gday_wizard_come_to_practice.ogg"
+      }
+    }
+
+  it 'i18n should find a valid target string', ->
+    expect(i18n(fixture1, 'text', 'en')).toEqual(fixture1.i18n.en.text)


update tests

update tests

--- test/applications_tests.coffee
+++ test/applications_tests.coffee
@@ -30,7 +30,7 @@
     @proxy.listen 9104

     @fakeApp = helpers.fakeServer this_should_be_an: 'icon', 200
-    @fakeApp.listen 8001
+    @fakeApp.listen 8003

 stopTestServers = ->
     @haibu.close()
@@ -135,13 +135,26 @@

         describe "UPDATE /api/applications/:slug/update Update an app", ->

-            it "When I send a request to update an application", (done) ->
+            it "When I send a request to update this application", (done) ->
                 @client.put "api/applications/my-app/update", {}, done

             it "Then it sends me a success response", ->
                 console.log @body
                 #@response.statusCode.should.equal 200
-                #expect(@body.success).to.be.ok
+                #expect(@body.success).to.be.ok
+
+    describe "Application update all", ->
+
+        before resetTestServers
+
+        describe "UPDATE /api/applications/update/all Update all app", ->
+
+            it "When I send a request to update an application", (done) ->
+                @client.put "api/applications/update/all", {}, done
+
+            it "Then it sends me a success response", ->
+                @response.statusCode.should.equal 200
+                expect(@body.success).to.be.ok

     describe "Application stop", ->


contextFactorySpec.coffee updated

contextFactorySpec.coffee updated

--- test/contextFactorySpec.coffee
+++ test/contextFactorySpec.coffee
@@ -1,5 +1,8 @@
 define ['contextFactory'], (ContextFactory) ->
   describe 'ContextFactory', ->
+    subject      =
+    JasmineStore = undefined
+
     it 'should be defined', ->
       expect(ContextFactory).toBeDefined()

@@ -7,8 +10,6 @@
       expect(ContextFactory).toBeAFunction()

     describe 'returnable DSL object', ->
-      subject      =
-      JasmineStore = undefined

       beforeEach ->
         Jasmine      = jasmine.createSpyObj('JasmineMock', ['beforeEach', 'afterEach'])
@@ -35,9 +36,9 @@
           name    = 'collection'
           store   = {}
           factory = new ContextFactory(name, store, JasmineStore)
-          beforeEachArgs = /return eval\("var " \+ prop \+ " = " \+ Store\[prop\] \+ ";"\);/
+          beforeEachArgs = /return eval\.call\(this, "var " \+ prop \+ " = '" \+ Store\[prop\] \+ "';"\);/
           afterEachArgs1 = /delete Store\[prop\];/
-          afterEachArgs2 = /return eval\("delete " \+ prop \+ ";"\);/
+          afterEachArgs2 = /return eval\.call\(this, "delete " \+ prop \+ ";"\);/

         describe 'first - plain val', ->


bye istvan

bye istvan

--- scripts/name-expander.coffee
+++ scripts/name-expander.coffee
@@ -18,7 +18,6 @@
   "Jesse Howarth",
   "Josiah Kiehl",
   "Jamie Winsor",
-  "Istvan",
   "Chong Yan",
 ]


Test rxt basics

Test rxt basics

--- test/spec/test_reactive.coffee
+++ test/spec/test_reactive.coffee
@@ -1,3 +1,4 @@
+bind = rx.bind
 describe 'source cell', ->
   src = null
   beforeEach -> src = rx.cell()
@@ -22,3 +23,41 @@
     expect(src.get()).toBe(1)
   it 'cannot be set', ->
     expect(-> dep.set(0)).toThrow()
+
+describe 'tag', ->
+  size = elt = null
+  beforeEach ->
+    size = rx.cell(10)
+    elt = rxt.tags.header {
+      class: 'my-class'
+      style: bind -> "font-size: #{size.get()}px"
+      id: 'my-elt'
+      click: ->
+      init: -> @attr('data-foo', 'bar')
+    }, bind -> [
+      'hello world'
+      rxt.tags.button ['click me']
+    ]
+  it 'should have the right tag', ->
+    expect(elt.is('header')).toBe(true)
+  it 'should have the set attributes', ->
+    expect(elt.attr('class')).toBe('my-class')
+    expect(elt.attr('style')).toBe('font-size: 10px')
+    expect(elt.attr('id')).toBe('my-elt')
+    expect(elt.attr('data-foo')).toBe('bar')
+    expect(elt.hasClass('my-class')).toBe(true)
+    expect(elt.css('font-size')).toBe('10px')
+    expect(elt.data('foo')).toBe('bar')
+  it 'should update attrs in response to size changes', ->
+    size.set(9)
+    expect(elt.attr('style')).toBe('font-size: 9px')
+    expect(elt.css('font-size')).toBe('9px')
+  it 'should have the given child contents', ->
+    cont = elt.contents()
+    expect(cont.length).toBe(2)
+    expect(cont.first().text()).toBe('hello world')
+    expect(cont.last().is('button')).toBe(true)
+    expect(cont.last().text()).toBe('click me')
+  it 'should not have special attrs set', ->
+    expect(elt.attr('init')).toBe(undefined)
+    expect(elt.attr('click')).toBe(undefined)


Add more tests for async binds

Add more tests for async binds

Refs #50

--- test/spec/test_reactive.coffee
+++ test/spec/test_reactive.coffee
@@ -411,6 +411,30 @@
       x.set(1)
       expect(y.get()).toBe('none')
     waitsFor (-> y.get() == 1), 'The async should have fired', 1
+  it 'should work asynchronously with recording at the end', ->
+    x = rx.cell(0)
+    y = rx.asyncBind 'none', ->
+      _.defer => @done(@record => x.get())
+    runs ->
+      expect(y.get()).toBe('none')
+      x.set(1)
+      expect(y.get()).toBe('none')
+    waitsFor (-> y.get() == 1), 'The async should have fired', 1
+  it 'should work asynchronously with recording at the beginning', ->
+    x = rx.cell(0)
+    y = rx.asyncBind 'none', ->
+      xx = @record => x.get()
+      _.defer => @done(xx)
+    runs ->
+      expect(y.get()).toBe('none')
+      x.set(1)
+      expect(y.get()).toBe('none')
+    waitsFor (-> y.get() == 1), 'The async should have fired', 1
+  it 'should enforce one-time record', ->
+    x = rx.cell(0)
+    y = rx.asyncBind 'none', ->
+      xx = @record => x.get()
+      _.defer => expect(=> @done(@record => x.get())).toThrow()
   it 'should not be a SrcCell', ->
     x = rx.cell(0)
     y = rx.asyncBind 'none', -> @done(x.get())


wording issues

wording issues

--- test/state_machine_spec.coffee
+++ test/state_machine_spec.coffee
@@ -90,7 +90,7 @@
         transition_func.type.should.be.equal 'coffee_state_machine.TransitionHelperFunction'

-    it "should auto create state definition for initial state from options", ->
+    it "should implicit register state from option 'initial'", ->

         sm = state_machine "state", initial: "idle", ->

@@ -99,7 +99,7 @@
         sm.is_valid_state("plah").should.be.not.ok

-    it "should auto create state definition for initial state set with state.initial()", ->
+    it "should implicit register state for initial state defined by state.initial()", ->

         sm = state_machine "state", (state) -> state.initial "plah"

@@ -141,7 +141,7 @@
         sm.is_valid_state("foobar").should.be.not.ok

-    it "should register parent state if called with option 'parent'", ->
+    it "should implicit register parent state if called with option 'parent'", ->

         sm = state_machine "state", initial: 'idle', (state) ->


Remove duplicate code from timers

Remove duplicate code from timers

--- homedisplay/info_timers/static/js/timer.coffee
+++ homedisplay/info_timers/static/js/timer.coffee
@@ -128,7 +128,7 @@
       deleteItem "ui"
       return

-    timer_elem.stop(true)
+    timer_elem.stop true
     .css "background-color", timer_elem.data("original-bg-color")
     .effect "highlight",
       color: "#cc0000"
@@ -150,19 +150,26 @@
       diff = (new Date(options.stopped_at) - start_time) / 1000
       updateTimerContent diff, ""

+  receivedData = (message) ->
+    data = message[0]
+    start_time = new Date data.fields.start_time
+    options.duration = data.fields.duration
+    # TODO: update start_time and end_time data fields
+
+    if data.fields.running
+      if !running
+        startItem "backend"
+    else
+      if running
+        stopItem "backend"
+
   refreshFromBackend = ->
     if id? # Don't refresh if no data is available.
       jq.ajax
         url: "/homecontroller/timer/get/#{id}"
         success: (data) ->
-          start_time = new Date data[0].fields.start_time
-          options.duration = data[0].fields.duration
-          if data[0].fields.running
-            if !running
-              startItem "backend"
-          else
-            if running
-              stopItem "backend"
+          receivedData(data)
+
         statusCode:
           404: ->
             deleteItem "backend"
@@ -174,28 +181,7 @@
       deleteItem source
       return

-    data = message[0]
-    start_time = new Date data.fields.start_time
-    options.duration = data[0].fields.duration
-    if data.fields.running
-      # Timer should be running.
-      startItem source
-      return
-
-    # Timer is stopped
-    timer_elem.stop(true).css "background-color", timer_elem.data("original-bg-color")
-    .effect "highlight",
-      color: "#cc0000"
-    , 500
-
-    running = false
-    clearItemIntervals()
-    timer_elem.find ".stopclock-stop i"
-    .removeClass "fa-stop"
-    .addClass "fa-trash"
-    if data.fields.stopped_at
-      diff = (new Date(data.fields.stopped_at) - start_time) / 1000
-      updateTimerContent diff, ""
+    receivedData message

   setId = (new_id) ->
     # Set backend id to local object.


Turn off twitch-irc debugging so the console is prettier

--- options/twitch.cson
+++ options/twitch.cson
@@ -1,5 +1,5 @@
 options:
-    debug: true
+    debug: false
     debugIgnore: ['ping', 'chat', 'join', 'part']
     tc: 1
 identity:


BOB HATES TREES.

BOB HATES TREES.

--- mixirc/mixirc.coffee
+++ mixirc/mixirc.coffee
@@ -223,7 +223,7 @@
 db = new firebase(auth.domain)
 db.auth auth.token, (error) ->
 	if error
-		console.log "[FAIL] Firebase Authication: ", error
+		console.log "[FAIL] Firebase Authentication: ", error
 	else
 		console.log "[PASS] Firebase Authenticated"
 dataRef = new firebase(auth.domain)


mock workers: make received[method] always exist

--- mocks/workers.coffee
+++ mocks/workers.coffee
@@ -15,9 +15,9 @@
     super
     @received = {}
     _(METHODS).each (method) =>
+      @received[method] = []
       @[method] = (args...) =>
         @emit.apply @, [method].concat args
-        @received[method] ?= []
         @received[method].push args
     @handle = "some_thing:#{Math.floor (Math.random() * 99999) + 1}"
 # A mock worker that expects to only have the 'done' method called


Update hover_group.coffee to use Slick 1.4

--- app/assets/javascripts/martian_components/components/hover_group.coffee
+++ app/assets/javascripts/martian_components/components/hover_group.coffee
@@ -46,7 +46,7 @@

   onResponsiveSizeChange: ->
     @items.map 'checkPlugins'
-    @slider.slickGoTo(0)
+    @slider.slick('slickGoTo', 0)

   onResize: ->
     super


Forgot to increase the tweet display time from debugging

--- app/assets/javascripts/network_executive/components/tweet_player.coffee
+++ app/assets/javascripts/network_executive/components/tweet_player.coffee
@@ -7,7 +7,7 @@
     @avatarEl     = document.getElementById( 'avatar' )
     @backgroundEl = document.getElementById( 'background' )
     @tweets       = tweets
-    @displayTime  = 2000
+    @displayTime  = 10000
     @cursor       = 0

     setInterval @render, @displayTime


Fixing pills when drag and drop

Fixing pills when drag and drop

--- app/modules/components/belong-to-epics/belong-to-epics.directive.coffee
+++ app/modules/components/belong-to-epics/belong-to-epics.directive.coffee
@@ -22,8 +22,9 @@
 BelongToEpicsDirective = () ->

     link = (scope, el, attrs) ->
-        if scope.epics && !scope.epics.isIterable
-          scope.epics = Immutable.fromJS(scope.epics)
+        scope.$watch 'epics', (epics) ->
+            if epics && !epics.isIterable
+              scope.epics = Immutable.fromJS(epics)

     templateUrl = (el, attrs) ->
         if attrs.format


disabled sandbox on all iframes.

disabled sandbox on all iframes.


disallow + in voter email address

disallow + in voter email address

--- models/models.coffee
+++ models/models.coffee
@@ -317,6 +317,7 @@
     if !@person?
       Person.firstOrNew { email: @email }, (error, voter) =>
         return fn ['Unauthorized'] unless voter.isNew()
+        return fn ['"+" not allowed in voter email address'] if @email.split('@')[0].match /\+/
         @person = voter
         @person.type = 'Voter'
         @person.save (error, person) =>


Put back following button for topic and the private feed

--- client/landing/app/Applications/Topics.kdapplication/ContentDisplays/Topic.coffee
+++ client/landing/app/Applications/Topics.kdapplication/ContentDisplays/Topic.coffee
@@ -104,6 +104,15 @@
     , data

     super
+    unless data.followee
+      KD.whoami().isFollowing? data.getId(), "JTag", (following) =>
+        data.followee = following
+        if data.followee
+          @followButton.setClass 'following-btn following-topic'
+          @followButton.setState "Following"
+        else
+          @followButton.setState "Follow"
+          @followButton.unsetClass 'following-btn following-topic'

   viewAppended:->
     @setTemplate @pistachio()


Adds events to watched.itemview

Adds events to watched.itemview

--- app/assets/javascripts/backbone/apps/watched/list/list_view.js.coffee
+++ app/assets/javascripts/backbone/apps/watched/list/list_view.js.coffee
@@ -3,6 +3,19 @@
   class List.WatchedMovieView extends Marionette.ItemView
     template: 'watched/list/templates/_watchedmovie'
     tagName: 'tr'
+    events:
+      'click .remove-btn'  : 'unwatch'
+      'mouseenter'         : 'showOverlay'
+      'mouseleave'         : 'hideOverlay'
+
+    unwatch: ->
+      this.model.set(watched: false).save()
+
+    showOverlay: ->
+      this.$el.find('.overlay').fadeIn(500)
+
+    hideOverlay: ->
+      this.$el.find('.overlay').fadeOut(500)


tool not @tool

tool not @tool

--- server/code/model/box.coffee
+++ server/code/model/box.coffee
@@ -62,7 +62,7 @@
             boxName: @name
             boxServer: @server
             #TODO(ehg): don't create http dir in cobalt
-            cmd: "rm -fr http ; mkdir incoming ; ln -s /tools/#{@tool.name} tool ; ln -s tool/http http"
+            cmd: "rm -fr http ; mkdir incoming ; ln -s /tools/#{tool.name} tool ; ln -s tool/http http"
           , (err, res, body) ->
             if err?
               callback err


don't use projectname any longer to create application definition namespaces.

--- server/scripts/common.coffee
+++ server/scripts/common.coffee
@@ -35,7 +35,6 @@

 findAppDef = (name, version) ->
   ApplicationDefs.findOne
-    project: Settings.findOne().project
     name: name
     version: version
 renderForNameAndVersion = (template) -> (name, version, instance, options, params) ->


Extract build_expects_method.is_reserved_method_name()

--- src/TinyMock.coffee
+++ src/TinyMock.coffee
@@ -107,7 +107,10 @@
     fail(messages.ExpectsUsage) unless arg_count == 1
     fail(messages.NotAnExistingMethod, method_name) unless is_mock_object(self) or has_method(self, method_name)
     fail(messages.PreExistingProperty, method_name) if has_property(self, method_name)
-    fail(messages.ReservedMethodName, method_name) if method_name == expects_method_name        # TODO: extract is_reserved_method_name()
+    fail(messages.ReservedMethodName, method_name) if is_reserved_method_name(method_name)
+
+  is_reserved_method_name = (method_name) ->
+    method_name == expects_method_name

   expects_method


Added a filter for the EqBeats archive.

Added a filter for the EqBeats archive.

--- resources/assets/scripts/app/services/tracks.coffee
+++ resources/assets/scripts/app/services/tracks.coffee
@@ -1,5 +1,5 @@
 # Pony.fm - A community for pony fan music.
-# Copyright (C) 2015 Peter Deltchev
+# Copyright (C) 2015-2017 Peter Deltchev
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -244,6 +244,7 @@
                     name: 'archive'
                     values: [
                         {title: 'None', query: '', isDefault: true, filter: ''}
+                        {title: 'Equestrian Beats', query: 'eqbeats', isDefault: false, filter: 'archive=eqbeats'}
                         {title: 'MLP Music Archive', query: 'mlpma', isDefault: false, filter: 'archive=mlpma'}
                         {title: 'Ponify', query: 'ponify', isDefault: false, filter: 'archive=ponify'}
                     ]


allow override of options.display for facebook auth

--- src/api/auth.coffee
+++ src/api/auth.coffee
@@ -111,7 +111,7 @@
       authenticating.providerName = providerName

-      if providerName == 'facebook'
+      if providerName == 'facebook' && !options.display?
         options.display = if options.strategy=='redirect' then 'page' else 'popup'

       authUrl = module.authUrl(config, providerName, options)


Kill console.log

Kill console.log

--- src/app/atom.coffee
+++ src/app/atom.coffee
@@ -22,8 +22,6 @@

   loadPackages: (packageNames=@getAvailablePackages()) ->
     disabledPackages = config.get("core.disabledPackages") ? []
-
-    console.log packageNames
     for packageName in packageNames
       @loadPackage(packageName) unless _.contains(disabledPackages, packageName)


config: add gatekeeper worker config

config: add gatekeeper worker config

--- config/main.dev.coffee
+++ config/main.dev.coffee
@@ -341,14 +341,17 @@
       nginx             :
         locations       : [ "= /payments/stripe/webhook" ]

-    # gatekeeper          :
-    #   group             : "socialapi"
-    #   ports             :
-    #     incoming        : "#{gatekeeper.port}"
-    #   supervisord       :
-    #     command         : "cd #{projectRoot}/go/src/socialapi && make gatekeeperdev config=#{socialapi.configFilePath} && cd #{projectRoot}"
-    #   healthCheckURL    : "http://localhost:#{gatekeeper.port}/healthCheck"
-    #   versionURL        : "http://localhost:#{gatekeeper.port}/version"
+    gatekeeper          :
+      group             : "socialapi"
+      ports             :
+        incoming        : "#{gatekeeper.port}"
+      supervisord       :
+        command         : "cd #{projectRoot}/go/src/socialapi && make gatekeeperdev config=#{socialapi.configFilePath} && cd #{projectRoot}"
+      healthCheckURL    : "http://localhost:#{gatekeeper.port}/healthCheck"
+      versionURL        : "http://localhost:#{gatekeeper.port}/version"
+      nginx             :
+        locations         : [ "~ /api/gatekeeper/(.*)" ]
+        proxyPass         : "http://gatekeeper/$1"

     dispatcher          :
       group             : "socialapi"


namespaced unbind

namespaced unbind

--- src/bindable.coffee
+++ src/bindable.coffee
@@ -45,7 +45,7 @@
   ###
   bind: (events, callback) ->
     events.split(" ").each (namespacedEvent) ->
-      event = namespacedEvent.sprit
+      event = namespacedEvent.split()
       eventCallbacks[event] = eventCallbacks[event] || []

       eventCallbacks[event].push(callback)


Don't call Rivets.Binding::setModel more than once. Call ::update() on the observer instead.

--- src/bindings.coffee
+++ src/bindings.coffee
@@ -125,7 +125,7 @@
   # Updates the binding's model from what is currently set on the view. Unbinds
   # the old model first and then re-binds with the new model.
   update: (models = {}) =>
-    @setModel() if models[@rootKey.path]
+    @observer.update() if models[@rootKey.path]
     @binder.update?.call @, models

 # Rivets.ComponentBinding


Whitespace fix

Whitespace fix

--- scripts/linkticket.coffee
+++ scripts/linkticket.coffee
@@ -7,7 +7,7 @@
   rootCas = require('ssl-root-cas/latest').create()
   require('https').globalAgent.options.ca = rootCas
   ticketId = null
-  robot.hear /(DM|RFC)-\d+/gi, (msg) ->
+  robot.hear /(^|\s+)(DM|RFC)-\d+/gi, (msg) ->
     # Link to the associated tickets
     issueResponses(robot, msg)


don't preview answer choice on new

don't preview answer choice on new

--- app/assets/javascripts/hanuman/components/answer-choice-row.js.coffee
+++ app/assets/javascripts/hanuman/components/answer-choice-row.js.coffee
@@ -7,7 +7,7 @@
   question: null

   setNewModel: ->
-    model = @get('question').get('answerChoices').content.createRecord(
+    model = @get('question').store.createRecord('answerChoice',
       optionText: ''
     )
     @set('model', model)
@@ -21,37 +21,11 @@

   actions:
     save: ->
+      @get('model').set('question', @get('question'))
       @sendAction('save', @get('model'))
       if @get('model.isNew')
         @set('model',null)
       @send('toggleForm')
-
-
-      # trying to handle situation where user save answerchoice before saving question
-      # answerChoice = @get('model')
-      # question = answerChoice.get('question')
-      # controller = @
-      # if question.get('isNew')
-      #   question.save().then (question) ->
-      #     console.log "saved"
-      #     answerChoice.set "question_id", question.get('id')
-      #     answerChoice.save().then(
-      #       =>
-      #         controller.set('model', null)
-      #         controller.send('toggleForm')
-      #       ,->
-      #         console.log('failed')
-      #     )
-      #   , (response) ->
-      #     console.log "failed"
-      # else
-      #   answerChoice.save().then(
-      #     =>
-      #       @set('model', null)
-      #       @send('toggleForm')
-      #     ,->
-      #       console.log('failed')
-      #   )

     toggleForm: ->
       this.toggleProperty('isEditingAnswerChoice')


Much better and cleaner

Much better and cleaner

--- client/app/MainApp/kodingappscontroller.coffee
+++ client/app/MainApp/kodingappscontroller.coffee
@@ -68,22 +68,20 @@
         stack = []

         files.forEach (file)->
-          if /\.kdapp$/.test file.name
+          if /\.kdapp$/.test(file.name) and file.type is 'folder'
             apps.push file

         apps.forEach (app)=>
           stack.push (cb)=>
-            manifestFile = if app.type is "folder" then \
-              FSHelper.createFileFromPath "#{app.path}/.manifest" else app
-            manifestFile.fetchContents (err, response)->
+            manifest = FSHelper.createFileFromPath "#{app.path}/.manifest"
+            manifest.fetchContents (err, response)->
               # shadowing the error is intentional here
-              # to not to break the results of the stack
+              # to not to break the result of the stack
               cb null, response

-        manifests = @constructor.manifests
-        async.parallel stack, (err, results)=>
-          warn err if err
-          results.forEach (rawManifest)->
+        {manifests} = @constructor
+        async.parallel stack, (err, result)=>
+          result.forEach (rawManifest)->
             if rawManifest
               try
                 manifest = JSON.parse rawManifest


[client][app][Main][tab] updated routes as removed leading slashes

--- client/app/MainApp/maintabs/maintabview.coffee
+++ client/app/MainApp/maintabs/maintabview.coffee
@@ -48,13 +48,13 @@
     appView     = pane.getMainView()
     appInstance = appManager.getByView appView
     options     = appInstance.getOptions()
-    @getSingleton('router').handleRoute "/#{options.route}"
+    @getSingleton('router').handleRoute "#{options.route}"

     if $(event.target).hasClass "close-tab"
       pane.mainView.destroy()
       return no

-    @showPane pane  if options.route is 'Develop'
+    @showPane pane  if options.route is '/Develop'

   showHandleContainer:()->
     @tabHandleContainer.$().css top : -25


Flux: Environment: Add new properties to machine items while mapping

--- client/app/lib/flux/environment/getters.coffee
+++ client/app/lib/flux/environment/getters.coffee
@@ -1,3 +1,6 @@
+machineRuleChecker = require 'app/util/machinerulechecker'
+getMachineOwner    = require 'app/util/getmachineowner'
+
 StacksStore                = ['StacksStore']
 MachinesStore              = ['MachinesStore']
 WorkspacesStore            = ['WorkspacesStore']
@@ -11,27 +14,46 @@
   WorkspacesStore
   MachinesWorkspacesStore
   (machines, workspaces, machinesWorkspaces) ->
+
     machines.map (machine) ->
-      machine.set 'workspaces', machinesWorkspaces.get(machine.get '_id').map (workspaceId) ->
-        workspaces.get workspaceId
+      machine
+        .set 'workspaces', machinesWorkspaces.get(machine.get '_id')?.map (workspaceId) ->
+          workspaces.get workspaceId
 ]

 ownMachines = [
   OwnMachinesStore
   machinesWithWorkspaces
-  (own, machines) -> own.map (id) -> machines.get id
+  (own, machines) -> own.map (id) ->
+    machines.get(id)
+      .set 'type', 'own'
+      .set 'isApproved', yes
+      .set 'isManaged', machineRuleChecker machine, ['managed']
 ]

 sharedMachines = [
   SharedMachinesStore
   machinesWithWorkspaces
-  (shared, machines) -> shared.map (id) -> machines.get id
+  (shared, machines) -> shared.map (id) ->
+    machine = machines.get(id)
+    machine
+      .set 'type', 'shared'
+      .set 'owner', getMachineOwner machine
+      .set 'isApproved', machineRuleChecker machine, ['approved']
+      .set 'isPermanent', machineRuleChecker machine, ['permanent']
 ]

 collaborationMachines = [
   CollaborationMachinesStore
   machinesWithWorkspaces
-  (collaboration, machines) -> collaboration.map (id) -> machines.get id
+  (collaboration, machines) ->
+    collaboration.map (id) ->
+      machine = machines.get(id)
+      machine
+        .set 'type', 'collaboration'
+        .set 'owner', getMachineOwner machine
+        .set 'isApproved', machineRuleChecker machine, ['approved']
+        .set 'isPermanent', machineRuleChecker machine, ['permanent']
 ]

 stacks = [
@@ -42,7 +64,11 @@
       .sortBy (stack) -> stack.get '_id'
       .map (stack) ->
         stack.update 'machines', (machines) ->
-          machines.map (id) -> machinesWorkspaces.get id
+          machines.map (id) ->
+            machine = machinesWorkspaces.get(id)
+            machine
+              .set 'type', 'own'
+              .set 'isApproved', yes
 ]

 module.exports = {


shortcuts/facade: do not emit DUP for hidden bindings

--- client/app/lib/shortcuts/actions-facade.coffee
+++ client/app/lib/shortcuts/actions-facade.coffee
@@ -37,6 +37,7 @@
   dups = getShortcuts().getCollisionsFlat collection.name

   collection.each (model) ->
+    return  if model.options.hidden is yes
     key = "#{collection.name}$#{model.name}"
     entity = entities[key]
     entity.emit EventType.Facade.DUP, _.includes dups, model.name


Fix projection in project query

Fix projection in project query

--- services/web/app/coffee/Features/Collaborators/CollaboratorsHandler.coffee
+++ services/web/app/coffee/Features/Collaborators/CollaboratorsHandler.coffee
@@ -18,7 +18,13 @@
 module.exports = CollaboratorsHandler =

 	getMemberIdsWithPrivilegeLevels: (project_id, callback = (error, members) ->) ->
-		Project.findOne { _id: project_id }, { owner_ref: 1, collaberator_refs: 1, readOnly_refs: 1 }, (error, project) ->
+		projection =
+			owner_ref: 1,
+			collaberator_refs: 1,
+			readOnly_refs: 1,
+			tokenAccessReadOnly_refs: 1,
+			tokenAccessReadAndWrite_refs: 1
+		Project.findOne { _id: project_id }, projection, (error, project) ->
 			return callback(error) if error?
 			return callback new Errors.NotFoundError("no project found with id #{project_id}") if !project?
 			members = []


Don't use audio mapping with level values (just use raw level value)

--- client/components/audiofader/audiofader.coffee
+++ client/components/audiofader/audiofader.coffee
@@ -7,13 +7,11 @@

   setLevel: (level) ->
     if @sliderRendered and @allowUpdate
-      level = @_mapValue level
       @tmpl.$('input').slider 'setValue', level
     level

   getLevel: ->
-    slider = @tmpl.$('input').slider 'getValue'
-    @_unmapValue slider
+    @tmpl.$('input').slider 'getValue'

   saveLevel: ->
     _id = Template.parentData(1)._id


group : clean trailing spaces

group : clean trailing spaces

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -461,7 +461,7 @@
             else
               console.log 'roles are added'
               queue.next()
-        ->
+        ->
           # CtF hacked because we need client to create a post
           group.createGroupBotAndPostMessage client, (err) ->
             return callback err if err
@@ -605,7 +605,7 @@
           permissionSet.update $set:{permissions}, callback
         else
           permissionSet = new JPermissionSet {permissions, isCustom: true}
-          permissionSet.save (err) =>
+          permissionSet.save (err) =>
             return callback err if err
             @addPermissionSet permissionSet, (err)->
               return callback err if err
@@ -1469,7 +1469,7 @@
     JAccount.one "profile.nickname" : "bot", (err, account) =>
       return callback err if err
       return callback new KodingError "Can't find bot account" if not account
-
+
       @addMember account, "member", (err, member)=>
         return callback err if err
         JNewStatusUpdate = require '../messages/newstatusupdate'
@@ -1480,10 +1480,11 @@
         client.connection.delegate = account
         client.groupName = @slug

-        data =
+        data =
           body  : "Welcome to your group"
-          group : @slug
+          group : @slug
         JNewStatusUpdate.create client, data, callback
+
   getPermissionSet : (callback)->
     @fetchPermissionSet (err, permissionSet) =>
       callback err, null if err