Update dimensions calculations for hidden views.

--- src/component/ComponentView.coffee
+++ src/component/ComponentView.coffee
@@ -5,12 +5,12 @@
 # @module stout-ui/component/ComponentView
 ###

-nextTick           = require 'stout-client/util/nextTick'
-Promise            = require 'stout-core/promise/Promise'
-TransitionCanceled = require('stout-client/exc').TransitionCanceled
-vars               = require '../vars'
-View               = require 'stout-client/view/View'
-ViewNotRenderedErr = require('stout-client/err').ViewNotRenderedErr
+nextTick              = require 'stout-client/util/nextTick'
+Promise               = require 'stout-core/promise/Promise'
+TransitionCanceledExc = require('stout-client/exc').TransitionCanceledExc
+vars                  = require '../vars'
+View                  = require 'stout-client/view/View'
+ViewNotRenderedErr    = require('stout-client/err').ViewNotRenderedErr

 # Load component variables.
 require '../vars/component'
@@ -114,8 +114,8 @@
         clearTimeout @_transitionTimer

         if @_transitionPromise
-          Promise.reject @_transitionPromise, new TransitionCanceled "Transition
-          canceled by another transition event."
+          Promise.reject @_transitionPromise, new TransitionCanceledExc "
+          Transition canceled by another transition event."

         @_transitionPromise = promise

@@ -135,7 +135,7 @@
       else
         msg = "Transition canceled because test function returned false or the
         view is not yet rendered."
-        reason = new TransitionCanceled(msg)
+        reason = new TransitionCanceledExc(msg)
         Promise.reject promise, reason
     promise

@@ -192,8 +192,8 @@
   clearTimeout target._transitionTimer

   if target._transitionPromise
-    Promise.reject target._transitionPromise, new TransitionCanceled "Transition
-    canceled by another transition event."
+    Promise.reject target._transitionPromise, new TransitionCanceledExc "
+    Transition canceled by another transition event."

   target._transitionPromise = promise

@@ -380,7 +380,7 @@
     clearTimeout @_transitionTimer
     @_removeTransitionClasses()
     if @_transitionPromise
-      Promise.reject @_transitionPromise, new TransitionCanceled(reason)
+      Promise.reject @_transitionPromise, new TransitionCanceledExc(reason)
     return

@@ -412,10 +412,12 @@
       # is hidden we can still calculate the size of this object.
       document.body.appendChild @root

+      pv = @visible
+
       # Calculate the dimensions.
       @_show()
       {width, height} = @root.getBoundingClientRect()
-      @_hide()
+      if not pv then @_hide()

       # Restore the original style and DOM position.
       style.position = pos
@@ -424,12 +426,11 @@

       Promise.resolve promise, {width, height}

-    resolvePosition = =>
-      r = @root.getBoundingClientRect()
+    # Get the current bounding rect.
+    r = @root.getBoundingClientRect()
+
+    if r.width > 0 and r.height > 0
       Promise.resolve promise, {width: r.width, height: r.height}
-
-    if @visible
-      resolvePosition()
     else if @rendered
       calcPositionOffScreen()
     else


Fix currentGame

Fix currentGame

--- controllers/game_controller.coffee
+++ controllers/game_controller.coffee
@@ -90,8 +90,9 @@
     currentGame: (callback) ->
         now = new Date
         Game.findOne
-            startTime: $lt: now
-            endTime: $gt: now
+            where:
+                startTime: $lt: now
+                endTime: $gt: now
         .done callback

     getGamePoint: (point, game, callback) ->


Intercom issue (#4886)

Intercom issue (#4886)

* Fix for intercom issue

* Adding trigger

* Removing trigger

--- app/core/Tracker.coffee
+++ app/core/Tracker.coffee
@@ -237,7 +237,7 @@
     return unless me.isTeacher(true)
     loadSegmentIo()
     .then (segmentIo) =>
-      @segmentLoaded = segmentIo.length is not 0
+      @segmentLoaded = segmentIo.length != 0
       @identify()
     #analytics.page()  # It looks like we don't want to call this here because it somehow already gets called once in addition to this.
     # TODO: record any events and pageviews that have built up before we knew we were a teacher.
@@ -246,7 +246,7 @@
     return if @shouldBlockAllTracking()
     loadSegmentIo()
     .then (segmentIo) =>
-      @segmentLoaded = segmentIo.length is not 0
+      @segmentLoaded = segmentIo.length != 0
       @identify(attrs)

   shouldBlockAllTracking: ->


Making the payload optional for the message

--- client/components/player.cjsx
+++ client/components/player.cjsx
@@ -1,6 +1,7 @@
 _ = require 'lodash'
 React = require 'react'
 Howl = require('howler').Howl
+meshbluConfig = require ''
 Meshblu = require 'meshblu'
 MessageSchema =
   type : 'object'
@@ -31,7 +32,8 @@
   componentDidMount: ->
     @connection.on 'message', (message) =>
       console.log 'message', message
-      @playAudio(message.payload.audioUrl)
+      audioUrl = message.payload.audioUrl || message.audioUrl
+      @playAudio(audioUrl)

   playAudio:  (audioUrl) =>
     console.log 'Play ', audioUrl


improved

improved

--- modules/stores/platforms/node/tools/index.coffee
+++ modules/stores/platforms/node/tools/index.coffee
@@ -1,48 +1,51 @@

 module.exports =
-
-
+
+
     ##
     ##
     ##
     context: (id, type, config)->
-
+        if typeof type is 'object' && !config
+            config = type
+            type = config.type
+
         new floyd.Config
             id: id
-
+
             type: 'stores.Context'
-
-            data:
+
+            data:
                 type: type
                 name: id
-
+
         , config
-
-
-
+
+
+
     ##
     ##
-    ##
+    ##
     read: (key, file='.floyd/default-store.json')->
-
+
         floyd.tools.objects.resolve key, _read(file) || {}
-
-
-
+
+
+
     ##
     ##
     ##
     write: (key, value, file='.floyd/default-store.json')->
         _data = data = _read(file) || {}
-
+
         keys = key.split '.'
         while keys.length > 1 && _data[keys[0]]
             _data = _data[keys.shift()]
-
+
         _data[keys.shift()] = value
-
+
         _write file, data
-
+

 ##
@@ -53,7 +56,7 @@
     if floyd.tools.files.fs.existsSync file

         JSON.parse floyd.tools.files.fs.readFileSync file, 'utf-8'
-
+

 ##
 ##
@@ -61,5 +64,5 @@
 _write = (file, data)->

     json = JSON.stringify data, null, 4
-
+
     floyd.tools.files.fs.writeFileSync file, json, 'utf-8'


Do not search in all frames.

Do not search in all frames.

Chrome has never searched in all frames, so this is no loss.

However, find on Firefox Quantum is now broken with the "all frames"
flag set.

Fixes #2962.

H/t: @gdh1995 (https://github.com/philc/vimium/issues/2962#issuecomment-367991086).

--- content_scripts/mode_find.coffee
+++ content_scripts/mode_find.coffee
@@ -177,7 +177,7 @@
       document.removeEventListener("selectionchange", @restoreDefaultSelectionHighlight, true)

     try
-      result = window.find(query, options.caseSensitive, options.backwards, true, false, true, false)
+      result = window.find(query, options.caseSensitive, options.backwards, true, false, false, false)
     catch # Failed searches throw on Firefox.

     # window.find focuses the |window| that it is called on. This gives us an opportunity to (re-)focus


Refactor value variable

Refactor value variable

--- client/pages/home/home.coffee
+++ client/pages/home/home.coffee
@@ -22,17 +22,16 @@

 validate = (input) ->
     errors = Session.get('errors')
-    value  = input.value

     switch input.type
         when 'email'
-            if validateEmail(value)
+            if validateEmail(input.value)
                 spliceItem(errors, input.name)
             else
                 uppush(errors, input.name)

         when 'password'
-            if validatePassword(value)
+            if validatePassword(input.value)
                 spliceItem(errors, input.name)
             else
                 uppush(errors, input.name)


Lazily create default app.

Lazily create default app.

--- src/die.coffee
+++ src/die.coffee
@@ -15,8 +15,14 @@
     @updateOptions 'default'
     @updateOptions process.env.NODE_ENV or 'development'

-    # Create default app
-    @app = @createServer server.default(@options)
+    # Lazily create default app
+    Object.defineProperty @, 'app',
+      get: =>
+        # Replace accessor with @app
+        delete @app
+        @app = @createServer server.default(@options)
+        enumerable: true
+        configurable: true

   # update options using configuration file or object
   updateOptions: (options) ->
@@ -32,10 +38,10 @@
     require('./build')(@options)

   createServer: (func) ->
-    @app = server.createServer func
+    @_app = server.createServer func

   extend: (func) ->
-    @app = server.extend @app, func
+    server.extend @app, func
     @

   inject: (dieApp) ->


Retira codigo nao utilizado de cache

Retira codigo nao utilizado de cache

--- src/checkout.coffee
+++ src/checkout.coffee
@@ -83,31 +83,19 @@
 			return d.promise()

 		# TODO alterar chamadas para não mandar stringified
-		orderAttachmentRequest = JSON.parse(serializedAttachment)
-		orderAttachmentRequest[expectedOrderFormSections] = expectedOrderFormSections
-
-		if options.cache and options.currentStateHash
-			requestHash = uniqueHashcode(attachmentId + JSON.stringify(orderAttachmentRequest))
-			stateRequestHash = options.currentStateHash + ':' +  requestHash
-
-			if @stateRequestHashToResponseMap[stateRequestHash]
-				deferred = $.Deferred()
-				deferred.resolve(@stateRequestHashToResponseMap[stateRequestHash])
-				return deferred.promise()
+		data = JSON.parse(serializedAttachment)
+		data[expectedOrderFormSections] = expectedOrderFormSections

 		xhr = @ajax
 			url: @_getSaveAttachmentURL(attachmentId)
 			type: 'POST'
 			contentType: 'application/json; charset=utf-8'
 			dataType: 'json'
-			data: JSON.stringify(orderAttachmentRequest)
+			data: JSON.stringify(data)

 		if options.abort and options.subject
 			@subjectToJqXHRMap[options.subject]?.abort()
 			@subjectToJqXHRMap[options.subject] = xhr
-
-		if options.cache and options.currentStateHash
-			xhr.done (data) => @stateRequestHashToResponseMap[stateRequestHash] = data

 		return xhr


Fixed: changing sorting criterion was triggering an error in Firefox

--- client/app/components/menu.coffee
+++ client/app/components/menu.coffee
@@ -120,7 +120,7 @@
             getSubmenu: getSubmenuHandler
             url: url

-    onSelectCriterion: (criterion) ->
+    onSelectCriterion: (criterion, event) ->
         event.preventDefault()
         TagActionCreator.selectSortCriterion criterion


<model> Backbone - Actuator - Adding getURL().

--- client/app/models/actuator.coffee
+++ client/app/models/actuator.coffee
@@ -10,5 +10,9 @@
 	urlRoot: 'actuators'

     defaults: ->
-        customId: 	''
-		name: 		''+        customId: 	'Undefined'
+		name: 		'Undefined'
+		url:		'actuators/'
+
+	getURL: ->
+		return "actuators/#{@id}"


Add budget and change to left menu

Add budget and change to left menu

--- assets/game_state.coffee
+++ assets/game_state.coffee
@@ -22,7 +22,9 @@
     )

   removeCustomer: (customer) ->
-    customers.pop(customer)
+    @customers.filter((item) ->
+      item != customer
+    )

   calculateReputation: ->
     totalWorth = 0
@@ -32,6 +34,14 @@
       totalWorth += customer.worth
     if totalWorth != 0
       @reputation = totalRep / totalWorth
+
+  calculateBudgetChange: ->
+    budget = 0
+    for agent in @agents
+      budget -= agent.salary
+    for customer in @customers
+      budget += customer.worth
+    budget

   constructor: ->
     @level = new Level
@@ -44,6 +54,7 @@

   toString: ->
     "Customers: " + @customers.length +
+    "\nMoney: " + @money + " (" + @calculateBudgetChange() + ")" +
     "\nRequest queue: " + @numberOfRequests() +
     "\nReputation: " + (@reputation * 100) + "%" +
     "\nAgents: " + @agents.join(", ")


Loading the visualization API after the calculations to avoid race condition of not having data before rendering the graph

--- widow-analyze/src/main/coffee/controllers/PageSummaryController.coffee
+++ widow-analyze/src/main/coffee/controllers/PageSummaryController.coffee
@@ -27,12 +27,6 @@
   ################

   doCharts = (visits) ->
-    # Load the Visualization API and the chart package.
-    google.load 'visualization', '1.0', {
-      'packages': ['line']
-      'callback': -> loadCallback()
-    }
-
     responseTimes = ([
       new Date(visit['TIME_ACCESSED'])
       visit['LOAD_TIME_MILLIS']
@@ -49,6 +43,12 @@
     extra = (vMax - vMin) * 0.2
     vMax += extra
     vMin -= extra
+
+    # Load the Visualization API and the chart package.
+    google.load 'visualization', '1.0', {
+      'packages': ['line']
+      'callback': -> loadCallback()
+    }

     # Set a callback to run when the Google Visualization API is loaded.
     loadCallback = ->
@@ -71,8 +71,12 @@
           minValue: vMin
           maxValue: vMax
         }
+        chartArea: {
+          backgroundColor: '#f0f0f0'
+        }
         width: 800
         height: 400
+        pointSize: 5
       }

       # Instantiate and draw our chart, passing in some options.


stacktemplate: remove Validator.own permission from generateStack and clone

--- workers/social/lib/social/models/computeproviders/stacktemplate.coffee
+++ workers/social/lib/social/models/computeproviders/stacktemplate.coffee
@@ -325,7 +325,7 @@
   generateStack: permit

     advanced: [
-      { permission: 'update own stack template', validateWith: Validators.own }
+      { permission: 'update own stack template' }
       { permission: 'update stack template' }
     ]

@@ -449,7 +449,7 @@
   clone: permit

     advanced: [
-      { permission: 'update own stack template', validateWith: Validators.own }
+      { permission: 'update own stack template' }
       { permission: 'update stack template' }
     ]


refactor(autocomplete): Removed unnecessary watch

--- src/directives/autocomplete.coffee
+++ src/directives/autocomplete.coffee
@@ -61,10 +61,6 @@
       $menuScope       = $rootScope.$new()
       $menuScope.items = []
       $menuScope.index = 0
-
-      $scope.$watch attrs.ngModel, (value) ->
-        ctrl.$setViewValue value
-        ctrl.$render()

       ctrl.$parsers.push (value) ->
         if value and not disabled($scope)


remove verbose logging in navbar.directive

--- src/app/components/navbar/navbar.directive.coffee
+++ src/app/components/navbar/navbar.directive.coffee
@@ -11,12 +11,10 @@

       vm.activeRoute = undefined
       $rootScope.$on '$stateChangeSuccess', (event, toState, toParams, fromState, fromParams) ->
-        $log.log 'State change success event', event, toState, toParams, fromState, fromParams
         vm.activeRoute = toState.name

       vm.currentLanguage = -> 'navigation.language.' + if $translate.use() == 'en_EN' then 'de_DE' else 'en_EN'
-      vm.toggleLanguage = ->
-        $translate.use( if $translate.use() == 'en_EN' then 'de_DE' else 'en_EN')
+      vm.toggleLanguage = -> $translate.use( if $translate.use() == 'en_EN' then 'de_DE' else 'en_EN')

       return


Use English words in the English translation.

--- coffeescripts/cards-en.coffee
+++ coffeescripts/cards-en.coffee
@@ -33,7 +33,7 @@
         "TIE Advanced Expansion Pack": "TIE Advanced Expansion Pack"
         "Lambda-Class Shuttle Expansion Pack": "Lambda-Class Shuttle Expansion Pack"
         "Slave I Expansion Pack": "Slave I Expansion Pack"
-        "Imperial Aces Expansion Pack": "Imperial Aces Erweiterung"
+        "Imperial Aces Expansion Pack": "Imperial Aces Expansion Pack"
     ui:
         pilotSelectorPlaceholder: "Select a pilot"
         upgradePlaceholder: (translator, language, slot) ->


fix docker build command.

fix docker build command.

--- services/document-updater/Gruntfile.coffee
+++ services/document-updater/Gruntfile.coffee
@@ -75,7 +75,7 @@
 				command: """
 				if [ -z $(docker images | awk \'{ print $1 }\' | grep sharelatex-docupdater-tests) ];
 				then
-				  docker build . -t sharelatex-docupdater-tests;
+				  docker build -t sharelatex-docupdater-tests .;
 			  else
 					echo ">> docker image \'sharelatex-docupdater-tests\' already exists";
 				fi


Add more packages for javascript development in Atom

--- atom/dot-atom/packages.cson
+++ atom/dot-atom/packages.cson
@@ -28,6 +28,7 @@
   "autocomplete-R"
   "autocomplete-sql"
   "autocomplete-xml"
+  "browser-plus"
   "build"
   "build-make"
   "busy"
@@ -70,6 +71,7 @@
   "linter-eslint"
   "linter-flake8"
   "linter-flow"
+  "linter-jshint"
   "linter-lintr"
   "linter-markdown"
   "linter-pydocstyle"


Fix #4934, #4899, and #3911. Channels were the creator wasn't imported was causing issues

--- packages/rocketchat-importer-slack/server.coffee
+++ packages/rocketchat-importer-slack/server.coffee
@@ -135,7 +135,12 @@
 									url = user.profile.image_original
 								else if user.profile.image_512
 									url = user.profile.image_512
-								Meteor.call 'setAvatarFromService', url, undefined, 'url'
+
+								try
+								  Meteor.call 'setAvatarFromService', url, undefined, 'url'
+								catch error
+								  this.logger.warn "Failed to set #{user.name}'s avatar from url #{url}"
+
 								# Slack's is -18000 which translates to Rocket.Chat's after dividing by 3600
 								if user.tz_offset
 									Meteor.call 'userSetUtcOffset', user.tz_offset / 3600
@@ -173,13 +178,9 @@
 								if user?
 									users.push user.username

-							userId = ''
-							for user in @users.users when user.id is channel.creator
+							userId = startedByUserId
+							for user in @users.users when user.id is channel.creator and user.do_import
 								userId = user.rocketId
-
-							if userId is ''
-								@logger.warn "Failed to find the channel creator for #{channel.name}, setting it to the current running user."
-								userId = startedByUserId

 							Meteor.runAsUser userId, () =>
 								returned = Meteor.call 'createChannel', channel.name, users


cooldown finilazation

cooldown finilazation

--- src/cooldown.coffee
+++ src/cooldown.coffee
@@ -9,7 +9,7 @@
       I[name] = I[name].approach(target, approachBy)

   cooldown: (name, options={target: 0, approachBy: 1, value: null}) ->
-    options.target ||=
+    options.target ||= 0

     unless I.cooldowns[name]
       I.cooldowns[name] = options


cooldown finilazation

cooldown finilazation

--- src/cooldown.coffee
+++ src/cooldown.coffee
@@ -8,7 +8,7 @@

       I[name] = I[name].approach(target, approachBy)

-  cooldown: (name, options={target: 0, approachBy: 1, value: null}) ->
+  cooldown: (name, options={}) ->
     options.target ||= 0
     unless options.approachBy


fix non-ember version

fix non-ember version

--- app/scripts/main.coffee
+++ app/scripts/main.coffee
@@ -1,10 +1,5 @@
 'use strict'
 @Clean = @Clean || {}
-
-@Clean = Ember.Application.create
-  LOG_TRANSITIONS: true
-  DEBUG: false
-  rootElement: '#application'

 @Clean.editor = new Editor
   newPostCallback: (editor)->
@@ -27,4 +22,7 @@
         editor.setConnecting false
       error: ->
         console.log 'unable to autosave'
-        editor.setConnecting false+        editor.setConnecting false
+
+$(document).ready =>
+  @Clean.editor.init()


updated path creation to use __dirname

updated path creation to use __dirname

--- config/files.coffee
+++ config/files.coffee
@@ -15,5 +15,5 @@
   local_dependancies: local_dependancies

   test_parameters: './test/parameters.coffee'
-  tests_core: ("./test/spec/#{filename}" for filename in wrench.readdirSyncRecursive('./test/spec') when /\.coffee$/.test(filename))
-  tests_webpack: ("./config/builds/test/#{filename}" for filename in wrench.readdirSyncRecursive('./config/builds/test') when /\.webpack.config.coffee$/.test(filename))
+  tests_core: ("./test/spec/#{filename}" for filename in wrench.readdirSyncRecursive(__dirname + '/../test/spec') when /\.coffee$/.test(filename))
+  tests_webpack: ("./config/builds/test/#{filename}" for filename in wrench.readdirSyncRecursive(__dirname + '/builds/test') when /\.webpack.config.coffee$/.test(filename))


redundant from lineman-lib

redundant from lineman-lib

--- config/files.coffee
+++ config/files.coffee
@@ -7,8 +7,3 @@
 #

 module.exports = (lineman) ->
-  grunt = lineman.grunt
-
-  js:
-    uncompressedDist: "dist/#{grunt.file.readJSON('package.json').name}.js"
-


Updating to 1.0 api

Updating to 1.0 api

--- keymaps/jsdoc.cson
+++ keymaps/jsdoc.cson
@@ -1,2 +1,2 @@
-'.editor':
+'atom-text-editor':
   'ctrl-shift-d': 'jsdoc:block'


:penguin: Add application:open-dev keybinding

--- keymaps/linux.cson
+++ keymaps/linux.cson
@@ -10,6 +10,7 @@
   'ctrl-alt-i': 'window:toggle-dev-tools'
   'ctrl-alt-p': 'window:run-package-specs'
   'ctrl-alt-s': 'application:run-all-specs'
+  'ctrl-shift-o': 'application:open-dev'

   # Sublime Parity
   'ctrl-N': 'application:new-window'


Add boilerplate snippets

Add boilerplate snippets

--- .atom/snippets.cson
+++ .atom/snippets.cson
@@ -13,3 +13,18 @@
 #     'prefix': 'log'
 #     'body': 'console.log $1'
 #
+'.source.js':
+  'jquery ready':
+    'prefix': 'ready'
+    'body': """
+      $("${1:selector}").ready(function(){
+        $2
+      });
+    """
+  'self executing':
+    'prefix': 'load'
+    'body': """
+      $(function() {
+        $1
+      });
+      """


Bugfix (due to coffeescript) to JS behaviour

--- collector/scripts/frontend.coffee
+++ collector/scripts/frontend.coffee
@@ -70,12 +70,12 @@
 	eventTarget.value = ""
 	replySpace.textContent = reply
 	replySpace.className += " show"
-	parent.scroll(0,100000) //Hack
+	parent.scroll(0,100000) #Hack
 	nextResponse = parent.querySelector(".robot:not(.show)")
 	if nextResponse?
 		showNext = ->
 			nextResponse.className += " show"
-			parent.scrollY(0,100000) //Hack
+			parent.scrollY(0,100000) #Hack
 		setTimeout(showNext, 1000)
 	if not parent.querySelector(".tester:not(.show)")?
 		eventTarget.setAttribute("disabled", "disabled")


Improve whitespace config

Improve whitespace config

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -25,7 +25,7 @@
       "wrap-guide"
     ]
   whitespace:
-    ensureSingleTrailingNewline: false
+    ignoreWhitespaceOnCurrentLine: false
   "multi-wrap-guide":
     columns: [
       80


changed Atom themes

changed Atom themes

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -42,13 +42,12 @@
       "script"
       "archive-view"
       "feedback"
-      "atom-color-highlight"
       "tabs"
       "tree-view"
     ]
     themes: [
-      "isotope-ui"
-      "predawn-syntax"
+      "rain-ui"
+      "rain-syntax"
     ]
     projectHome: "~/Sites"
   "spell-check":


New setup

New setup

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -1,35 +1,37 @@
-'editor':
-  'showIndentGuide': true
-  'fontFamily': 'Menlo'
-  'fontSize': 15
-'core':
-  'excludeVcsIgnoredPaths': true
-  'ignoredNames': [
-    '.bundle'
-    '.git'
-    'log'
-    'repositories'
-    'tmp'
-    'vendor'
-  ]
-  'themes': [
-    'unity-ui'
-    'glacier-syntax'
-  ]
-  'hideGitIgnoredFiles': true
-  'disabledPackages': [
-    'background-tips'
-    'exception-reporting'
-    'metrics'
-  ]
-'spell-check':
-  'grammars': [
-    'text.plain'
-    'source.gfm'
-    'text.git-commit'
-  ]
-'welcome':
-  'showOnStartup': false
-'release-notes':
-  'viewedVersion': '0.89.0'
-'tree-view': {}
+"*":
+  editor:
+    showIndentGuide: true
+    invisibles: {}
+    showInvisibles: true
+    fontFamily: "Roboto Mono"
+  core:
+    excludeVcsIgnoredPaths: true
+    ignoredNames: [
+      ".bundle"
+      ".git"
+      "log"
+      "repositories"
+      "tmp"
+      "vendor"
+    ]
+    themes: [
+      "atom-dark-ui"
+      "atom-dark-syntax"
+    ]
+    hideGitIgnoredFiles: true
+    disabledPackages: [
+      "background-tips"
+      "exception-reporting"
+      "metrics"
+    ]
+  "spell-check":
+    grammars: [
+      "text.plain"
+      "source.gfm"
+      "text.git-commit"
+    ]
+  welcome:
+    showOnStartup: false
+  "release-notes":
+    viewedVersion: "0.89.0"
+  "tree-view": {}


Updates atom config

Updates atom config

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -1,13 +1,18 @@
 "*":
-  editor:
-    showInvisibles: true
-    showIndentGuide: true
-    preferredLineLength: 100
-    softWrap: true
-    softWrapAtPreferredLineLength: true
-    invisibles: {}
-    fontSize: 11
+  "atom-beautify":
+    _analyticsUserId: "dd5ae96b-29e0-40aa-be70-a2344a5c6ad2"
+    beautifyEntireFileOnSave: false
+    js_preserve_newlines: false
+    js_space_before_conditional: false
+  autocomplete:
+    includeCompletionsFromAllBuffers: false
+  "autocomplete-plus": {}
   core:
+    disabledPackages: [
+      "jshint"
+      "atom-jshint"
+      "linter-jshint"
+    ]
     ignoredNames: [
       ".git"
       ".svn"
@@ -17,19 +22,31 @@
       "seti-ui"
       "monokai"
     ]
-    disabledPackages: [
-      "jshint"
-      "atom-jshint"
-      "linter-jshint"
-    ]
+  editor:
+    fontSize: 11
+    invisibles: {}
+    preferredLineLength: 100
+    showIndentGuide: true
+    showInvisibles: true
+    softWrap: true
+    softWrapAtPreferredLineLength: true
+  emmet: {}
+  esformatter:
+    formatOnSave: true
   "exception-reporting":
     userId: "927ad9ee-b6a5-4937-bc3c-31ee92e96c24"
-  "release-notes":
-    viewedVersion: "0.90.0"
-  welcome:
-    showOnStartup: false
-  metrics:
-    userId: "c5a6a7c8def523ce52153546d495c81bb7082706"
+  "git-plus": {}
+  linter:
+    ignoredLinterErrors: [
+      "jshint"
+    ]
+    showErrorPanel: false
+  "linter-eslint":
+    disableWhenNoEslintrcFileInPath: true
+    globalNodePath: "/Users/benoit/.node"
+  "linter-jshint": {}
+  "linter-scss-lint":
+    executablePath: "/usr/local/bin/scss-lint"
   "markdown-preview":
     grammars: [
       "source.gfm"
@@ -38,44 +55,28 @@
       "text.plain.null-grammar"
     ]
     useGitHubStyle: true
-  autocomplete:
-    includeCompletionsFromAllBuffers: false
-  whitespace:
-    ignoreWhitespaceOnCurrentLine: false
-  esformatter:
-    formatOnSave: true
-  "atom-beautify":
-    _analyticsUserId: "dd5ae96b-29e0-40aa-be70-a2344a5c6ad2"
-    js_preserve_newlines: false
-    js_space_before_conditional: false
-    beautifyEntireFileOnSave: false
-  linter:
-    ignoredLinterErrors: [
-      "jshint"
-    ]
-    showErrorPanel: false
-  "autocomplete-plus": {}
-  "linter-jshint": {}
-  "git-plus": {}
+  metrics:
+    userId: "c5a6a7c8def523ce52153546d495c81bb7082706"
   react: {}
+  "release-notes":
+    viewedVersion: "0.90.0"
+  tabs:
+    usePreviewTabs: true
   "tool-bar":
     iconSize: "16px"
     position: "Left"
-  emmet: {}
-  "linter-scss-lint":
-    executablePath: "/usr/local/bin/scss-lint"
   "tree-view": {}
-  tabs:
-    usePreviewTabs: true
-  "linter-eslint":
-    globalNodePath: "/Users/benoit/.node"
-    disableWhenNoEslintrcFileInPath: true
-".js.jsx.source":
-  editor:
-    preferredLineLength: 100
+  welcome:
+    showOnStartup: false
+  whitespace:
+    ignoreWhitespaceOnCurrentLine: false
+    keepMarkdownLineBreakWhitespace: false
 ".coffee.jsx.source":
   editor:
     preferredLineLength: 100
 ".diff.source":
   editor:
     preferredLineLength: 100
+".js.jsx.source":
+  editor:
+    preferredLineLength: 100


Add some atom config

Add some atom config

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -24,10 +24,12 @@
     invisibles: {}
     showIndentGuide: true
     softWrapAtPreferredLineLength: true
-  "go-plus":
-    goPath: "/Users/holman/Code/go"
-  "release-notes":
-    viewedVersion: "0.89.0"
+    disabledPackages: [
+      "background-tips"
+      "exception-reporting"
+      "metrics"
+      "linter-shellcheck"
+    ]
   "spell-check":
     grammars: [
       "text.plain"
@@ -37,3 +39,7 @@
     ]
   welcome:
     showOnStartup: false
+  "release-notes":
+    viewedVersion: "0.89.0"
+  tabs:
+    usePreviewTabs: true


Add editorconfig package

Add editorconfig package

--- atom/.atom/packages.cson
+++ atom/.atom/packages.cson
@@ -3,6 +3,7 @@
   'atom-beautify'
   'atom-idiomatic-comments-css-snippets'
   'cursor-blink-interval'
+  'editorconfig'
   'emmet'
   'file-icons'
   'highlight-line'


add option to build test file specs.js and also provide an option to watch if any file changes to to specs source files

--- src/hem.coffee
+++ src/hem.coffee
@@ -12,6 +12,7 @@
   '    server  start a dynamic development server',
   '    build   serialize application to disk',
   '    watch   build & watch disk for changes'
+  '    test    build and run tests'
 ].join("\n"))
 .alias('p', 'port')
 .alias('d', 'debug')
@@ -90,18 +91,23 @@
     source = @cssPackage().compile()
     fs.writeFileSync(path.join(@options.public, @options.cssPath), source)

-    # TODO add build for tests??
+    if buildTests
+      source = @specsPackage().compile()
+      fs.writeFileSync(path.join(@options.testPublic, @options.specsPath), source)

-  watch: ->
+  watch: (callback) ->
     @build()
-    # TODO watch specs folder too??
-    # TODO or separate watchTests folder that will build and launch phantomjs
-    for dir in (path.dirname(lib) for lib in @options.libs).concat @options.css, @options.paths
+    for dir in (path.dirname(lib) for lib in @options.libs).concat @options.css, @options.paths, @options.specs
       continue unless fs.existsSync(dir)
       require('watch').watchTree dir, (file, curr, prev) =>
         if curr and (curr.nlink is 0 or +curr.mtime isnt +prev?.mtime)
           console.log "#{file} changed.  Rebuilding."
           @build()
+          # TODO: run script here if option is provided
+
+  test: ->
+    @build true
+    # TODO: run phatomjs and print output

   exec: (command = argv._[0]) ->
     return help() unless @[command]
@@ -109,6 +115,7 @@
     switch command
       when 'build'  then console.log 'Built application'
       when 'watch'  then console.log 'Watching application'
+      when 'test'   then console.log 'Testing application'

   # Private


Query definition on sanitization must be enclosed with a group

--- components/SanitizeObjects.coffee
+++ components/SanitizeObjects.coffee
@@ -13,6 +13,7 @@
       definition: new noflo.Port
     @outPorts =
       out: new noflo.Port
+      error: new noflo.Port

     @inPorts.definition.on "connect", =>
       @definitions = {}
@@ -22,7 +23,14 @@
       @definitions[@table] ?= []

     @inPorts.definition.on "data", (def) =>
-      @definitions[@table].push def
+      error = new Error 'There must be a group indicating which table'
+      if @table?
+        @definitions[@table].push def
+      else if @outPorts.error.isAttached()
+        @outPorts.error.send error
+        @outPorts.error.disconnect()
+      else
+        throw error

     @inPorts.definition.on "disconnect", =>
       @table = null


Uppercased prefixes to avoid console log warnings in React 0.13

--- src/index.cjsx
+++ src/index.cjsx
@@ -130,8 +130,8 @@
       left: 0
       right: 0
       zIndex: 1
-      webkitTransform: "translateY(#{@state.translateY})"
-      msTransform: "translateY(#{@state.translateY})"
+      WebkitTransform: "translateY(#{@state.translateY})"
+      MsTransform: "translateY(#{@state.translateY})"
       transform: "translateY(#{@state.translateY})"

     # Don't add css transitions until after we've done the initial
@@ -140,9 +140,9 @@
     # while it transitions from 0 — -100%.
     if @state.state isnt "unfixed"
       style = objectAssign style, {
-        webkitTransition: "all .2s ease-in-out"
-        mozTransition: "all .2s ease-in-out"
-        oTransition: "all .2s ease-in-out"
+        WebkitTransition: "all .2s ease-in-out"
+        MozTransition: "all .2s ease-in-out"
+        OTransition: "all .2s ease-in-out"
         transition: "all .2s ease-in-out"
       }


Add shortcuts to jump between Git diffs

Add shortcuts to jump between Git diffs

--- .config/keymap.cson
+++ .config/keymap.cson
@@ -49,6 +49,8 @@
 # Navigation
 "atom-workspace atom-text-editor:not(.mini)":
 	"cmd-g":          "go-to-line:toggle"
+	"cmd-[":          "git-diff:move-to-previous-diff"
+	"cmd-]":          "git-diff:move-to-next-diff"
 	"ctrl-f":         "file-icons:open-settings"

 ".platform-darwin":


Pass user to subject page forms

Pass user to subject page forms

- Closes #1110

--- app/subjects/index.cjsx
+++ app/subjects/index.cjsx
@@ -94,9 +94,10 @@
                     </div>
                     <div>
                       {if @state.tab is 0
-                        <QuickSubjectCommentForm subject={subject} user={user} />
+                        <QuickSubjectCommentForm subject={subject} user={@props.user} />
                        else if @state.tab is 1
                         <NewDiscussionForm
+                          user={@props.user}
                           subject={subject}
                           onCreateDiscussion={@onCreateDiscussion} />
                           }


config: add countly restore op

config: add countly restore op

--- config/generateRunFile.coffee
+++ config/generateRunFile.coffee
@@ -445,6 +445,7 @@
       restoredefaultmongodump
       restoreredis
       restorerabbitmq
+      restorecountly
       restoredefaultpostgresdump

       echo "#---> CLEARING ALGOLIA INDEXES: <---#"


Js refactor

Js refactor

--- app/assets/javascripts/activeadmin_ancestry_view/base.coffee
+++ app/assets/javascripts/activeadmin_ancestry_view/base.coffee
@@ -44,7 +44,7 @@
       Math.abs $(sourceNode).offset().top - $(targetNode).offset().top

     verticalBranch: (node, lastChild) ->
-      this.betweenTop(node, lastChild) + this.middleHeight(lastChild)
+      @betweenTop(node, lastChild) + @middleHeight(lastChild)

   branchProp =
     base:
@@ -57,14 +57,14 @@
       "margin-left: 2em; " +
       "height: #{height}px; " +
       "z-index: -1; " +
-      this.base
+      @base

     horizontal: (marginTop) ->
       "margin-top: -#{marginTop}px; " +
       "margin-left: -2em; " +
       "width: 2em; " +
       "z-index: -2; " +
-      this.base
+      @base

   pseudoElement =
     addHorizontal: (node) ->
@@ -107,13 +107,16 @@
       allParents  = $(node).prevAll('.panel-parent')
       parentIds   = $.map(allParents, (el) -> $(el).attr 'id')
       actualIds   = similarItems(nodeClasses, parentIds)
+
       # add current node id
       actualIds.push $(node).attr('id')
       # get array of jquery elements from actual ids
       actualCollection = getElements(actualIds)
       # update vertical pseudoelement of actual elements
-      $.each actualCollection, (i, element) ->
-        this.uptVertical(element)
+      that = this
+      $.each(actualCollection, (i, element) ->
+        that.uptVertical(element)
+      )

   findPanelHeader = (object) ->
     object.find('.panel').find('.panel-header')
@@ -128,9 +131,7 @@
     item for item in arr2 when item in arr1

   getElements = (arrayOfIds) ->
-    $.map(arrayOfIds, (id) ->
-      $("##{id}").get()
-    )
+    $.map arrayOfIds, (id) -> $("##{id}").get()

   # inherit color from parent panel on load
   # if parent has no color, inherit from parent of parent
@@ -155,7 +156,7 @@
       content.show 0, -> pseudoElement.uptHorizontal(node)
     else
       content.hide 0, -> pseudoElement.uptHorizontal(node)
-    pseudoelement.uptEachVertical(node)
+    pseudoElement.uptEachVertical(node)

   # show-hide content table for bunch of nodes
   $('.show-childrens').click ->
@@ -180,7 +181,7 @@
         subLastChildId = $(subNode).attr 'data-last-child'
         pseudoElement.uptVertical $("##{subLastChildId}") if subLastChildId?

-    pseudoelement.uptEachVertical(lastChild)
+    pseudoElement.uptEachVertical(lastChild)

   # select user
   $('.panel-header').on 'click', ->


fix for popovers

fix for popovers

--- app/assets/javascripts/admin/admin_in_place_editor.js.coffee
+++ app/assets/javascripts/admin/admin_in_place_editor.js.coffee
@@ -41,8 +41,8 @@

 class AdminInPlaceEditor extends AdminEditor
   init: () ->
+    super
     @initEditors()
-    @initModals()

   initEditors: () ->
     $('#admin-in-place-editor .editable').editable


remove administrator addition to couchDB

--- config/initializers/db.coffee
+++ config/initializers/db.coffee
@@ -17,16 +17,6 @@
         data = fs.readFileSync '/etc/cozy/couchdb.login'
         lines = S(data.toString('utf8')).lines()
         return lines
-
-    # Add admin to couchDB
-    # Result : Unauthorized applications cannot create a database
-    addCouchdbAdmin = (callback) ->
-        loginCouch = initLoginCouch()
-        couchClient.put "_config/admins/#{loginCouch[0]}", "#{loginCouch[1]}",
-                (err, res, body) =>
-            couchClient.setBasicAuth(loginCouch[0],loginCouch[1])
-            couchClient.get 'cozy/_security', (err, res, body) =>
-                callback err, body

     # Add admin to cozy database
     # Result : Unauthorized applications cannot read on cozy
@@ -70,8 +60,9 @@
                 feed_start()
             else if exists
                 if process.env.ENV_VARIABLE is 'production'
-                    addCouchdbAdmin (err, body) =>
-                        loginCouch = initLoginCouch()
+                    loginCouch = initLoginCouch()
+                    couchClient.setBasicAuth(loginCouch[0],loginCouch[1])
+                    couchClient.get 'cozy/_security', (err, res, body)=>
                         if not body.admins? or
                                 body.admins.names[0] isnt loginCouch[0]
                             addCozyAdmin (err) =>
@@ -94,16 +85,12 @@
         db.create (err) ->
             if err
                 logError()
-            else if (process.env.ENV_VARIABLE is 'production')
-                addCouchdbAdmin (err, body) =>
+            else if (process.env.ENV_VARIABLE is 'production')
+                addCozyAdmin (err) =>
                     if err
                         logError()
-                    else
-                        addCozyAdmin (err) =>
-                            if err
-                                logError()
-                            else
-                                logCreated
+                    else
+                        logCreated
             else
                 logCreated


Removed 'inherit' keyword for backward compatibility with 0.10

--- src/dispatch.coffee
+++ src/dispatch.coffee
@@ -79,7 +79,7 @@
       # commands, which would lead to a complete crash.
       # We'll see when that happens :)
       if pStdout
-        execSettings.stdio = [null, "inherit", process.stderr, "ipc"]
+        execSettings.stdio = [null, process.stdout, process.stderr, "ipc"]
       else
         execSettings.stdio = [null, "pipe", process.stderr, "ipc"]


[improvement] Showed PTO on Timesheet reports (10m)

--- app/assets/javascripts/houston/reports/timesheet_view.coffee
+++ app/assets/javascripts/houston/reports/timesheet_view.coffee
@@ -18,7 +18,9 @@
       "project-maintenance",

       "planning",
-      "ux-research"
+      "ux-research",
+
+      "pto"
     ]
     @colors = [
       'rgba(220, 81, 27, 0.75)',
@@ -33,6 +35,8 @@

       'rgba(28, 28, 28, 0.5)',
       'rgba(140, 135, 134, 0.5)',
+
+      'rgba(98, 183, 0, 0.1)',
     ]

     view = @
@@ -50,7 +54,7 @@
       start: App.serverDateFormat(@start)
       end: App.serverDateFormat(@end)
       subject_type: "User"
-      name: ["daily.hours.worked", "daily.hours.charged.{#{@components.join(",")}}"]
+      name: ["daily.hours.{off,worked}", "daily.hours.charged.{#{@components.join(",")}}"]
     jqXHR = $.getJSON "/api/v1/measurements", params, (measurements, response, jqXHR) =>
       i = @requests.indexOf(jqXHR)
       @requests.splice(i, 1)
@@ -102,6 +106,9 @@

       if name == "daily.hours.worked"
         ceilsByDate[App.serverDateFormat(date)][1] += +value
+      else if name == "daily.hours.off"
+        i = @components.indexOf("pto")
+        stack[i + 1] += +value unless i < 0
       else
         i = @components.indexOf(name.substr(20))
         stack[i + 1] += +value unless i < 0


typo修正

typo修正

--- app/assets/javascripts/ponytail/models/migration_file.coffee
+++ app/assets/javascripts/ponytail/models/migration_file.coffee
@@ -13,7 +13,7 @@

   update: =>
     rawContent = [
-      "class #{@.get("className")} < ActiveRecord::MigrationFile",
+      "class #{@.get("className")} < ActiveRecord::Migration",
       @.getContentOfClass(),
       "end",
     ].join("\n")


break it down!

break it down!

--- app/assets/javascripts/views/decision_radio_button.js.coffee
+++ app/assets/javascripts/views/decision_radio_button.js.coffee
@@ -2,7 +2,9 @@
   click: ->
     paper = @get('model')
     decision = @get('value')
-    @get('controller').send('setDecisionTemplate', paper, decision)
+    Ember.run.later(@, (->
+      @get('controller').send('setDecisionTemplate', paper, decision)
+    ), 150)

   checked: (->
     @get('value') == @get('selection')


Add education route

Add education route

--- apps/about/index.coffee
+++ apps/about/index.coffee
@@ -15,3 +15,5 @@
   res.render 'faqs'
 app.get '/pricing', (_req, res) ->
   res.redirect '/about#pricing'
+app.get '/education', (_req, res) ->
+  res.render 'education'


Removed caching of post otherwise we won't get the increments.

--- apps/blog/routes.coffee
+++ apps/blog/routes.coffee
@@ -32,7 +32,6 @@
 module.exports.post = (req, res) ->
     post = new Post id: req.params.post
     post.fetch
-        cache: sd.ENV is 'production'
         success: ->
             res.locals.sd.blogPost = post.toJSON()
             template.render req, res,


revert bad change

revert bad change

--- src/jvm.coffee
+++ src/jvm.coffee
@@ -32,11 +32,8 @@
 show_stacktrace = (rs,e) ->
   e_type = rs.get_obj(e.exception.fields.cause).type
   detail_ref = e.exception.fields.detailMessage
-  if detail_ref
-    detail = rs.jvm2js_str rs.get_obj detail_ref
-    console.error "Exception in thread \"main\" #{detail}"
-  else
-    console.error "Exception in thread \"main\" #{ext_classname e_type}"
+  detail = if detail_ref then rs.jvm2js_str rs.get_obj detail_ref else ''
+  console.error "Exception in thread \"main\" #{ext_classname e_type}: #{detail}"
   for i in [e.stack.length-1..0] by -1
     entry = e.stack[i]
     console.error "\tat #{entry.cls}.#{entry.method}(#{entry.file}:#{entry.line}, code #{entry.op})"


Help text for orchid species

Help text for orchid species

--- content/field-examples.coffee
+++ content/field-examples.coffee
@@ -1,11 +1,11 @@
 module.exports = [{
     label: 'Species'
     content: '''
-                 Identify the species by selecting from the photographs of the 29 species in the study. You can refine your selection by selecting flower colour and/or habitat from the drop down list
+                 The thumbnails show the 29 species included in this survey. The colour and habitat filter tools can help you to narrow your search but your selections will not be recorded. We only record your final choice of species name. For more help identifying the orchids in this survey please see our Identification Guide (16.5MB PDF).
                  '''

     figures: [{
-      label: 'Download the idenitification guide (16.5MB PDF)'
+      label: 'Zoom in on the main image to see the flowers in close-up; flower shape and colour pattern are key identification features. Select the orchid that most closely matches the main image.'
       image: "examples/species.jpg"
       alt: "Screenshot of the species identification tool."
     }]


config: remove duplicate helpscout setting

--- config/credentials.default.coffee
+++ config/credentials.default.coffee
@@ -176,9 +176,6 @@
     secretKey: ""
   vmwatcher =
     secretKey: ""
-  helpscout =
-    apiKey: ''
-    baseUrl: 'https://api.helpscout.net/v1'
   recurly =
     apiKey: ""
     loggedRequests: "/^(subscriptions|transactions)/"


dotchart: remove extraneous blank line

dotchart: remove extraneous blank line

--- src/dotchart.coffee
+++ src/dotchart.coffee
@@ -101,7 +101,6 @@
         xscale = myframe.xscale()
         yscale = myframe.yscale()

-
         # jitter x-axis
         if xjitter == null
             xjitter = ((Math.random()-0.5)*0.2 for v in d3.range(x.length))


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/drawable.coffee
+++ src/drawable.coffee
@@ -23,7 +23,12 @@
     spriteName: null
     zIndex: 0

-  if I.spriteName
+  if I.sprite.isString?()
+    I.sprite = Sprite(I.sprite, (sprite) ->
+      I.width = sprite.width
+      I.height = sprite.height
+    )
+  else if I.spriteName
     I.sprite = Sprite(I.spriteName, (sprite) ->
       I.width = sprite.width
       I.height = sprite.height


Check for textContent support in fallback

textContent is not supported in IE8 and earlier, when fallback is likely

--- src/dropzone.coffee
+++ src/dropzone.coffee
@@ -274,7 +274,11 @@
         @element.appendChild messageElement

       span = messageElement.getElementsByTagName("span")[0]
-      span.textContent = @options.dictFallbackMessage if span
+      if span
+        if span.textContent?
+          span.textContent = @options.dictFallbackMessage
+        else if span.innerText?
+          span.innerText = @options.dictFallbackMessage

       @element.appendChild @getFallbackForm()


Calls _updateMaxFilesReachedClass after File.accepted has been set

--- src/dropzone.coffee
+++ src/dropzone.coffee
@@ -299,8 +299,6 @@

         file.previewElement.appendChild file._removeLink

-      @_updateMaxFilesReachedClass()
-
     # Called whenever a file is removed.
     removedfile: (file) ->
       file.previewElement?.parentNode.removeChild file.previewElement
@@ -744,6 +742,8 @@
         @_errorProcessing [ file ], error # Will set the file.status
       else
         @enqueueFile file # Will set .accepted = true
+      @_updateMaxFilesReachedClass()
+

   # Wrapper for enqueuFile
   enqueueFiles: (files) -> @enqueueFile file for file in files; null


Fixed possible duplication of event subscription

--- client/app/lib/providers/machinesettingssnapshotsview.coffee
+++ client/app/lib/providers/machinesettingssnapshotsview.coffee
@@ -57,18 +57,20 @@
     machineId         = machine._id
     eventId           = "createSnapshot-#{machineId}"

-    monitorProgress = => computeController.on eventId, (event) =>
+    monitorProgress = (event) =>
       {error, percentage} = event
       @emit 'SnapshotProgress', percentage
       return  if percentage < 100
+      # Remove the subscriber if the percent is >= 100
+      computeController.off eventId, monitorProgress
       return callback error  if error
       # Because kloud.createSnapshot does not return a snapshot object,
       # we need to request the newest snapshot (sorted by creation date)
       snapshotHelpers.fetchNewestSnapshot machineId, callback

     computeController.createSnapshot machine, label
-      .then monitorProgress
       .catch callback
+      .then -> computeController.on eventId, monitorProgress

   ###*


invalid object id is now passed, not thrown http://nodeknockout.hoptoadapp.com/errors/10401481

--- controllers/middleware.coffee
+++ controllers/middleware.coffee
@@ -46,15 +46,11 @@

   loadTeam: (req, res, next) ->
     if id = req.params.teamId or req.params.id
-      try
-        Team.findById id, (err, team) ->
-          return next err if err
-          return next 404 unless team
-          req.team = team
-          next()
-      catch error
-        throw error unless error.message == 'Id cannot be longer than 12 bytes'
-        return next 404
+      Team.findById id, (err, team) ->
+        return next err if err && err.message != 'Invalid ObjectId'
+        return next 404 unless team
+        req.team = team
+        next()
     else if code = req.params.code
       code = qs.unescape(code)
       Team.findOne code: code, (err, team) ->


parse exit code, add as a trailer

parse exit code, add as a trailer

--- lib/builder.coffee
+++ lib/builder.coffee
@@ -36,8 +36,17 @@
         "Transfer-Encoding": "chunked"
         "X-Cache-Url":       builder.cache_url
         "X-Slug-Url":        builder.slug_url()
-      build.on "data", (data)   -> res.write(data)
-      build.on "end", (success) -> res.end()
+      build.on "data", (data)   ->
+        exit_header = "ANVIL!EXITCODE:"
+        if (pos = data.toString().indexOf(exit_header)) > -1
+          res.write data.slice(0, pos)
+          code = data[pos + exit_header.length]
+          res.addTrailers
+            "X-Exit-Code": code.toString()
+        else
+          res.write(data)
+      build.on "end", (success) ->
+        res.end()

   buildpack_with_default: (buildpack) ->
     if (buildpack || "") is "" then "https://buildkits.herokuapp.com/buildkit/default.tgz" else buildpack


var name fix

var name fix

--- client/landing/app/Applications/Environments.kdapplication/views/DomainMapperView.coffee
+++ client/landing/app/Applications/Environments.kdapplication/views/DomainMapperView.coffee
@@ -41,18 +41,16 @@
     options.cssClass = 'domain-vm-item'
     super options, data

-    listViewData = @getDelegate().getData()
-    switchStatus = if @getData().hostnameAlias in listViewData.hostnameAliases then on else off
-    domainIns    = listViewData.domain
-
-    console.log domainIns
+    listViewData   = @getDelegate().getData()
+    switchStatus   = if @getData().hostnameAlias in listViewData.hostnameAliases then on else off
+    domainInstance = listViewData.domain

     @onOff = new KDOnOffSwitch
       size        : 'small'
       labels      : ['CON', "DCON"]
       defaultValue: switchStatus
       callback : (state) =>
-        domainIns.bindVM
+        domainInstance.bindVM
           vmName     : @getData().name
           state      : state
         , (err) =>


typo :hamster:

typo :hamster:

--- lib/core/kd.coffee
+++ lib/core/kd.coffee
@@ -13,7 +13,7 @@
   if singletons[name]?
     singletons[name]
   else
-    debug "could not found singleton #{name}"
+    debug "could not find singleton #{name}"
     null

 module.exports =


remove incorrect and ineffective assert

remove incorrect and ineffective assert

--- src/Bacon.coffee
+++ src/Bacon.coffee
@@ -1048,7 +1048,6 @@
        f = patterns[i+1]
        pat = {f: (if isFunction(f) then f else (-> f)), ixs: []}
        for s in patSources
-         assert isObservable(s), usage
          index = _.indexOf(sources, s)
          if index < 0
             sources.push(s)


Fix brazilian regex

Fix brazilian regex


FIX #59: avoid half-drawn residues

FIX #59: avoid half-drawn residues

--- src/g/zoomer.coffee
+++ src/g/zoomer.coffee
@@ -12,9 +12,9 @@
     metaWidth: 100
     labelWidth: 100
     alignmentWidth: "auto"
-    alignmentHeight: 200
+    alignmentHeight: 195

-    rowHeight: 16
+    rowHeight: 15
     textVisible: true
     labelLength: 20
     labelFontsize: "10px"
@@ -65,8 +65,11 @@

     # TODO: dirty hack
     maxWidth = parentWidth - @getLabelWidth()
-    calcWidth = @g.zoomer.getAlignmentWidth( model.getMaxLength() - @g.columns.get('hidden').length)
-    @set "alignmentWidth", Math.min(maxWidth,calcWidth)
+    calcWidth = @getAlignmentWidth( model.getMaxLength() - @g.columns.get('hidden').length)
+    val = Math.min(maxWidth,calcWidth)
+    # round to a valid AA box
+    val = Math.floor( val / @get("columnWidth")) * @get("columnWidth")
+    @set "alignmentWidth", val
     #el.style.width = Math.min calcWidth, maxWidth

   # updates both scroll properties (if needed)


Test KanbanUsController

Test KanbanUsController

--- test/unit/controllers/kanbanControllerSpec.coffee
+++ test/unit/controllers/kanbanControllerSpec.coffee
@@ -316,3 +316,63 @@
                 expect(ctrl.scope.$emit).have.been.calledWith("spinner:stop")
                 expect(ctrl.scope.$emit).have.been.called.twice
                 expect(ctrl.scope.checksleyErrors).to.be.deep.equal({test: "test"})
+
+
+    describe "KanbanUsController", ->
+        httpBackend = null
+        scope = null
+        ctrl = null
+
+        beforeEach(inject(($rootScope, $controller, $httpBackend, $q, $gmFilters) ->
+            scope = $rootScope.$new()
+            ctrl = $controller("KanbanUsController", {
+                $scope: scope
+            })
+            httpBackend = $httpBackend
+            httpBackend.whenGET(APIURL+"/sites").respond(200, {test: "test"})
+            httpBackend.flush()
+        ))
+
+        afterEach ->
+            httpBackend.verifyNoOutstandingExpectation()
+            httpBackend.verifyNoOutstandingRequest()
+
+        it "should allow to change the assigned of a US on success", inject ($model) ->
+            us = $model.make_model("userstories", {id: 3, test: "test", assigned_to: 1})
+            newAssigned = 3
+
+            sinon.spy(us, "revert")
+            httpBackend.expectPATCH("#{APIURL}/userstories/#{us.id}", {assigned_to: newAssigned}).respond(
+                                                                                200, "ok")
+
+            ctrl.updateUsAssignation(us, newAssigned)
+            httpBackend.flush()
+
+            expect(us.revert).have.not.been.called
+            expect(us.assigned_to).to.be.equal(newAssigned)
+
+        it "should allow to change the assigned of a US on success", inject ($model) ->
+            us = $model.make_model("userstories", {id: 3, test: "test", assigned_to: 1})
+            newAssigned = 3
+
+            sinon.spy(us, "revert")
+            httpBackend.expectPATCH("#{APIURL}/userstories/#{us.id}", {assigned_to: newAssigned}).respond(
+                                                                                400, "error")
+
+            ctrl.updateUsAssignation(us, newAssigned)
+            httpBackend.flush()
+
+            expect(us.revert).have.been.calledOnce
+            expect(us.assigned_to).to.be.equal(1)
+
+        it "should go to the US detail page", ->
+            sinon.spy(ctrl.location, "url")
+            projectSlug = "test"
+            usRef = "1"
+
+            ctrl.openUs(projectSlug, usRef)
+            ctrl.location.url.should.have.been.calledOnce
+            ctrl.location.url.should.have.been.calledWith("/project/test/user-story/1")
+
+
+


Turned if nots in unless

Turned if nots in unless

--- js-library/src/js/models/fact.coffee
+++ js-library/src/js/models/fact.coffee
@@ -80,7 +80,7 @@

       @highlight()

-      if not @balloon.isVisible()
+      unless @balloon.isVisible()
         # Need to call a direct .hide() here to make sure not two popups are
         # open at a time
         Factlink.el.find('div.fl-popup').hide()
@@ -90,7 +90,7 @@
     @blur (e) =>
       clearTimeout(@timeout)

-      if not @balloon.loading()
+      unless @balloon.loading()
         @stopHighlighting()

         @timeout = setTimeout =>
@@ -107,7 +107,7 @@
   destroy: ->
     for el in @elements
       $el = $(el)
-      if not $el.is('.fl-first')
+      unless $el.is('.fl-first')
         $el.before $el.html()

       $el.remove()


The app url root is /test.

The app url root is /test.

--- test/midway/controllersSpec.coffee
+++ test/midway/controllersSpec.coffee
@@ -7,15 +7,14 @@
   afterEach ->
     tester.destroy()

-  describe 'The Subject List', ->
+  describe 'Subject List', ->
     scope = null

     it 'should route home to the subject list', (done) ->
-      tester.visit '/quip', ->
-        console.log(">> sl visit enter")
-        expect(tester.path()).to.equal('/quip')
+      tester.visit '/test/quip', ->
+        #expect(tester.path()).to.equal('/')
         expect(tester.viewElement()).to.exist
-        expect(tester.viewScope()).to.exist
+        console.log(tester.viewElement().html())
         # scope = tester.inject('$route').current.scope
         # console.log(">> sl ck " + scope)
         # resolved = ->
@@ -23,4 +22,4 @@
         # tester.until resolved, ->
         #   console.log(">> sl rslvd enter")
         #   expect(scope.subjects).to.not.be.empty
-        #   done()
+        done()


Fix Save As bug detected during Concord Cloud deprecation testing When switching providers (e.g. saving a file previously saved to Concord Cloud to Google Drive) the provider-specific data in the metadata must be cleared or it can confuse the new provider.

--- src/code/views/file-dialog-tab-view.coffee
+++ src/code/views/file-dialog-tab-view.coffee
@@ -117,7 +117,10 @@
     confirmed = (metadata) =>
       # ensure the metadata provider is the currently-showing tab
       @state.metadata = metadata
-      @state.metadata.provider = @props.provider
+      if @state.metadata.provider isnt @props.provider
+        @state.metadata.provider = @props.provider
+        # if switching provider, then clear providerData
+        @state.metadata.providerData = {}
       @props.dialog.callback? @state.metadata
       @props.close()


removing overrider env check. this will be done later

--- lib/pagerv2.coffee
+++ lib/pagerv2.coffee
@@ -209,18 +209,8 @@
         err 'Sorry you cannot set an override of more than 1 day.'
       else
         schedule_id = process.env.PAGERV2_SCHEDULE_ID
-        #how to test this? I tried setting the env var to '' and the robot.auth to null
-        #didn't work..
-        if process.env.PAGERV2_OVERRIDERS isnt ''
-          overriders = process.env.PAGERV2_OVERRIDERS?.split(',')
         if not who? or not who.name? or who.name is 'me'
           who = { name: from.name }
-        else
-          if overriders? and who not in overriders
-            unless @robot.auth? and
-               (@robot.auth.hasRole(from, ['pageradmin']) or @robot.auth.isAdmin(from))
-              who = null
-              err "You cannot force #{who.name} to take the override."
         if who?
           @getUser(from, who)
           .bind({ id: null })
@@ -264,14 +254,6 @@
       schedule_id = process.env.PAGERV2_SCHEDULE_ID
       if not who? or not who.name? or who.name is 'me'
         who = { name: from.name }
-      else
-        if process.env.PAGERV2_OVERRIDERS isnt ''
-          overriders = process.env.PAGERV2_OVERRIDERS?.split(',')
-        if overriders? and who not in overriders
-          unless @robot.auth? and
-             (@robot.auth.hasRole(from, ['pageradmin']) or @robot.auth.isAdmin(from))
-            who = null
-            err "You cannot force #{who.name} to take the override."
       if who?
         @getUser(from, who)
         .bind({ id: null })


plane image now rotates to angle of last plot line

--- src/components/learning-guide-chart.coffee
+++ src/components/learning-guide-chart.coffee
@@ -120,10 +120,26 @@
       .text( (f,i) -> i+1 )

+  getLineAngle: (x1,x2,y1,y2) ->
+    deltaX = x2 - x1
+    deltaY = y2 - y1
+    rad = Math.atan2(deltaY, deltaX)
+    deg = rad * (180 / Math.PI)
+    deg

   drawPlane: (container, points) ->
     point = _.last(points)
-    @addImage(PLANE_PATH, x: point.x+2, y: point.y-3, height: 6, width: 8)
+    pointPrev = points[points.length-2]
+    lineAngle = @getLineAngle(pointPrev.x,point.x,pointPrev.y,point.y)
+    node = @svgNode
+    d3.select(node).append('svg:image')
+      .attr('x',point.x+2)
+      .attr('y',point.y-3)
+      .attr('width', 8)
+      .attr('height', 6)
+      .attr('xlink:href', PLANE_PATH)
+      .attr("transform", "rotate(#{lineAngle},#{point.x},#{point.y})")
+

   drawHills: (container) ->
     # might be nice to move this definition up into DefaultProps


fbp-protocol: Tweak network:data and runtime:packet

--- lib/runtime.coffee
+++ lib/runtime.coffee
@@ -288,6 +288,8 @@
     if not send
         return [] # in the middle of bracketed data, will send when gets to the end

+    delete payload.type # XXX
+
     # Check if exported outport
     if graph.outports
         found = null
@@ -300,8 +302,10 @@
             payload:
                 port: found
                 event: 'data'
+                type: 'any'
+                #schema: ''
+                graph: graph.name
                 payload: data
-                index: null
         messages.push m

     # Sent network:data for edge introspection


fixed error with Timer file

fixed error with Timer file

--- src/Timer.coffee
+++ src/Timer.coffee
@@ -8,7 +8,7 @@

   timeToString = (seconds, minutes, hours) ->
     timeString = ""
-    if (hours !== undefined)
+    if (hours != undefined)
       hoursString = ""
       if (hours < 10)
         hoursString += "0" + hours
@@ -16,7 +16,7 @@
         hoursString += hours
       hoursString += ":"
       timeString += hoursString
-    if (minutes !== undefined)
+    if (minutes != undefined)
       minutesString = ""
       if (minutes < 10)
         minutesString += "0" + minutes
@@ -24,7 +24,7 @@
         minutesString += minutes
       minutesString += ":"
       timeString += minutesString
-    if (seconds !== undefined)
+    if (seconds != undefined)
       secondsString = ""
       if (seconds < 10)
         secondsString += "0" + seconds


seems still need parse after activate

seems still need parse after activate

--- lib/watcher.coffee
+++ lib/watcher.coffee
@@ -56,6 +56,9 @@
     @eventCursorMoved = on
     @eventDestroyed = on
     @eventBufferChanged = on
+
+    d 'activate and parse'
+    @parse()

   deactivate: ->
     # Stop listening


Don't automatically disable showOnStartup

--- lib/welcome.coffee
+++ lib/welcome.coffee
@@ -41,7 +41,6 @@
         @show()
         Reporter ?= require './reporter'
         Reporter.sendEvent('show-on-initial-load')
-        atom.config.set('welcome.showOnStartup', false)

   show: ->
     atom.workspace.open(WelcomeUri)


Client: Activity: Test: Deleted unused references

--- client/activity/lib/components/commentinputwidget/test/container.coffee
+++ client/activity/lib/components/commentinputwidget/test/container.coffee
@@ -1,13 +1,8 @@
 kd           = require 'kd'
 React        = require 'kd-react'
-ReactDOM     = require 'react-dom'
 expect       = require 'expect'
 Container    = require '../container'
 TestUtils    = require 'react-addons-test-utils'
-ActivityFlux = require 'activity/flux'
-immutable    = require 'immutable'
-toImmutable  = require 'app/util/toImmutable'
-mock         = require '../../../../../mocks/mockingjay'
 KeyboardKeys = require 'app/constants/keyboardKeys'


Teamwork: Handled callback non existence case.

--- client/app/Applications/Teamwork.kdapplication/Views/teamworkapp.coffee
+++ client/app/Applications/Teamwork.kdapplication/Views/teamworkapp.coffee
@@ -137,7 +137,7 @@
       content                 : @teamwork.markdownContent
       targetEl                : @teamwork.getActivePanel().headerHint

-  handleZipImportDone_: (vmController, root, folderName, path, modal, notification, url, callback) ->
+  handleZipImportDone_: (vmController, root, folderName, path, modal, notification, url, callback = noop) ->
     vmController.run "rm -rf #{root}/#{folderName} ; mv #{path}/#{folderName} #{root}", (err, res) =>
       return warn err if err
       modal.destroy()


shareddoc

shareddoc

--- client/landing/app/Applications/Chat.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Chat.kdapplication/AppController.coffee
@@ -1,59 +1,54 @@
-# class Chat12345 extends AppController
-#   constructor:()->
-#     mainViewClass = KDView
-#     mainViewClass = KD.getPageClass('Activity') if KD.getPageClass('Activity')?
-#
-#     @mainView = new mainViewClass {cssClass : "content-page" }
-#     super
-#
-#   bringToFront:()->
-#     @propagateEvent (KDEventType : 'ApplicationWantsToBeShown', globalEvent : yes), options : {}, data : @mainView
-#
-#   initAndBringToFront:(options,callback)->
-#     @bringToFront()
-#     callback()
-
-class ChatRoom
-
-
-  constructor:(options,callback)->
-
-
-  fetchRoom :({id},callback)->
-
-
-
-
-class @Chatter
+class @Chatter extends KDEventEmitter
   {mq} = bongo

   constructor:()->
-
+    @account = KD.whoami()
+    @username = @account.profile.nickname

   joinRoom:(options,callback)->

-    {id,callbacks} = options
+    {name,type,callbacks} = options

-
-    @name = "private-chat-#{__utils.getRandomNumber}"
+    name ?= __utils.getRandomNumber
+    type ?= "chat"
+    @name = "private-#{type}-#{name}"
     @room = mq.channel(@name)
-
+    console.log "creating room with #{@name}"
     if @room?
-      callback @room
+      callback null,{room:@room,name:@name,isNew:yes}
     else
-      mq.subscribe(@name)
-      @room.bind 'pusher:subscription_succeeded', ->
+      @room = mq.subscribe(@name)
+      @room.bind 'pusher:subscription_succeeded', =>
         console.log('success', arguments)
-        callback null,@room
+        callback null,{room:@room,name:@name,isNew:yes}
+      @room.bind 'client-#{type}-msg',callbacks.data
+
+  sendMsg : ({msg},callback) ->
+    @room.trigger 'client-chat-msg',{msg,username:@username,date:Date.now()}

-        room.bind 'client-chat-msg',->
-          console.log arguments
+
+class @SharedDoc extends @Chatter
+
+
+  constructor:(options)->
+    {isMaster} = options
+    @isMaster = isMaster
+    @lastScreen = ""
+    super

+
+  join :(options,callback)->

-  sendMsg : (options,callback)->
-    {msg} = options
-    @room.trigger 'client-chat-msg',msg
+    @joinRoom type:"sharedDoc",callbacks: data: @msgDidArrive,(err,res)->
+
+
+  @msgDidArrive: ({msg,username,date})->
+    @currentScreen = @dmp.patch_apply msg,@lastScreen
+    @emit "screenDidChange",@currentScreen
+
+
+


Development console.log slipped in, removed

--- src/beans.coffee
+++ src/beans.coffee
@@ -295,7 +295,6 @@
   info = loadInfo()
   paths = (path.join(pth, '**/*.coffee') for pth of info.paths)
   paths.push pth + '.{coffee,js}' for _, pth of info.hooks when pth
-  console.log paths
   withFiles "{#{paths.join()}}", (files) ->
     tryExec('docco', '"' + files.join('" "') + '"')


TAP5-2225: fix Prototype implementation

TAP5-2225: fix Prototype implementation

--- tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee
+++ tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee
@@ -883,7 +883,7 @@
 #if jquery
     value = $(element).data(attribute)
 #elseif prototype
-    value = JSON.parse($(element).readAttribute('data-' + attribute))
+    value = $(element).readAttribute('data-' + attribute)
     if value isnt null
       value = JSON.parse(value)
     else
@@ -906,10 +906,8 @@

     eventName = eventName.toLowerCase()

-#if jquery
     if element instanceof jQuery
       element = element[0];
-#endif

     if element is null
       element = document.getElementsByTagName('body')[0]


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/color.coffee
+++ src/color.coffee
@@ -2826,14 +2826,6 @@
   names.each (element) ->
     lookup[normalizeKey(element[1])] = parseHex(element[0])

-  Color.fromHue = (hue) ->
-    color = Color(0, 0, 0, 1)
-    color.hue(hue)
-    color.saturation(1)
-    color.lightness(0.5)
-
-    return color
-
   Color.random = ->
     Color(rand(256), rand(256), rand(256))


cleaning up array constructions

cleaning up array constructions

--- src/color.coffee
+++ src/color.coffee
@@ -80,9 +80,7 @@
     else if args.length == 1 && Object.isArray(args.first())
       arr = args.first()

-      rgb = arr.splice(0, 3)
-
-      rgbMap = rgb.map (channel) ->
+      rgbMap = arr.splice(0, 3).map (channel) ->
         parseFloat channel

       alpha = if arr[0]? then parseFloat arr[0] else 1.0
@@ -97,7 +95,8 @@
           parseFloat channel

         parsedColor = rgbMap.concat(parseFloat alpha)
-      else if !Object.isArray(color)
+
+    else if !Object.isArray(color)
         parsedColor = lookup[normalizeKey(color)] || parseHex(color) || parseRGB(color)
         parsedColor[3] = alpha
     else if arguments.length > 2


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/color.coffee
+++ src/color.coffee
@@ -28,6 +28,8 @@

   window.Color = (color) ->
     color ||= "rgba(0, 0, 0, 0)"
+
+    parsedColor = null

     if lookup[color.toLowerCase().replace(/ /g, "")]
       parsedColor = lookup[color.toLowerCase().replace(/ /g, "")]


Updated the header comment to include TeX in the list of languages

--- src/docco.coffee
+++ src/docco.coffee
@@ -22,7 +22,7 @@
 #
 #     sudo npm install docco
 #
-# Docco can be used to process CoffeeScript, JavaScript, Ruby or Python files.
+# Docco can be used to process CoffeeScript, JavaScript, Ruby, Python, or TeX files.
 # Only single-line comments are processed -- block comments are ignored.
 #
 #### Partners in Crime:


ensure input is always a valid string

ensure input is always a valid string

--- src/giphy.coffee
+++ src/giphy.coffee
@@ -88,7 +88,7 @@
     if msg
       state = {
         msg: msg
-        input: msg.match[1]
+        input: msg.match[1] or ''
         endpoint: undefined
         args: undefined
         options: undefined


Update FileHandler.coffee

Update FileHandler.coffee

Restoring error check.

--- services/filestore/app/coffee/FileHandler.coffee
+++ services/filestore/app/coffee/FileHandler.coffee
@@ -12,6 +12,7 @@
 	insertFile: (bucket, key, stream, callback)->
 		convetedKey = KeyBuilder.getConvertedFolderKey(key)
 		PersistorManager.deleteDirectory bucket, convetedKey, (error) ->
+			return callback(error) if error?
 			PersistorManager.sendStream bucket, key, stream, callback

 	deleteFile: (bucket, key, callback)->


fix event id parsing to allow for dashes in keys

--- services/real-time/app/coffee/EventLogger.coffee
+++ services/real-time/app/coffee/EventLogger.coffee
@@ -14,8 +14,9 @@

 	checkEventOrder: (channel, message_id, message) ->
 		return if typeof(message_id) isnt 'string'
-		[key, count] = message_id.split("-", 2)
-		count = parseInt(count, 10)
+		return if !(result = message_id.match(/^(.*)-(\d+)$/))
+		key = result[1]
+		count = parseInt(result[2], 0)
 		if !(count >= 0)# ignore checks if counter is not present
 			return
 		# store the last count in a hash for each host


editInPlace of "title" and "description"

--- source/javascripts/src/view_xlformbuilder.coffee
+++ source/javascripts/src/view_xlformbuilder.coffee
@@ -82,7 +82,8 @@
   render: ()->
     @$el.html """

-
#{@survey.settings.get("form_title")}

+

+

@@ -99,6 +100,17 @@
     @formEditorEl = @$(".-form-editor")

     addOpts      = @$("#additional-options")
+
+    # watch for changes on the title and description
+    for _s in ["form_title", "description"]
+      do (setting=_s)=>
+        elem = @$(".#{setting}")
+        elem.html es  if (es = @survey.settings.get(setting))
+        eip =
+          callback: (u, ent)=>
+            @survey.settings.set setting, ent
+            ent
+        elem.editInPlace eip

     @survey.rows.trigger("reset")


Clear batch enrollment and beta text fields upon button click

--- lms/static/coffee/src/instructor_dashboard/membership.coffee
+++ lms/static/coffee/src/instructor_dashboard/membership.coffee
@@ -202,13 +202,22 @@
         success: (data) => @display_response data
         error: std_ajax_err => @fail_with_error gettext "Error adding/removing users as beta testers."

+  # clear the input text field
+  clear_input: ->
+    @$emails_input.val ''
+    # default for the checkboxes should be checked
+    @$checkbox_emailstudents.attr('checked', true)
+    @$checkbox_autoenroll.attr('checked', true)
+
   fail_with_error: (msg) ->
     console.warn msg
+    @clear_input()
     @$task_response.empty()
     @$request_response_error.empty()
     @$request_response_error.text msg

   display_response: (data_from_server) ->
+    @clear_input()
     @$task_response.empty()
     @$request_response_error.empty()
     errors = []
@@ -284,13 +293,22 @@
         error: std_ajax_err => @fail_with_error gettext "Error enrolling/unenrolling users."

+  # clear the input text field
+  clear_input: ->
+    @$emails_input.val ''
+    # default for the checkboxes should be checked
+    @$checkbox_emailstudents.attr('checked', true)
+    @$checkbox_autoenroll.attr('checked', true)
+
   fail_with_error: (msg) ->
     console.warn msg
+    @clear_input()
     @$task_response.empty()
     @$request_response_error.empty()
     @$request_response_error.text msg

   display_response: (data_from_server) ->
+    @clear_input()
     @$task_response.empty()
     @$request_response_error.empty()


Scenario 23. added

Scenario 23. added

Scenario 23. one attribute in the parent tag with space at the
beginning and at the end

--- test/scenario-based-testing.coffee
+++ test/scenario-based-testing.coffee
@@ -244,4 +244,14 @@
     # console.log output
     expectedOutput = fs.readFileSync './test/scenarios/scenario-22-expected.html', 'utf8'
     # console.log expectedOutput
+    expect(output).to.equal(expectedOutput)
+
+  it 'Scenario 23. one attribute in the parent tag with space at the beginning and at the end', ->
+
+    input = fs.readFileSync './test/scenarios/scenario-23-input.cohtml', 'utf8'
+    # console.log input
+    output = toHtml5 input
+    # console.log output
+    expectedOutput = fs.readFileSync './test/scenarios/scenario-23-expected.html', 'utf8'
+    # console.log expectedOutput
     expect(output).to.equal(expectedOutput)


Defer after clicking toolbar

Defer after clicking toolbar

--- test/src/formatting_helpers.coffee
+++ test/src/formatting_helpers.coffee
@@ -9,7 +9,7 @@
 @clickToolbarDialogButton = ({method}, callback) ->
   button = document.querySelector("#toolbar .dialog input[type=button][data-method='#{method}']")
   triggerEvent(button, "click")
-  callback()
+  defer(callback)

 @isToolbarButtonActive = (selector) ->
   button = getToolbarButton(selector)


client: remove the most stupid comments

client: remove the most stupid comments

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/app/lib/index.coffee
+++ client/app/lib/index.coffee
@@ -1,4 +1,3 @@
-# Make sure none of these modules are calling remote#getInstance before this file. -og
 globals                = require 'globals'
 kookies                = require 'kookies'
 kd                     = require 'kd'
@@ -57,15 +56,6 @@

   MainController = require './maincontroller'
   Status = require './status'
-
-  # Dear sir, madam, or dolphin,
-  # `Status` & `MainController` have these `registerSingleton` calls.
-  # Since (at the moment) there is no easy way to track what singletons
-  # we have defined or undefined; we should try to keep those calls
-  # within a single space, preferably in entry point (this file).
-  # That is to say, if you have registered a singleton in somewhere else,
-  # and that file is not a direct dependency of this file, you are most
-  # probably causing harm to sea lions and sea turtles. -og

   status         = new Status
   mainController = new MainController


Update cardData.coffee

Update cardData.coffee

--- client/data/cardData.coffee
+++ client/data/cardData.coffee
@@ -18,7 +18,7 @@
 #  img: 'svg'
 #  description: 'Check up on your baby from afar'
 #  url:
-#    github: 'https://github.com/grant/herder'
+#    github: 'https://github.com/grant/herder.co'
 #,
 #  id: 'herder'
 #  title: 'Herder'


Update mimosa-config.coffee

Update mimosa-config.coffee

--- client/mimosa-config.coffee
+++ client/mimosa-config.coffee
@@ -5,9 +5,9 @@
     'require'
     'minify'
     'bower'
-    'require-lint'
-    'mimosa-jshint'
-    'mimosa-csslint'
+    #'require-lint'
+    #'mimosa-jshint'
+    #'mimosa-csslint'
     'mimosa-karma-enterprise'
   ]
   server:


Deleted unused classname

Deleted unused classname

--- core/app/backbone/views/facts/react_fact_vote_area.coffee
+++ core/app/backbone/views/facts/react_fact_vote_area.coffee
@@ -99,6 +99,6 @@
         type: 'disbelieves'

   render: ->
-    _div ['fact-vote-area'],
+    _div [''],
       @_voting()
       @_voters()


maximum dropdown height fix

maximum dropdown height fix

--- coffee/chosen.jquery.coffee
+++ coffee/chosen.jquery.coffee
@@ -256,13 +256,12 @@
     @search_results.css("maxHeight", "240px")

     # Fix maximum size
-    dropdownBottom = @dropdown.position().top + @dropdown.height()
-    windowHeight = $(window).height()
-
-    if dropdownBottom > windowHeight
-      maxHeight = @dropdown.height() - (dropdownBottom  - windowHeight)
-      @dropdown.css("maxHeight", maxHeight + "px")
-      @search_results.css("maxHeight", (maxHeight - @search_container.height() - 10) + "px")
+    realDropdownTop = @dropdown.offset().top - $(window).scrollTop()
+    maxHeight = $(window).height() - realDropdownTop
+    maxHeight = 240 if maxHeight > 240
+    maxHeight = 100 if maxHeight < 100
+    @dropdown.css("maxHeight", maxHeight + "px")
+    @search_results.css("maxHeight", ( maxHeight - @search_container.height() - 10 ) + "px")

     @results_showing = true


fix(storage): display no error image

fix(storage): display no error image

--- coffee/zeno-services.coffee
+++ coffee/zeno-services.coffee
@@ -84,6 +84,9 @@

         if @percentage == '0.00'
           success = true
+          a = angular.element('<a href="#/result/' + f1 + '/' + f2 + '"/>')
+          @block.append a    # add link
+          a.append diffBlock # add image
         else
           success = false


Revert "One more try with the slack markdown"

This reverts commit c1bfd3a10646b6d45caf3eaa323e9c844e61554e.

--- scripts/pudding.coffee
+++ scripts/pudding.coffee
@@ -183,16 +183,16 @@
       defaults.envs.map (env) ->
         fields.push
           title: "#{site} #{env}"
-          text: format_instance_totals_in_site_env(site, env, instances)
+          value: format_instance_totals_in_site_env(site, env, instances)
           short: true
-          mrkdwn_in: ['title', 'text']
+          mrkdwn_in: ['title', 'value', 'text']

     payload =
       message: msg.message
       content:
         text: ''
         fallback: 'Instances'
-        pretext: "All _#{default_role}_ instances"
+        pretext: "All #{default_role} instances"
         color: '#77cc77'
         fields: fields
         mrkdwn_in: ['fallback', 'pretext']
@@ -205,7 +205,7 @@
   resp = ''
   Object.keys(totals).map (instance_type) ->
     capacity = (defaults.counts[instance_type] || 0) * totals[instance_type]
-    resp += "#{instance_type}: *#{totals[instance_type]}* (capacity *#{capacity}*)"
+    resp += "#{instance_type}: #{totals[instance_type]} (capacity #{capacity})"
   resp

 get_instance_totals_in_site_env = (site, env, instances) ->


Change clearing technique until a bug is resolved. https://github.com/argerim/select2-rails/issues/38

--- app/assets/javascripts/admin/suppliers_code.js.coffee
+++ app/assets/javascripts/admin/suppliers_code.js.coffee
@@ -59,7 +59,8 @@

     # Reset fields
     $fieldset.data("sku", "").data("name", "").data("qty", 0)
-    $fieldset.find('.variant_autocomplete').select2('data', null)
+    # $fieldset.find('.variant_autocomplete').select2('data', null)
+    $fieldset.find('.variant_autocomplete').select2('data', {})

     return false


grab the correct location from the hash

grab the correct location from the hash

--- app/assets/javascripts/components/subject-viewer.cjsx
+++ app/assets/javascripts/components/subject-viewer.cjsx
@@ -18,7 +18,7 @@
     # console.log 'USING ENDPOINT: ', @props.endpoint
     imageWidth: 0
     imageHeight: 0
-
+
     subjectEndpoint: @props.endpoint
     subjects: null
     subject: null
@@ -47,18 +47,18 @@
       windowInnerHeight: window.innerHeight

   fetchSubjects: ->
+
     $.ajax
       url: @state.subjectEndpoint
       dataType: "json"
       success: ((data) ->
         # DEBUG CODE
         # console.log 'FETCHED SUBJECTS: ', data
-
         @setState
           subjects: data
           subject: data[0], =>
             @state.classification = new Classification @state.subject
-            @loadImage @state.subject.location
+            @loadImage @state.subject.location.standard

         # console.log 'Fetched Images.' # DEBUG CODE

@@ -103,7 +103,7 @@
       return
     else
       @setState subject: @state.subjects[0], =>
-        @loadImage ((if @usingFakeSubject() then @state.subject.classification.subject.location else @state.subject.location))
+        @loadImage ((if @usingFakeSubject() then @state.subject.classification.subject.location.standard else @state.subject.location.standard))

     @state.classification = new Classification @state.subject

@@ -113,13 +113,13 @@
     console.log 'handleInitStart() '
     { ex, ey } = @getEventOffset e
     marks = @state.marks
-    newMark =
+    newMark =
       key: @state.lastMarkKey
       x: ex
       y: ey
       timestamp: (new Date).toJSON()
     marks.push newMark
-    @setState
+    @setState
       marks: marks
       lastMarkKey: @state.lastMarkKey + 1
       selectedMark: marks[marks.length-1]
@@ -140,10 +140,10 @@
       mark.y = @state.imageHeight
     else if ey < 0
       mark.y = 0
-
+
     @setState selectedMark: mark
       # , => @forceUpdate()
-
+
   # AVAILABLE, BUT UNUSED, METHODS
   # handleInitRelease: (e) ->
   # handleToolMouseDown: (e) ->
@@ -167,7 +167,7 @@
     marks = @state.marks
     for mark, i in [ marks...]
       if mark.key is key
-        marks.splice(i,1) # delete marks[key]
+        marks.splice(i,1) # delete marks[key]
     @setState
       marks: marks
       selectedMark: null, =>
@@ -180,7 +180,7 @@
       clickOffset:
         x: mark.x - ex
         y: mark.y - ey
-      # , => @forceUpdate()
+      # , => @forceUpdate()

   render: ->
     # console.log 'render()'
@@ -190,7 +190,7 @@
     if @state.loading
       markingSurfaceContent = <LoadingIndicator />
     else
-      markingSurfaceContent =
+      markingSurfaceContent =
         <svg
           className = "subject-viewer-svg"
           width = {@state.imageWidth}
@@ -213,14 +213,14 @@
           </Draggable>

           { @state.marks.map ((mark, i) ->
-              <ToolComponent
-                key={i}
-                mark={mark}
+              <ToolComponent
+                key={i}
+                mark={mark}
                 subject={@state.subject}
                 workflow={@props.workflow}
-                getEventOffset={@getEventOffset}
-                isSelected={mark is @state.selectedMark}
-                handleMarkClick={@handleMarkClick.bind null, mark}
+                getEventOffset={@getEventOffset}
+                isSelected={mark is @state.selectedMark}
+                handleMarkClick={@handleMarkClick.bind null, mark}
                 onClickDelete={@onClickDelete}
                 clickOffset={@state.clickOffset}
                 imageWidth={@state.imageWidth}


一度保存したあとは「上書きしますか？」を聞かないように修正

一度保存したあとは「上書きしますか？」を聞かないように修正

--- app/assets/javascripts/views/main_menu_view.js.coffee
+++ app/assets/javascripts/views/main_menu_view.js.coffee
@@ -65,6 +65,8 @@
         sourceCode.write()
           .done (data) ->
             afterSave = ->
+              Smalruby.savedFilename = sourceCode.get('filename')
+              window.changed = false
               sourceCode.check()
                 .done (data) ->
                   if data.length > 0
@@ -92,7 +94,8 @@
                 .fail -> failedFunc()

             if data.source_code.error
-              if confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか？\nセーブすると前に作成したプログラムは消えてしまうよ！")
+              if sourceCode.get('filename') == Smalruby.savedFilename ||
+                 confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか？\nセーブすると前に作成したプログラムは消えてしまうよ！")
                 sourceCode.write(true)
                   .done (data) ->
                     afterSave()
@@ -173,11 +176,13 @@
           .done (data) ->
             afterSave = ->
               $.unblockUI()
+              Smalruby.savedFilename = sourceCode.get('filename')
               window.changed = false
               window.successMessage('セーブしました')

             if data.source_code.error
-              if confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか？\nセーブすると前に作成したプログラムは消えてしまうよ！")
+              if sourceCode.get('filename') == Smalruby.savedFilename ||
+                 confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか？\nセーブすると前に作成したプログラムは消えてしまうよ！")
                 sourceCode.write(true)
                   .done (data) ->
                     afterSave()


Log std output errors

Log std output errors

--- components/SCDDetect.coffee
+++ components/SCDDetect.coffee
@@ -31,6 +31,9 @@
 onEnd = (tmpFile, cascade, callback) ->
   bin = path.join __dirname, '../build/Release/scddetect'
   exec "#{bin} #{tmpFile.path} #{cascade}", (err, stdout, stderr) ->
+    console.log 'stdout', stdout
+    console.log 'stderr', stderr
+    console.log 'err', err
     if err
       callback err
       tmpFile.unlink()


create a closed area (border)

create a closed area (border)

--- src/webapp/_scripts/r7/assetsLoader.coffee
+++ src/webapp/_scripts/r7/assetsLoader.coffee
@@ -18,7 +18,7 @@
   _area02 = {
     width : 16 #nbcell
     height : 9 #nbcell
-    cellr : 7
+    cellr : 10
     walls : {
       cells : [1,2,0,4] #cellunit [x0,y0,w0,h0, x1,y1,....]
     }
@@ -73,10 +73,10 @@
         body.shapes.push(shape)
       body
     addBorderAsCells = (w, h, cells) ->
-      cells.push(0, 0, w, 0)
-      cells.push(0, 0, 0, h)
-      cells.push(w, 0, 0, h)
-      cells.push(0, h, w, 0)
+      cells.push(-1, -1, w+2, 1)
+      cells.push(-1, -1, 1, h+2)
+      cells.push(w, -1, 1, h+2)
+      cells.push(-1, h, w+2, 1)
     addBorderAsCells(area.width, area.height, area.walls.cells)
     area.walls.obj3d = () -> cells2boxes3d(area.walls.cells, area.width / -2, area.height/-2)
     area.walls.obj2d = () -> cells2boxes2d(area.walls.cells, area.width / -2, area.height/-2)


return updated object after update

return updated object after update

--- server/common/dal/sql.coffee
+++ server/common/dal/sql.coffee
@@ -80,7 +80,13 @@
         @query += separator + ' ' + key + '=' + value
         separator = ','
     @query += ' WHERE ' + @idColumn + ' = ' + id
-    @exec cb
+    @exec (err, obj) =>
+      if err
+        cb err, obj
+      else
+        query = {}
+        query[@idColumn] = id
+        @findOne query, cb

   remove: (query, cb) ->
     @returnArray = false


update

update

--- src/index.coffee
+++ src/index.coffee
@@ -76,7 +76,6 @@

 			# Now check if animation is the one you are looking for
 			if eventAnimationName == animationName
-				console.log 'success'
 				success(e)

 		handleObj.data.ns = ns = ".#{handleObj.guid}"


Corrected where connection cleanup is performed.

--- src/index.coffee
+++ src/index.coffee
@@ -76,6 +76,7 @@
 runQueries = (config, queries) ->
   uri = "postgres://#{config.username}:#{config.password}@#{config.host}:#{config.port}/#{config.database}"
   console.log "Connecting to URI '#{uri}'"
+
   pgConnect uri
   .then (context) ->
     context.watch = durations.stopwatch().start()
@@ -83,10 +84,11 @@
     runQuery context.client, queries
     .then ->
       return context
-  .then (context) ->
-    context.watch.stop()
-    console.log "Wrapping up connection. All queries took #{context.watch}"
-    context.done()
+    .then (context) ->
+      context.watch.stop()
+      console.log "Wrapping up connection. All queries took #{context.watch}"
+    .finally ->
+      context.done()
   .catch (error) ->
     console.log "Error running queries: #{error}\nStack:\n#{error.stack}"


Interleave downloading and scoring posts

--- src/index.coffee
+++ src/index.coffee
@@ -45,47 +45,6 @@
         body: body
       cache.set(key, JSON.stringify(entry))
       callback null, body
-
-sortPosts = (db, client, agentID, posts, user, token, callback) ->
-  assert.ok _.isObject(db), "#{db} is not an object"
-  assert.ok _.isObject(client), "#{client} is not an object"
-  assert.ok _.isString(agentID), "#{agentID} is not a string"
-  assert.ok _.isArray(posts), "#{posts} is not an array"
-  assert.ok _.isObject(user), "#{user} is not an object"
-  assert.ok _.isString(token), "#{token} is not a string"
-
-  async.waterfall [
-    (callback) ->
-      db.read "UserFollowing", user.id, (err, following) ->
-        if err and err.name == "NoSuchThingError"
-          callback null, []
-        else if err
-          callback err
-        else
-          callback null, following
-    (followings, callback) ->
-      scorePost = (post, callback) ->
-        inputs =
-          relatedPostUpvotes: _.filter(post.related_posts, (related) -> related?.current_user?.voted_for_post).length
-          relatedPostComments: _.filter(post.related_posts, (related) -> related?.current_user?.commented_on_post).length
-          followingHunters: _.filter([post.user], (user) -> followings.indexOf(user.id) != -1).length
-          followingUpvotes: _.filter(post.votes, (vote) -> followings.indexOf(vote.user_id) != -1).length
-          followingComments: 0
-          totalUpvotes: post.votes_count
-          totalComments: post.comments_count
-        client.evaluate agentID, inputs, (err, outputs) ->
-          if err
-            callback err
-          else
-            post.score = outputs.score
-            callback null, post
-      async.mapLimit posts, 16, scorePost, (err, scored) ->
-        if err
-          callback err
-        else
-          scored = _.sortByOrder scored, ["score"], [false]
-          callback null, scored
-  ], callback

 defaultAgent =
   inputs:
@@ -191,21 +150,55 @@
     start = last = Date.now()
     async.waterfall [
       (callback) ->
-        token = req.token
-        headers =
-          "Accept": JSON_TYPE
-          "Authorization": "Bearer #{token}"
-        url = "https://api.producthunt.com/v1/posts"
-        cacheGet url, token, headers, (err, body) ->
-          if err
-            callback err
-          else
-            results = JSON.parse(body)
-            now = Date.now()
-            console.log "#{now - start} (#{now - last}) to get posts"
-            last = now
-            callback null, results.posts
-      (posts, callback) ->
+        async.parallel [
+          (callback) ->
+            req.app.db.read "UserFollowing", req.user.id, (err, following) ->
+              if err and err.name == "NoSuchThingError"
+                callback null, []
+              else if err
+                callback err
+              else
+                callback null, following
+          (callback) ->
+            token = req.token
+            headers =
+              "Accept": JSON_TYPE
+              "Authorization": "Bearer #{token}"
+            url = "https://api.producthunt.com/v1/posts"
+            cacheGet url, token, headers, (err, body) ->
+              if err
+                callback err
+              else
+                results = JSON.parse(body)
+                now = Date.now()
+                console.log "#{now - start} (#{now - last}) to get posts"
+                last = now
+                callback null, results.posts
+        ], callback
+      (results, callback) ->
+        [followings, posts] = results
+        downloadAndScore = (post, callback) ->
+          async.waterfall [
+            (callback) ->
+              downloadFullPost post, callback
+            (fullPost, callback) ->
+              scorePost fullPost, callback
+          ], callback
+        scorePost = (post, callback) ->
+          inputs =
+            relatedPostUpvotes: _.filter(post.related_posts, (related) -> related?.current_user?.voted_for_post).length
+            relatedPostComments: _.filter(post.related_posts, (related) -> related?.current_user?.commented_on_post).length
+            followingHunters: _.filter([post.user], (user) -> followings.indexOf(user.id) != -1).length
+            followingUpvotes: _.filter(post.votes, (vote) -> followings.indexOf(vote.user_id) != -1).length
+            followingComments: 0
+            totalUpvotes: post.votes_count
+            totalComments: post.comments_count
+          req.app.fuzzyIO.evaluate req.agent, inputs, (err, outputs) ->
+            if err
+              callback err
+            else
+              post.score = outputs.score
+              callback null, post
         downloadFullPost = (post, callback) ->
           token = req.token
           headers =
@@ -218,20 +211,16 @@
             else
               results = JSON.parse(body)
               callback null, results.post
-        async.map posts, downloadFullPost, callback
-      (posts, callback) ->
-        now = Date.now()
-        console.log "#{now - start} (#{now - last}) to get full posts"
-        last = now
-        sortPosts req.app.db, req.app.fuzzyIO, req.agent, posts, req.user, req.token, callback
-    ], (err, posts) ->
+        async.map posts, downloadAndScore, callback
+    ], (err, scored) ->
       if err
         next err
       else
+        scored = _.sortByOrder scored, ["score"], [false]
         now = Date.now()
-        console.log "#{now - start} (#{now - last}) to sort posts"
+        console.log "#{now - start} (#{now - last}) to download and sort posts"
         last = now
-        res.json posts
+        res.json scored

 router.get '/about', (req, res, next) ->
   res.render 'about', title: 'About'


Use findOne instead of _list

Use findOne instead of _list

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

--- src/items.coffee
+++ src/items.coffee
@@ -39,7 +39,7 @@
   getRecipe: ->
     recipe = []
     for x in @recipe
-      recipe.push lol.items._list[x]
+      recipe.push lol.items.findOne[x]
     return recipe

   getTotalCost: ->


Cycle the cyclones

Cycle the cyclones


Add log source

Add log source

--- chrome/src/gmailr.coffee
+++ chrome/src/gmailr.coffee
@@ -62,6 +62,7 @@

   # Utility methods
   dbg = (args...) ->
+    args.unshift '[Gmailr]'
     console.log.apply console, args if console?.log and Gmailr.debug is true
     return


Comment some notices

Comment some notices

--- gulp/production/index.coffee
+++ gulp/production/index.coffee
@@ -1,4 +1,4 @@
 # Todo:
-- Minify Files
-- Deploy in 'builds/#{timestamp}'-folder (so we've a history of builds and can rollback)
-- +# - Minify Files
+# - Deploy in 'builds/#{timestamp}'-folder (so we've a history of builds and can rollback)
+# -


one more range literal expansion test

one more range literal expansion test

--- test/test_ranges_slices_and_splices.coffee
+++ test/test_ranges_slices_and_splices.coffee
@@ -30,6 +30,9 @@
 array = [(1+5)..1+9]
 ok array.join(' ') is "6 7 8 9 10"

+array = [5..1]
+ok array.join(' ') is '5 4 3 2 1'
+

 # String slicing (at least on Node).
 hello = "Hello World"


Delay graph initialization until we have data

--- widgets/bar_graph/bar_graph.coffee
+++ widgets/bar_graph/bar_graph.coffee
@@ -2,37 +2,38 @@
   @accessor 'current', ->

   ready: ->
-    container = $(@node).parent()
-    # Gross hacks. Let's fix this.
-    width = (Dashing.widget_base_dimensions[0] * container.data("sizex")) + Dashing.widget_margins[0] * 2 * (container.data("sizex") - 1)
-    height = (Dashing.widget_base_dimensions[1] * container.data("sizey"))
+    @container = $(@node).parent()
+    this._initializeGraph(@get('items')) if @get('items')

-    @names = @get('items')
-    data = this._data(@get('items'))
+  onData: (data) ->
+    if data.items && @graph
+      $(data.items).each (i, item) =>
+        @graph.series[0].data[i].y = item.count
+      @graph.render()
+    else if data.items && !@graph
+      this._initializeGraph(data.items)
+
+  _initializeGraph: (items) =>
+    @names = items
+    data = this._data(items)

     @graph = new Rickshaw.Graph(
       element: @node
       renderer: 'bar'
-      width: width
-      height: height
+      width: @_width()
+      height: @_height()
       series: [data]
     )

-    x_axis = new Rickshaw.Graph.Axis.X(
-      graph: @graph
-      orientation: 'bottom'
-      tickFormat: this._format
-    )
+    # x_axis = new Rickshaw.Graph.Axis.X(
+    #   graph: @graph
+    #   orientation: 'bottom'
+    #   tickFormat: this._format
+    # )

     @graph.renderer.unstack = true

     @graph.render()
-
-  onData: (data) ->
-    if data.items
-      $(data.items).each (i, item) =>
-        @graph.series[0].data[i].y = item.count
-      @graph.render()

   _data: (items) ->
     color: '#fff'
@@ -42,3 +43,9 @@
   _format: (n) =>
     console.debug n
     @names[n].name
+
+  _width: =>
+    (Dashing.widget_base_dimensions[0] * @container.data("sizex")) +
+     Dashing.widget_margins[0] * 2 * (@container.data("sizex") - 1)
+  _height: =>
+    (Dashing.widget_base_dimensions[1] * @container.data("sizey"))


Log all events via GeordiLogger.logEvent() Otherwise, makeHandler ignores remembered event data.

--- app/partials/app.cjsx
+++ app/partials/app.cjsx
@@ -27,13 +27,11 @@
       subjectGetter: () => @keys?.subjectID

   makeHandler: (defType) -> # Once defined, efficiently logs different data to same event type
-    instance = @instance
-    (eventData, eventType) ->
+    (eventData, eventType) =>
         eventType = defType if typeof eventType isnt 'string'
-        if GeordiLogger.tokens.indexOf(instance().projectToken) > -1
-          instance()?.logEvent
-            type: eventType
-            data: "\"#{eventData}\""
+        @logEvent
+          type: eventType
+          data: "\"#{eventData}\""

   logEvent: (logEntry) -> # Accepts key/values to make appropriate Geordi logging
     newEntry = Object.assign {}, logEntry, @keys


CLI prettifying the 'help' command output

--- cli/commands/help.coffee
+++ cli/commands/help.coffee
@@ -8,6 +8,24 @@
 commands_list = ->
   require('fs').readdirSync(__dirname).map (file) ->
     file.split('.')[0]
+
+# returns the commands list in a batches of given length
+commands_list_in_batches = (length)->
+  separator = ', '
+  batches   = []
+  batch     = []
+  commands  = commands_list()
+  commands.sort()
+
+  for name in commands
+    if batch.join(separator).length > length
+      batches.push(batch.join(separator))
+      batch = []
+
+    batch.push(name)
+
+  batches.push(batch.join(separator))
+  batches

 # kicks in the command
@@ -26,7 +44,7 @@
   Usage: lovely <command>

   Where <command> is one of:
-      #{commands_list().join(', ')}
+      #{commands_list_in_batches(60).join("\n    ")}

   Help usage: lovely help <command>


Update maker.coffee

Update maker.coffee

removed uneded comment.

--- src/maker.coffee
+++ src/maker.coffee
@@ -1,5 +1,3 @@
-# Este archivo será evenualmente vendoreado solamente para correr pruebas de
-# Jasmine.

 Maker =
   define: (name, model = Object) ->


:art: Add minimap bookmark in marker specs


:fire: errant log

:fire: errant log

--- spec/git-repository-async-spec.coffee
+++ spec/git-repository-async-spec.coffee
@@ -364,7 +364,6 @@
         waitsFor ->
           statusHandler.callCount >= 1
         runs ->
-          console.log "in run block"
           expect(statusHandler.callCount).toBe 1
           expect(statusHandler).toHaveBeenCalledWith {path: editor.getPath(), pathStatus: 256}