config: fix template url

config: fix template url

--- config/main.prod.coffee
+++ config/main.prod.coffee
@@ -29,7 +29,7 @@
   mq                  = { host:     "#{rabbitmq.host}"                               , port:               rabbitmq.port                         , apiAddress:      "#{rabbitmq.host}"     , apiPort:         "#{rabbitmq.apiPort}"                , login:    "#{rabbitmq.login}"    , componentUser: "#{rabbitmq.login}"                                   , password:       "#{rabbitmq.password}"                                , heartbeat:       0           , vhost:        "#{rabbitmq.vhost}" }
   customDomain        = { public:   "https://#{hostname}"                            , public_:            "#{hostname}"                         , local:           "http://localhost"     , local_:          "localhost"                          , port:     80                   }
   sendgrid            = { username: "koding"                                         , password:           "DEQl7_Dr"                          }
-  email               = { host:     "#{customDomain.public_}"                        , protocol:           'https:'                              , defaultFromMail: 'hello@koding.com'     , defaultFromName: 'koding'                             , username: sendgrid.username      , password:      sendgrid.password                                     , templateRoot:   "#{projectRoot}}/go/src/socialapi/workers/emailnotifier/templates/"  , forcedRecipient: undefined }
+  email               = { host:     "#{customDomain.public_}"                        , protocol:           'https:'                              , defaultFromMail: 'hello@koding.com'     , defaultFromName: 'koding'                             , username: sendgrid.username      , password:      sendgrid.password                                     , templateRoot:   "#{projectRoot}/go/src/socialapi/workers/emailnotifier/templates/"  , forcedRecipient: undefined }
   kontrol             = { url:      "#{options.publicHostname}/kontrol/kite"         , port:               4000                                  , useTLS:          no                     , certFile:        ""                                   , keyFile:  ""                     , publicKeyFile: "#{projectRoot}/certs/test_kontrol_rsa_public.pem"    , privateKeyFile: "#{projectRoot}/certs/test_kontrol_rsa_private.pem" }
   broker              = { name:     "broker"                                         , serviceGenericName: "broker"                              , ip:              ""                     , webProtocol:     "https:"                             , host:     customDomain.public    , port:          8008                                                  , certFile:       ""                                                    , keyFile:         ""          , authExchange: "auth"                , authAllExchange: "authAll" , failoverUri: customDomain.public }
   regions             = { kodingme: "#{configName}"                                  , vagrant:            "vagrant"                             , sj:              "sj"                   , aws:             "aws"                                , premium:  "vagrant"            }


moved test data for /nodes into test function

Signed-off-by: Dominik Richter <b7323add517e187efe0283b76511b7ed762bfe13@gmail.com>

--- test/spec/controllers/main.coffee
+++ test/spec/controllers/main.coffee
@@ -19,13 +19,6 @@
     @typeOf = (obj) ->
       ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()

-    @nodes = [
-      { 'id': 'my1.full.fqdn' },
-      { 'id': 'my2.full.fqdn' }
-    ]
-
-    @httpBackend.whenGET("/v1/nodes").respond(@nodes);
-
     MainCtrl = $controller('MainCtrl', {
       $scope: scope,
       Restangular: @Restangular
@@ -40,6 +33,11 @@
     expect(scope.ponyExpressHost).toBe('127.0.0.1')

   it 'should be able to list /nodes', () ->
+    nodes = [
+      { 'id': 'my1.full.fqdn' },
+      { 'id': 'my2.full.fqdn' }
+    ]
+    @httpBackend.whenGET('/v1/nodes').respond(nodes);
     @httpBackend.expectGET('/v1/nodes')
     scope.fetch()
     @httpBackend.flush()
@@ -48,7 +46,7 @@
     # test both nodes
     for idx in [0,1]
       expect(@typeOf(scope.nodes[idx])).toBe('object')
-      expect(scope.nodes[idx]['id']).toBe(@nodes[idx]['id'])
+      expect(scope.nodes[idx]['id']).toBe(nodes[idx]['id'])

   it 'should be able to access /node/xyz info (empty node)', () ->
     id = 'test'


fixed potential call stack exceed error

fixed potential call stack exceed error

--- src/lib/faction.coffee
+++ src/lib/faction.coffee
@@ -68,7 +68,8 @@

         next = ->

-            cursor.nextObject p
+            setImmediate ->
+                cursor.nextObject p

         finish = ->


Implement Renderer.App#onDidLogin

Implement Renderer.App#onDidLogin

--- src/renderer/scripts/app/App.coffee
+++ src/renderer/scripts/app/App.coffee
@@ -93,6 +93,7 @@
                 @_session?.relogin()
                 .then =>
                     console.info "%cRelogin successful.", Colors.text.info
+                    @emit "did-login", @_session
                     app.command.dispatch "channel:reset-session", @_session
                     return

@@ -107,7 +108,8 @@
                     @_session = session
                     @_saveSession()

-                    app.command.dispatch "channel:reset-session", session
+                    @emit "did-login", @_session
+                    app.command.dispatch "channel:reset-session", @_session
                     callback()

                 .catch (e) =>
@@ -145,7 +147,7 @@
             else
                 @_session = restoredSession
                 app.command.dispatch "channel:reset-session", @_session
-
+                @emit "did-login", @_session
                 console.info "%c[app.restoredSession] Session restored!", Colors.text.success
         #
         # .catch (e) =>
@@ -179,3 +181,6 @@

     onDidChangeChannel : (listener) ->
         @on "did-change-channel", listener
+
+    onDidLogin : (listener) ->
+        @on "did-login", listener


feat(core): add mobile link

feat(core): add mobile link

--- scripts/gitter-activity-notifier.coffee
+++ scripts/gitter-activity-notifier.coffee
@@ -304,6 +304,7 @@
                                     | Dev Builds                      | Prod Builds                     |
                                     | ------------------------------- | ------------------------------- |
                                     | [index-one.html](%6$s/dev/samples/index-one.html)    | [index-one.html](%6$s/prod/samples/index-one.html)    |
+                                    | [index-mobile.html](%6$s/dev/samples/index-mobile.html)    | [index-mobile.html](%6$s/prod/samples/index-mobile.html)    |
                                     | [index-fgp-en.html](%6$s/dev/samples/index-fgp-en.html) | [index-fgp-en.html](%6$s/prod/samples/index-fgp-en.html) |
                                     | [index-fgp-fr.html](%6$s/dev/samples/index-fgp-fr.html) | [index-fgp-fr.html](%6$s/prod/samples/index-fgp-fr.html) |


fix blank messages being sent by glitch

fix blank messages being sent by glitch

--- scripts/gitter-activity-notifier.coffee
+++ scripts/gitter-activity-notifier.coffee
@@ -8,9 +8,9 @@
 glitchpy = require( path.resolve( __dirname, "./glitch-py.js" ) )(process.env.HUBOT_PR_TOKEN)

 notificationRoom = process.env.GITTER_ACTIVITY_TARGET;
-disabledIssueActions = ['pinned', 'unpinned', 'locked', 'unlocked', 'milestoned', 'demilestoned'];
-validLabels = ['priority: low', 'priority: medium', 'priority: high', 'priority: urgent'];
-noCheck = ['muffin-crusaders/glitch', 'muffin-crusaders/hubot-scrumminator', 'muffin-crusaders/static-website-blob-browser', 'muffin-crusaders/hubot-azure-scripts', 'muffin-crusaders/angularjs-styleguide-snippets-es6', '/muffin-crusaders/hubot-gitter2'];
+disabledIssueActions = ["pinned", "unpinned", "locked", "unlocked", "milestoned", "demilestoned", "labeled", "unlabeled"];
+validLabels = ["priority: low", "priority: medium", "priority: high", "priority: urgent"];
+noCheck = ["muffin-crusaders/glitch", "muffin-crusaders/hubot-scrumminator", "muffin-crusaders/static-website-blob-browser", "muffin-crusaders/hubot-azure-scripts", "muffin-crusaders/angularjs-styleguide-snippets-es6", "/muffin-crusaders/hubot-gitter2"];

 module.exports = (robot) ->
     gitter = new Gitter(process.env.HUBOT_GITTER2_TOKEN)
@@ -120,11 +120,12 @@
             title = body.issue.title
             user = body.sender.login
             # if issue has has prior recent changes, combine them and prevent duplicates
+            if action == "labeled" && body.label in validLabels
+                action = "added `#{body.label}` to"
+            else if action == "unlabeled" && body.label in validLabels
+                action = "removed `#{body.label}` from"
+
             if action !in disabledIssueActions
-                if action == "labeled" && body.label in validLabels
-                    action = "added `#{body.label}`"
-                else if action == "unlabeled" && body.label in validLabels
-                    action = "removed `#{body.label}`"
                 if store.issues[issueNum]
                     if action !in store.issues[issueNum].actions
                         store.issues[issueNum].actions.push(action)
@@ -135,6 +136,8 @@
                         title: title
                         issue: issue
                     }
+            else
+                flag = false

         else if  type == "issue_comment"
             action = body.action


fix(typo): mobile -> samples

fix(typo): mobile -> samples

--- scripts/gitter-activity-notifier.coffee
+++ scripts/gitter-activity-notifier.coffee
@@ -305,7 +305,7 @@
                                     | ------------------------------- | ------------------------------- |
                                     | [index-one.html](%6$s/dev/samples/index-one.html)    | [index-one.html](%6$s/prod/samples/index-one.html)    |
                                     | [index-mobile.html](%6$s/dev/samples/index-mobile.html)    | [index-mobile.html](%6$s/prod/samples/index-mobile.html)    |
-                                    | [index-mobile.html](%6$s/dev/samples/index-samples.html)    | [index-mobile.html](%6$s/prod/samples/index-samples.html)    |
+                                    | [index-samples.html](%6$s/dev/samples/index-samples.html)    | [index-samples.html](%6$s/prod/samples/index-samples.html)    |
                                     | [index-fgp-en.html](%6$s/dev/samples/index-fgp-en.html) | [index-fgp-en.html](%6$s/prod/samples/index-fgp-en.html) |
                                     | [index-fgp-fr.html](%6$s/dev/samples/index-fgp-fr.html) | [index-fgp-fr.html](%6$s/prod/samples/index-fgp-fr.html) |


follow button can take a label argument

follow button can take a label argument

--- components/follow_button/view.coffee
+++ components/follow_button/view.coffee
@@ -4,12 +4,15 @@
 analytics = require '../../lib/analytics.coffee'

 module.exports = class FollowButton extends Backbone.View
+
   events:
     'click': 'toggle'
     'touchstart': () -> @$el.removeClass "no-touch"

   initialize: (options) ->
     { @following, @notes, @modelName } = options
+
+    @label = if options.label then options.label else "#{@modelName}s"

     return unless @following

@@ -39,7 +42,7 @@
       analytics.track.funnel 'Triggered sign up form via follow button'
       mediator.trigger 'open:auth',
         mode: 'register'
-        copy: "Sign up to follow #{@modelName}s"
+        copy: "Sign up to follow #{@label}"
         destination: "#{@model.href()}/follow"
       return false


Update jenkins-notifier.coffee

Update jenkins-notifier.coffee

--- src/scripts/jenkins-notifier.coffee
+++ src/scripts/jenkins-notifier.coffee
@@ -61,6 +61,12 @@
             console.log res.statusCode
             robot.messageRoom '#dev', "Mothra has the upper hand!"
             robot.messageRoom '#dev', "http://i.imgur.com/CoqJxBx.gif"
+          if data.name == 'MechaGodzilla .com (Prod)'
+            console.log "MECHA GODZILLA!!!!"
+            console.log res.statusCode
+            robot.messageRoom '#qa-chat', "Mecha Godzilla is winning!"
+            robot.messageRoom '#qa-chat', "http://media.giphy.com/media/LkziC7bd1yLUk/giphy.gif"
+            http.get 'http://xserve:5051/mechawins'
         if data.build.status == 'SUCCESS'
           console.log "Success"
           #if data.name in @failing
@@ -99,8 +105,14 @@
             http.get 'http://xserve:5051/deathstar', (res) ->
               console.log res.statusCode
             robot.messageRoom "#dev", "The Death Star is now fully armed and operational"
-
-
+           if data.name == 'MechaGodzilla .com (Prod)'
+            console.log "MECHA GODZILLA!!!!"
+            console.log res.statusCode
+            robot.messageRoom '#qa-chat', "Mecha Godzilla has been defeated!"
+            robot.messageRoom '#qa-chat', "http://media.giphy.com/media/33T28J1KEkRq0/giphy.gif"
+            robot.messageRoom '#qa-chat', "http://media.giphy.com/media/yygLBxnwBVynu/giphy.gif"
+            robot.messageRoom '#qa-chat', "http://media.giphy.com/media/tEgJl9nSsfTGM/giphy.gif"
+            http.get 'http://xserve:5051/mechaloses'
     catch error
       console.log "jenkins-notify error: #{error}. Data: #{req.body}"
       console.log error.stack


Add logging to test

Add logging to test

--- src/smc-webapp/project_store.coffee
+++ src/smc-webapp/project_store.coffee
@@ -1226,22 +1226,23 @@
         {webapp_client} = require('./webapp_client')
         ncpu = undefined

-        ###
         # Comment out f() at the bottom of init_free_compute_slowdown to use f_test
         # Expect load to increase by 1% every second while load should be displayed
-        test_load = 0
-        f_test = =>
-            proj_store = @redux.getStore('projects')
-            quotas = proj_store.get_total_project_quotas(@project_id)
-            state  = proj_store.getIn(['project_map', @project_id, 'state', 'state'])
-            if state == 'running' and (quotas?) and (not quotas.member_host)
-                test_load = test_load + 1
-                @setState(free_compute_slowdown : test_load)
-            else
-                @setState(free_compute_slowdown : 0.0)
-            setTimeout(f_test, 1000)
-        f_test()
-        ###
+        # Console logs should stop when project is closed
+        # Projects should have independent load values
+        # test_load = 0
+        # f_test = =>
+        #     proj_store = @redux.getStore('projects')
+        #     quotas = proj_store.get_total_project_quotas(@project_id)
+        #     state  = proj_store.getIn(['project_map', @project_id, 'state', 'state'])
+        #     if state == 'running' and (quotas?) and (not quotas.member_host)
+        #         test_load = test_load + 1
+        #         @setState(free_compute_slowdown : test_load)
+        #     else
+        #         @setState(free_compute_slowdown : 0.0)
+        #     console.log "test load for", @project_id, "is", test_load
+        #     setTimeout(f_test, 1000) if @get_store()?
+        # f_test()

         f = =>
             proj_store = @redux.getStore('projects')


Model: deep clone improvements

Model: deep clone improvements

--- coffee/src/model.coffee
+++ coffee/src/model.coffee
@@ -42,7 +42,9 @@
   #
   # See https://github.com/documentcloud/underscore/issues/162 as to why
   # underscore does not implement deep copy.
-  clone: => return new @.constructor JSON.parse @toJSONString()
+  clone: => return new @constructor @toJSON()
+
+  toJSON: => return JSON.parse JSON.stringify @attributes

   toJSONString: => return JSON.stringify @toJSON()


Client: Pokemon faints only fade out pokemon.

--- client/app/js/views/battle_view.coffee
+++ client/app/js/views/battle_view.coffee
@@ -213,6 +213,7 @@
     $pokeball.appendTo(@$(".battle_pane"))

     # Start animations
+    $oldPokemon.css(opacity: 0)
     $newPokemon.css(opacity: 0)
     $pokeball.css(opacity: 1)
     releasePokemon = =>
@@ -539,16 +540,17 @@

   faint: (player, slot, done) =>
     $pokemon = @$pokemon(player, slot)
+    $image = $pokemon.find('.sprite img')

     if @skip?
-      $pokemon.addClass('hidden')
+      $image.addClass('hidden')
       done()
       return

     $image = $pokemon.find('.sprite img')
     move($image).set('top', '100%').duration('.25s').ease('ease-in').end()
-    move($pokemon).set('opacity', 0).end ->
-      $pokemon.addClass('hidden').css(opacity: 1)
+    move($image).set('opacity', 0).end ->
+      $image.addClass('hidden')
       done()
     @renderUserInfo()


Kloud: group kloud methods add bootstrap and checkCredential (authenticate)

--- client/app/lib/kite/kites/kloud.coffee
+++ client/app/lib/kite/kites/kloud.coffee
@@ -32,23 +32,37 @@

       @tell rpcMethod, payload

+
   @createApiMapping
-    stop           : 'stop'
-    start          : 'start'
-    build          : 'build'
-    event          : 'event'
-    reinit         : 'reinit'
-    resize         : 'resize'
-    restart        : 'restart'
-    destroy        : 'destroy'
-    checkTemplate  : 'plan'
-    buildStack     : 'apply'
-    setDomain      : 'domain.set'
-    addDomain      : 'domain.add'
-    unsetDomain    : 'domain.unset'
-    removeDomain   : 'domain.remove'
-    createSnapshot : 'createSnapshot'
-    deleteSnapshot : 'deleteSnapshot'
+
+    # Eventer
+    event           : 'event'
+
+    # Machine related actions, these requires valid machineId
+    stop            : 'stop'
+    start           : 'start'
+    build           : 'build'
+    reinit          : 'reinit'
+    resize          : 'resize'
+    restart         : 'restart'
+    destroy         : 'destroy'
+
+    # Domain managament
+    setDomain       : 'domain.set'
+    addDomain       : 'domain.add'
+    unsetDomain     : 'domain.unset'
+    removeDomain    : 'domain.remove'
+
+    # Snapshots
+    createSnapshot  : 'createSnapshot'
+    deleteSnapshot  : 'deleteSnapshot'
+
+    # Stack, Teams, Credentials related methods
+    bootstrap       : 'bootstrap'
+    buildStack      : 'apply'
+    checkTemplate   : 'plan'
+    checkCredential : 'authenticate'
+

   constructor: (options) ->


Export whole Framework in load

Export whole Framework in load

--- client/landing/app/MainApp/main.coffee
+++ client/landing/app/MainApp/main.coffee
@@ -82,6 +82,9 @@

   KD.remote.connect()

+  # Its required for apps
+  KD.exportKDFramework()
+
   # updateModalActive = no
   # KD.models.api.JAccount.fetchVersion (err, version)->
   #   return if KD.version is version or updateModalActive


put back onClose method

put back onClose method

--- client/src/views/narrative_view.coffee
+++ client/src/views/narrative_view.coffee
@@ -49,4 +49,6 @@
   delayedResize: ->
     window.setTimeout @resize, 0

+  onClose: ->

+


Tests: Helpers: Code styling.

Tests: Helpers: Code styling.

--- client/test/lib/helpers/helpers.coffee
+++ client/test/lib/helpers/helpers.coffee
@@ -47,8 +47,6 @@
       .click                  '[testpath=login-button]'

-  waitForVMRunning: require './waitforvmrunning'
-
   doLogin: (browser, user) ->

     @attemptLogin(browser, user)
@@ -71,32 +69,6 @@
       .waitForElementVisible  '[testpath=main-header]', 10000 # Assertion

-  deleteFile: (browser, fileSelector) ->
-
-    browser
-      .waitForElementPresent     fileSelector, 20000
-      .click                     fileSelector
-      .click                     fileSelector + ' + .chevron'
-      .waitForElementVisible     'li.delete', 20000
-      .click                     'li.delete'
-      .waitForElementVisible     '.delete-container', 20000
-      .click                     '.delete-container button.clean-red'
-      .waitForElementNotPresent  fileSelector, 2000
-
-
-  deleteFolder: (browser, selector) ->
-
-    browser
-      .waitForElementPresent     selector, 20000
-      .click                     selector
-      .click                     selector + ' + .chevron'
-      .waitForElementVisible     'li.delete', 20000
-      .click                     'li.delete'
-      .waitForElementVisible     '.delete-container', 20000
-      .click                     '.delete-container button.clean-red'
-      .waitForElementNotPresent  selector, 2000
-
-
   attemptEnterEmailAndPasswordOnRegister: (browser, user) ->

     browser
@@ -138,6 +110,17 @@
     @doLogout(browser)

     @doLogin(browser, user)
+
+
+  assertMainHeader: (browser, assertLoginLink = yes) ->
+
+    logoSelector = '[testpath=main-header] a#koding-logo'
+    loginLinkSelector = '[testpath=main-header] [testpath=login-link]'
+
+    browser.waitForElementVisible logoSelector, 25000
+
+    if assertLoginLink
+      browser.waitForElementVisible loginLinkSelector, 25000

   postActivity: (browser, shouldBeginTest = yes) ->
@@ -338,6 +321,32 @@
     return data

+  deleteFile: (browser, fileSelector) ->
+
+    browser
+      .waitForElementPresent     fileSelector, 20000
+      .click                     fileSelector
+      .click                     fileSelector + ' + .chevron'
+      .waitForElementVisible     'li.delete', 20000
+      .click                     'li.delete'
+      .waitForElementVisible     '.delete-container', 20000
+      .click                     '.delete-container button.clean-red'
+      .waitForElementNotPresent  fileSelector, 2000
+
+
+  deleteFolder: (browser, selector) ->
+
+    browser
+      .waitForElementPresent     selector, 20000
+      .click                     selector
+      .click                     selector + ' + .chevron'
+      .waitForElementVisible     'li.delete', 20000
+      .click                     'li.delete'
+      .waitForElementVisible     '.delete-container', 20000
+      .click                     '.delete-container button.clean-red'
+      .waitForElementNotPresent  selector, 2000
+
+
   openChangeTopFolderMenu: (browser) ->

     browser
@@ -348,6 +357,7 @@

   createWorkspace: require './createworkspace'
+

   deleteWorkspace: (browser, workspaceName) ->

@@ -366,15 +376,7 @@
         .waitForElementNotVisible  workspaceSelector, 20000

-  assertMainHeader: (browser, assertLoginLink = yes) ->
-
-    logoSelector = '[testpath=main-header] a#koding-logo'
-    loginLinkSelector = '[testpath=main-header] [testpath=login-link]'
-
-    browser.waitForElementVisible logoSelector, 25000
-
-    if assertLoginLink
-      browser.waitForElementVisible loginLinkSelector, 25000
+  waitForVMRunning: require './waitforvmrunning'

   changeName: (browser, inputSelector, shouldAssertSidebar) ->


New method: siblings()

New method: siblings()

--- source/quo.query.coffee
+++ source/quo.query.coffee
@@ -43,6 +43,20 @@
   $$.fn.children = (selector) ->
     elements = @map -> Array::slice.call @children
     _filtered elements, selector
+
+
+  ###
+  Get the siblings of each element in the current instance
+  @method siblings
+  @param  {string} A string containing a selector expression to match elements against.
+  ###
+  $$.fn.siblings = (selector) ->
+    elements = @map((index, element) ->
+      Array::slice.call(element.parentNode.children).filter (child) ->
+        child isnt element
+    )
+    _filtered elements, selector
+

   ###
   Retrieve the DOM elements matched by the QuoJS object.


clean out auto-generated unused file

clean out auto-generated unused file

--- app/assets/javascripts/campaign_pages/widgets.coffee
+++ app/assets/javascripts/campaign_pages/widgets.coffee
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/


Changed toast's error message #65

Changed toast's error message #65

--- app/assets/javascripts/oxalis/view/mergemodal.coffee
+++ app/assets/javascripts/oxalis/view/mergemodal.coffee
@@ -191,7 +191,7 @@
       app.router.loadURL(url)
       Toast.message(annotation.messages)
     ).fail( (xhr) ->
-      Toast.message(xhr.responseJSON.messages)
+      Toast.message("Error. Please try again.")
     ).always( ->
       toggleIcon()
     )
@@ -207,7 +207,6 @@
     event.preventDefault()

     toggleIcon = =>
-
       [@ui.formSpinnerIcon, @ui.formUploadIcon].forEach((ea) -> ea.toggleClass("hide"))


Fix oversight in 7f3ae1ffcf3185392cf30a62f4b83474b68f66cc.

One line was unintentionally deleted.

--- content_scripts/vimium_frontend.coffee
+++ content_scripts/vimium_frontend.coffee
@@ -308,6 +308,7 @@
 extend window,
   scrollToBottom: ->
     Marks.setPreviousPosition()
+    Scroller.scrollTo "y", "max"
   scrollToTop: (count) ->
     Marks.setPreviousPosition()
     Scroller.scrollTo "y", (count - 1) * Settings.get("scrollStepSize")


Add ability for consuing selected words

Add ability for consuing selected words

--- lib/minimap-highlight-selected.coffee
+++ lib/minimap-highlight-selected.coffee
@@ -34,18 +34,21 @@
   init: ->
     @decorations = []
     @highlightSelected.onDidAddMarker (marker) => @markerCreated(marker)
+    @highlightSelected.onDidAddSelectedMarker (marker) => @markerCreated(marker, true)
     @highlightSelected.onDidRemoveAllMarkers => @markersDestroyed()

   dispose: ->
     @decorations.forEach (decoration) -> decoration.destroy()
     @decorations = null

-  markerCreated: (marker) =>
+  markerCreated: (marker, selected = false) =>
     activeMinimap = @minimap.getActiveMinimap()
     return unless activeMinimap?
+    className  = 'highlight-selected'
+    className += ' selected' if selected

     decoration = activeMinimap.decorateMarker(marker,
-      {type: 'highlight', class: @highlightSelected.makeClasses()})
+      {type: 'highlight', class: className })
     @decorations.push decoration

   markersDestroyed: =>


Add TODO regarding quieting progress bar

--- lib/resin/ui/patterns/patterns.coffee
+++ lib/resin/ui/patterns/patterns.coffee
@@ -31,6 +31,7 @@
 		return callback(error)
 	, (state) ->

+		# TODO: Allow quieting this progress bar
 		bar ?= new ProgressBar 'Downloading device OS [:bar] :percent :etas',
 			complete: '='
 			incomplete: ' '


Use list of available renderes at instantiation to build pattern list.

--- lib/Watchers/Script.coffee
+++ lib/Watchers/Script.coffee
@@ -20,14 +20,11 @@
             'controller'
             'directive'
         ].concat(@config.additionalTypes or [])
-        @config.typeList = @config.typeList or [
-            'js'
-            'coffee'
-        ].concat(@config.additionalTypeList or [])
         super()

     pattern: ->
-        prefix = (_)=> "**/#{_}.{#{@config.typeList.join(',')}}"
+        types = Object.keys(ScriptWatcher.renderers)
+        prefix = (_)=> "**/#{_}.{#{types.join(',')}}"
         typeList = @config.types.map(prefix)
         super typeList


Fix ack in models for machine/replication view

--- admin/static/coffee/models.coffee
+++ admin/static/coffee/models.coffee
@@ -593,7 +593,7 @@
         datacenter = datacenters.get(datacenter_uuid)
         acks = namespace?.get('ack_expectations')?[datacenter?.get('id')]?
         if acks?
-            return acks
+            return namespace.get('ack_expectations')[datacenter.get('id')]
         else
             return 0


Remove @unbind. We keep the extension of Backbone.View (for the method destroy, for safety)

--- admin/static/coffee/router.coffee
+++ admin/static/coffee/router.coffee
@@ -1,6 +1,5 @@
 # Extend Backbone View
 Backbone.View.prototype.destroy = ->
-    @unbind()
     return

 # Router for Backbone.js


Add ide-haskell migration messages and options

--- lib/haskell-ghc-mod.coffee
+++ lib/haskell-ghc-mod.coffee
@@ -31,10 +31,26 @@
       type: 'string'
       default: 'ghc-modi'
       description: 'Path to ghc-modi'
+    disableFrontend:
+      type: 'boolean'
+      default: false
+      description: 'Disable frontend completely. Frontent will be removed
+                    in 0.7.0'
+    suppressStartupWarning:
+      type: 'boolean'
+      default: false

   registerEditorCommands: ->
     if atom.packages.isPackageActive('ide-haskell')
       return
+
+    unless atom.config.get('haskell-gch-mod.suppressStartupWarning')
+      atom.notifications.addWarning "Haskell-ghc-mod package is intended to
+      be used as a backend for ide-haskell. Frontend will
+      be removed in 0.7.0, at which point ide-haskell will be preferred option.
+      All features supported by haskell-ghc-mod are now in ide-haskell.
+      Consider migrating early. You can suppress this warning in haskell-ghc-mod
+      settings.", dismissable:true

     @subscriptions_editor = new CompositeDisposable
     @editorMap = new WeakMap
@@ -77,23 +93,27 @@

   activate: (state) ->
     @process=new GhcModiProcess
-    @subscriptions = new CompositeDisposable

-    atom.views.addViewProvider HaskellGhcModMessage, (message)->
-      el=new HaskellGhcModMessageElement
-      el.setModel(message)
-      el
+    unless atom.config.get('haskell-gch-mod.disableFrontend')
+      @subscriptions = new CompositeDisposable

-    atom.packages.onDidActivatePackage (p) =>
-      @unregisterEdtiorCommands() if p.name=='ide-haskell'
+      @subscriptions.add atom.views.addViewProvider HaskellGhcModMessage,
+        (message)->
+          el=new HaskellGhcModMessageElement
+          el.setModel(message)
+          el

-    atom.packages.onDidDeactivatePackage (p) =>
-      @registerEditorCommands() if p.name=='ide-haskell'
+      @subscriptions.add atom.packages.onDidActivatePackage (p) =>
+        @unregisterEdtiorCommands() if p.name=='ide-haskell'

-    setTimeout @registerEditorCommands, 5000
+      @subscriptions.add atom.packages.onDidDeactivatePackage (p) =>
+        @registerEditorCommands() if p.name=='ide-haskell'
+
+      setTimeout @registerEditorCommands, 5000

   deactivate: ->
     @unregisterEdtiorCommands()
+    @subscriptions?.dispose()
     @process?.destroy()

   provideIdeBackend_0_1_0: ->


Allow /proposal/:id even for non accepted sessions


Updates counter position

Updates counter position

--- app/assets/javascripts/backend/animals.js.coffee
+++ app/assets/javascripts/backend/animals.js.coffee
@@ -169,6 +169,9 @@
     #     event.preventDefault()

     window.onLoad()
+    $('.golumn-columns').scroll () =>
+      $('.golumn-items-counter').css('right', - $('.golumn-columns').scrollLeft() )
+

   ko.unapplyBindings = ($node, remove) =>
     $node.find('*').each () ->


Reduce polling period on front-end

Reduce polling period on front-end

--- app/assets/javascripts/browserlog/logs.js.coffee
+++ app/assets/javascripts/browserlog/logs.js.coffee
@@ -1,5 +1,5 @@
 class LogFeed
-  POLL_PERIOD: 500
+  POLL_PERIOD: 1500

   constructor: ->
     @currentLine = -1


JS tweaks

JS tweaks

--- app/assets/javascripts/choose_your_own.js.coffee
+++ app/assets/javascripts/choose_your_own.js.coffee
@@ -1,3 +1,6 @@
+window.ChooseYourOwn =
+  choice_from_menu : (menu) -> $('#' + $(menu).attr('id').replace('menu_for_',''))
+
 jQuery ->
   $ = jQuery
   $('body').delegate '.choose_your_own > .menu > .menu_item', 'click', ->
@@ -5,6 +8,6 @@
     $this.closest('.menu').children().removeClass('active')
     $this.addClass('active')
     top = $this.closest('.choose_your_own')
+    top.children('input').val($this.data('value'))
     top.children().removeClass('active')
-    top.children("##{this.id.replace('menu_for_','')}").addClass('active')
-    top.children('input').val($this.data('value'))
+    ChooseYourOwn.choice_from_menu(this).addClass('active')


fixing assets 5

fixing assets 5

--- app/assets/javascripts/pirates/simulation.coffee
+++ app/assets/javascripts/pirates/simulation.coffee
@@ -5,7 +5,6 @@

 class @Simulation
-
   @initialize = () ->
     # load elements
     @canvas = document.getElementById "pirateGrid"


fix format money in application.coffee

fix format money in application.coffee

Fix bug when adding values with comma as '1,000.00' replacing the comma for nothing as regular integer values.

--- app/assets/javascripts/shoppe/application.coffee
+++ app/assets/javascripts/shoppe/application.coffee
@@ -72,7 +72,7 @@
 # Format money values to 2 decimal places
 #
 window.formatMoneyField = ->
-  value = $(this).val()
+  value = $(this).val().replace /,/, ""
   $(this).val(parseFloat(value).toFixed(2)) if value.length

 #
@@ -116,4 +116,4 @@
 Mousetrap.bind 'escape', ->
   Nifty.Dialog.closeTopDialog()
   false
-  +


clarify comment

clarify comment

--- apps/artwork/components/auction/test/view.coffee
+++ apps/artwork/components/auction/test/view.coffee
@@ -117,7 +117,7 @@
         data = Object.assign({}, @data)
         data.accounting = accounting
         data.artwork.sale_artwork.reserve_message = 'Reserve not met'
-        # just shoving user + me into data to meet the template conditions for rendering
+        # just shoving user + me into data to meet the template conditions for the .is_losing element to render
         data.user = true
         data.me =
           lot_standing:


Remove unnecessary construction of new editor

--- spec/app/editor-spec.coffee
+++ spec/app/editor-spec.coffee
@@ -2600,8 +2600,6 @@

   describe "editor-path-change event", ->
     it "emits event when buffer's path is changed", ->
-      editor = new Editor
-
       eventHandler = jasmine.createSpy('eventHandler')
       editor.on 'editor-path-change', eventHandler
       editor.buffer.setPath("moo.text")


:white_check_mark: for search-occurrence

--- spec/occurrence-spec.coffee
+++ spec/occurrence-spec.coffee
@@ -258,7 +258,7 @@

     beforeEach ->
       searchEditor = vimState.searchInput.editor
-      searchEditorElement = searchEditor.element
+      searchEditorElement = vimState.searchInput.editorElement
       jasmine.attachToDOM(getView(atom.workspace))
       settings.set('incrementalSearch', true)
       set
@@ -728,6 +728,70 @@
             xxx: ooo: XXX: ooo xxx: ooo:
             """

+    describe "search occurrence", ->
+      [searchEditor, searchEditorElement] = []
+      beforeEach ->
+        searchEditor = vimState.searchInput.editor
+        searchEditorElement = vimState.searchInput.editorElement
+        jasmine.attachToDOM(getView(atom.workspace))
+        settings.set('incrementalSearch', true)
+        set
+          text: """
+          ooo: xxx: ooo
+          !!!: ooo: xxx:
+          ooo: xxx: ooo:
+          """
+          cursor: [0, 0]
+
+        runs ->
+          ensure 'g o',
+            occurrenceText: ['ooo', 'ooo', 'ooo', 'ooo', 'ooo']
+        waitsFor ->
+          editorElement.classList.contains('has-occurrence')
+
+      describe "tab, shift-tab", ->
+        it "search next/previous occurrence marker", ->
+          keystroke 'tab'
+          rawKeystroke('tab enter', searchEditorElement)
+          ensure cursor: [1, 5]
+
+          keystroke 'tab'
+          rawKeystroke('tab enter', searchEditorElement)
+          ensure cursor: [2, 10]
+
+          keystroke 'shift-tab'
+          rawKeystroke('shift-tab enter', searchEditorElement)
+          ensure cursor: [1, 5]
+
+          keystroke 'shift-tab'
+          rawKeystroke('shift-tab enter', searchEditorElement)
+          ensure cursor: [0, 0]
+
+      describe "space can clear preset-marker", ->
+        it "clear preset-occurrence and move to next", ->
+          keystroke 'tab'
+          rawKeystroke('tab space tab enter', searchEditorElement)
+          ensure cursor: [2, 10], occurrenceCount: 4
+
+          ensure 'g U i p',
+            text: """
+            OOO: xxx: OOO
+            !!!: ooo: xxx:
+            OOO: xxx: OOO:
+            """
+
+        it "clear preset-occurrence and move to previous", ->
+          keystroke 'shift-tab'
+          rawKeystroke('shift-tab space shift-tab enter', searchEditorElement)
+          ensure cursor: [0, 10], occurrenceCount: 4
+
+          ensure 'g U i p',
+            text: """
+            OOO: xxx: OOO
+            !!!: OOO: xxx:
+            ooo: xxx: OOO:
+            """
+
     describe "explict operator-modifier o and preset-marker", ->
       beforeEach ->
         set


Fix some selection keyword tests

Fix some selection keyword tests

--- spec/powershell-spec.coffee
+++ spec/powershell-spec.coffee
@@ -134,13 +134,14 @@
           {tokens} = grammar.tokenizeLine("if($answer.length -lt 10) { echo $answer } elseif($answer.length -lt 100) { echo \"You talk a lot\" } else { echo \"?\"}")

         it "should highlight 'if'", ->
-          expect(tokens[0]).toEqual value: "if", scopes: ["source.powershell","keyword.control.flow.powershell"]
+          expect(tokens[0]).toEqual value: "if", scopes: ["source.powershell","keyword.control.powershell"]

         it "should highlight 'elseif'", ->
-          expect(tokens[18]).toEqual value: "elseif", scopes: ["source.powershell","keyword.control.flow.powershell"]
+          expect(tokens[14]).toEqual value: "elseif", scopes: ["source.powershell","keyword.control.powershell"]

         it "should highlight 'else'", ->
-          expect(tokens[37]).toEqual value: "else", scopes: ["source.powershell","keyword.control.flow.powershell"]
+          console.log(tokens)
+          expect(tokens[29]).toEqual value: "else", scopes: ["source.powershell","keyword.control.powershell"]

       describe "Do-until statements", ->
         tokens = null


Change '.status-bar' selector to 'status-bar' in spec

--- spec/status-bar-spec.coffee
+++ spec/status-bar-spec.coffee
@@ -15,9 +15,9 @@

   describe "@activate", ->
     it "appends only one status bar", ->
-      expect(workspaceElement.querySelectorAll('.status-bar').length).toBe 1
+      expect(workspaceElement.querySelectorAll('status-bar').length).toBe 1
       atom.workspace.getActivePane().splitRight(copyActiveItem: true)
-      expect(workspaceElement.querySelectorAll('.status-bar').length).toBe 1
+      expect(workspaceElement.querySelectorAll('status-bar').length).toBe 1

     it "makes the status bar available as a deprecated property on atom.workspaceView", ->
       spyOn(Grim, 'deprecate')
@@ -28,7 +28,7 @@
   describe "@deactivate()", ->
     it "removes the status bar view", ->
       atom.packages.deactivatePackage("status-bar")
-      expect(workspaceElement.querySelector('.status-bar')).toBeNull()
+      expect(workspaceElement.querySelector('status-bar')).toBeNull()
       expect(atom.__workspaceView.statusBar).toBeFalsy()

   describe "when status-bar:toggle is triggered", ->
@@ -37,6 +37,6 @@

     it "hides or shows the status bar", ->
       atom.commands.dispatch(workspaceElement, 'status-bar:toggle')
-      expect(workspaceElement.querySelector('.status-bar').parentNode).not.toBeVisible()
+      expect(workspaceElement.querySelector('status-bar').parentNode).not.toBeVisible()
       atom.commands.dispatch(workspaceElement, 'status-bar:toggle')
-      expect(workspaceElement.querySelector('.status-bar').parentNode).toBeVisible()
+      expect(workspaceElement.querySelector('status-bar').parentNode).toBeVisible()


Remove unneeded rootView variable

Remove unneeded rootView variable

--- spec/wrap-guide-spec.coffee
+++ spec/wrap-guide-spec.coffee
@@ -2,10 +2,10 @@
 RootView = require 'root-view'

 describe "WrapGuide", ->
-  [rootView, editor, wrapGuide] = []
+  [editor, wrapGuide] = []

   beforeEach ->
-    rootView = new RootView(require.resolve('fixtures/sample.js'))
+    new RootView(require.resolve('fixtures/sample.js'))
     atom.loadPackage('wrap-guide')
     rootView.attachToDom()
     editor = rootView.getActiveEditor()


:memo: Clarify that stack only has an effect if detail is present as well

--- src/notification-manager.coffee
+++ src/notification-manager.coffee
@@ -127,7 +127,7 @@
   #    * `icon` (optional) A {String} name of an icon from Octicons to display
   #      in the notification header. Defaults to `'flame'`.
   #    * `stack` (optional) A preformatted {String} with stack trace information
-  #      describing the location of the error.
+  #      describing the location of the error. Requires `detail` to be set.
   addError: (message, options) ->
     @addNotification(new Notification('error', message, options))

@@ -154,7 +154,7 @@
   #    * `icon` (optional) A {String} name of an icon from Octicons to display
   #      in the notification header. Defaults to `'bug'`.
   #    * `stack` (optional) A preformatted {String} with stack trace information
-  #      describing the location of the error.
+  #      describing the location of the error. Requires `detail` to be set.
   addFatalError: (message, options) ->
     @addNotification(new Notification('fatal', message, options))


Added engine selector

Added engine selector


Got color changes working

Got color changes working


metric: default null values to 0

metric: default null values to 0


custom class

custom class

--- shared/idle/IdlePlayerController.coffee
+++ shared/idle/IdlePlayerController.coffee
@@ -84,6 +84,7 @@
           when 'pro'              then return 'bg-purple'
           when 'idle'             then return 'bg-rainbow'
           when 'godly'            then return 'bg-black'
+          when 'custom'           then return 'bg-blue'

       $scope.equipmentStatArray = [
         {name: 'str', fa: 'fa-legal fa-rotate-90'}


add helper file to examples

add helper file to examples

--- examples/helper.coffee
+++ examples/helper.coffee
@@ -4,5 +4,5 @@
   key: process.env.TWITTER_USER_KEY
   secret: process.env.TWITTER_USER_SECRET
   token:  process.env.TWITTER_USER_TOKEN
-  token_secret:  process.env.TWITTER_USER_TOKEN_SECRET
+  tokenSecret:  process.env.TWITTER_USER_TOKEN_SECRET


removing comments from code samples

removing comments from code samples

--- src/array_extensions.coffee
+++ src/array_extensions.coffee
@@ -23,11 +23,9 @@
    a = ["a", "b", "c"]
    b = a.copy()

-   # their elements are equal
    a[0] == b[0] && a[1] == b[1] && a[2] == b[2]
 => true

-   # but they aren't the same object in memory
    a === b
 => false

@@ -67,7 +65,6 @@
    [[1, 2], [3, 4], 5].flatten()
 => [1, 2, 3, 4, 5]

-   # won't flatten twice nested arrays. You can call it twice for that.
    [[1, 2], [3, [4, 5]], 6].flatten()
 => [1, 2, 3, [4, 5], 6]

@@ -166,7 +163,7 @@
 ###*
 Call the given iterator once for each element in the array,
 passing in the element as the first argument, the index of
-the element as the second argument, and this array as the
+the element as the second argument, and `this` array as the
 third argument.

@@ -190,7 +187,7 @@
 @param {Function} iterator Function to be called once for
 each element in the array.
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.

 @type Array
 @returns this to enable method chaining.
@@ -207,7 +204,7 @@
 ###*
 Call the given iterator once for each element in the array,
 passing in the element as the first argument, the index of
-the element as the second argument, and this array as the
+the element as the second argument, and `this` array as the
 third argument.

@@ -222,7 +219,7 @@
 @param {Function} iterator Function to be called once for
 each element in the array.
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.
 @type Array
 @returns An array of the results of the iterator function
 being called on the original array elements.
@@ -240,12 +237,6 @@

   [1, 2, 3, 4].eachPair (a, b) ->
-    # 1, 2
-    # 1, 3
-    # 1, 4
-    # 2, 3
-    # 2, 4
-    # 3, 4

 @name eachPair
@@ -253,7 +244,7 @@
 @param {Function} iterator Function to be called once for
 each pair of elements in the array.
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.
 ###
 Array::eachPair = (iterator, context) ->
   length = this.length
@@ -285,7 +276,7 @@
 @param {Function} iterator Function to be called once for
 each element in the array.
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.

 @returns this
 @type Array
@@ -320,7 +311,7 @@
 @param {Function} iterator Function to be called once for
 each group of elements in the array.
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.

 @returns this
 @type Array
@@ -478,7 +469,7 @@

 @param {Function} iterator
 @param {Object} [context] Optional context parameter to be
-used as this when calling the iterator function.
+used as `this` when calling the iterator function.

 @type Array
 @returns An array in the form of [trueCollection, falseCollection]


Open file when received 'open-file' event.

This event is emitted when the OS X opens files with Atom.

--- src/atom-application.coffee
+++ src/atom-application.coffee
@@ -139,6 +139,10 @@
     app.on 'window-all-closed', ->
       app.quit()

+    app.on 'open-file', (event, filePath) =>
+      event.preventDefault()
+      @openPath filePath
+
     ipc.on 'close-without-confirm', (processId, routingId) ->
       window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
       window.removeAllListeners 'close'


Fix unexpected closure

Fix unexpected closure

--- src/beginner/TabView.coffee
+++ src/beginner/TabView.coffee
@@ -1,7 +1,6 @@
 class @TabView
-  _index = 0
-
   constructor: (@$el) ->
+    @index = 0
     @$btns = @$el.querySelectorAll('.js-tab-btn')
     @$contents = @$el.querySelectorAll('.js-tab-content')
     @toggleBtn()
@@ -12,20 +11,20 @@
     for $btn, i in @$btns
       $btn.dataset.index = i
       $btn.addEventListener 'click', (e) =>
-        _index = +e.target.dataset.index
+        @index = +e.target.dataset.index
         @toggleBtn()
         @showContent()

   toggleBtn: ->
     for $btn, i in @$btns
-      if _index is i
+      if @index is i
         $btn.classList.add('is-active')
       else
         $btn.classList.remove('is-active')

   showContent: ->
     for $content, i in @$contents
-      if _index is i
+      if @index is i
         $content.classList.add('is-active')
       else
         $content.classList.remove('is-active')


activity: temporarily set `ActivityListController` box mode to off

--- client/Social/Activity/activitylistcontroller.coffee
+++ client/Social/Activity/activitylistcontroller.coffee
@@ -11,7 +11,7 @@
     options.showHeader           ?= yes
     options.scrollView           ?= no
     options.wrapper              ?= no
-    options.boxed                ?= yes
+    options.boxed                ?= no
     options.itemClass           or= ActivityListItemView

     options.viewOptions         or= {}


Activity: listcontroller reverted back to boxed mode

--- client/Social/Activity/activitylistcontroller.coffee
+++ client/Social/Activity/activitylistcontroller.coffee
@@ -11,7 +11,7 @@
     options.showHeader           ?= yes
     options.scrollView           ?= no
     options.wrapper              ?= no
-    options.boxed                ?= no
+    options.boxed                ?= yes
     options.itemClass           or= ActivityListItemView

     options.viewOptions         or= {}


activity: show edit widget wrapper after widget is instantiated

--- client/Social/Activity/views/activitylistitem.coffee
+++ client/Social/Activity/views/activitylistitem.coffee
@@ -69,6 +69,7 @@
     @editWidget.on 'Submit', @bound 'resetEditing'
     @editWidget.on 'Cancel', @bound 'resetEditing'
     @editWidgetWrapper.addSubView @editWidget, null, yes
+    @editWidgetWrapper.show()

   resetEditing : ->


activity: make sure unreadCount is passed to ChatList

--- client/activity/lib/components/chatpane/index.coffee
+++ client/activity/lib/components/chatpane/index.coffee
@@ -39,8 +39,9 @@
         isMessagesLoading={@props.thread?.getIn ['flags', 'isMessagesLoading']}
         messages={@props.messages}
         showItemMenu={@props.showItemMenu}
+        channelId={@props.thread.getIn ['channel', 'id']}
         channelName={@props.thread.getIn ['channel', 'name']}
-        channelId={@props.thread.getIn ['channel', 'id']}
+        unreadCount={@props.thread.getIn ['channel', 'unreadCount']}
       />
     </Scroller>


Client: Activity: Added needed components and default state

--- client/activity/lib/components/feeditem/index.coffee
+++ client/activity/lib/components/feeditem/index.coffee
@@ -1,18 +1,38 @@
 kd                   = require 'kd'
 React                = require 'kd-react'
+ReactDOM             = require 'react-dom'
 Avatar               = require 'app/components/profile/avatar'
 Link                 = require 'app/components/common/link'
 TimeAgo              = require 'app/components/common/timeago'
 immutable            = require 'immutable'
+classnames           = require 'classnames'
+MessageLink          = require 'activity/components/messagelink'
 MessageBody          = require 'activity/components/common/messagebody'
 ProfileText          = require 'app/components/profile/profiletext'
-FeedItemAction       = require './feeditemaction'
 MessageLikeSummary   = require 'activity/components/common/messagelikesummary'
 ProfileLinkContainer = require 'app/components/profile/profilelinkcontainer'
+AutoSizeTextarea     = require 'app/components/common/autosizetextarea'
+toImmutable          = require 'app/util/toImmutable'
+ActivityLikeLink     = require 'activity/components/chatlistitem/activitylikelink'
+ActivityFlux         = require 'activity/flux'
+CommentList          = require 'activity/components/commentlist'
+fetchAccount         = require 'app/util/fetchAccount'
+whoami               = require 'app/util/whoami'
+ActivitySharePopup   = require 'activity/components/activitysharepopup'

 module.exports = class FeedItem extends React.Component

-  @defaultProps = message: immutable.Map()
+  @defaultProps =
+    message: immutable.Map()
+
+  constructor: (props) ->
+
+    super props
+
+    @state =
+      comment            : ''
+      focusOnInput       : no
+      isSharePopupOpened : no

   shouldComponentUpdate: (nextProps, nextState) ->
     return @props.message isnt nextProps.message


activity: require listitemview inline

activity: require listitemview inline

--- client/activity/lib/views/activityinputwidget.coffee
+++ client/activity/lib/views/activityinputwidget.coffee
@@ -4,7 +4,6 @@
 KDView = kd.View
 ActivityInputHelperView = require './activityinputhelperview'
 ActivityInputView = require './activityinputview'
-ActivityListItemView = require './activitylistitemview'
 EmbedBoxWidget = require './embedboxwidget'
 globals = require 'globals'
 mixpanel = require 'app/util/mixpanel'
@@ -213,6 +212,7 @@
     data = generateDummyMessage value

     @preview?.destroy()
+    ActivityListItemView = require './activitylistitemview'
     @addSubView @preview = new ActivityListItemView cssClass: 'preview', data
     @preview.addSubView new KDCustomHTMLView
       cssClass : 'preview-indicator'


MachineSettingsPopup: create a new ComputeResizeModal when resize button clicked

--- client/app/lib/providers/machinesettingspopup.coffee
+++ client/app/lib/providers/machinesettingspopup.coffee
@@ -224,7 +224,25 @@
         diskUsage.updateBar 0, '%', 'failed to fetch usage!'

-    {moreView, nickname, nickEdit} = @modalTabs.forms.Settings.inputs
+    {moreView, nickname,
+     nickEdit, resizeIcon} = @modalTabs.forms.Settings.inputs
+
+    resizeIcon.once 'click', =>
+
+      @fetchUsageInfo (err, info)=>
+
+        if showError err
+          return @destroy()
+
+        { plan, plans, usage, reward } = info
+
+        limits  = plans[plan]
+        options = { plan, limits, usage, reward, @machine }
+
+        new (require './computeresizemodal') options
+
+        @destroy()
+

     moreLabel = moreView.getOption 'label'
     moreLabel.on 'click', =>


fixed GET/query params to vanish when facets are clicked. needed to remove setRouteSilently

--- client/landing/app/MainApp/ApplicationManager.coffee
+++ client/landing/app/MainApp/ApplicationManager.coffee
@@ -26,7 +26,6 @@
       image : "Viewer"
       sound : "Viewer"
     @on 'AppManagerWantsToShowAnApp', @bound "setFrontApp"
-    @on 'AppManagerWantsToShowAnApp', @bound "setRouteSilently"

   open: do ->

@@ -245,20 +244,6 @@
       @appControllers[name].instances.splice index, 1
       if @appControllers[name].instances.length is 0
         delete @appControllers[name]
-
-  setRouteSilently:(controller, view, options)->
-
-    {profileEntryPoint, groupEntryPoint} = KD.config
-
-    entryPoint = if profileEntryPoint or groupEntryPoint
-      "/#{profileEntryPoint or groupEntryPoint}"
-    else ''
-
-    return unless options.route
-
-    @getSingleton('router').handleRoute "#{entryPoint}/#{options.route}",
-      suppressListeners : yes
-

   createPromptModal:(appOptions, callback)->
     # show modal and wait for response


Adds tests

Adds tests

--- api/apps/graphql/test/resolvers.coffee
+++ api/apps/graphql/test/resolvers.coffee
@@ -18,7 +18,11 @@

   beforeEach ->
     articles = total: 20, count: 1, results: [_.extend fixtures().articles, {slugs: ['slug-1']} ]
+    curations = total: 20, count: 1, results: [fixtures().curations]
+    channels = total: 20, count: 1, results: [fixtures().channels]
     resolvers.__set__ 'where', @where = sinon.stub().yields null, articles
+    resolvers.__set__ 'Curation', { where: @curationWhere = sinon.stub().yields null, curations }
+    resolvers.__set__ 'Channel', { where: @channelWhere = sinon.stub().yields null, channels }
     @req = user: channel_ids: ['456']

   describe 'articles', ->
@@ -44,3 +48,20 @@
       .then (results) =>
         results.length.should.equal 1
         results[0].slug.should.equal 'slug-1'
+
+  describe 'channels', ->
+
+    it 'can find channels', ->
+      resolvers.channels {}, {}, @req, {}
+      .then (results) ->
+        results.length.should.equal 1
+        results[0].name.should.equal 'Editorial'
+        results[0].type.should.equal 'editorial'
+
+  describe 'curations', ->
+
+    it 'can find curations', ->
+      resolvers.curations {}, {}, @req, {}
+      .then (results) ->
+        results.length.should.equal 1
+        results[0].name.should.equal 'Featured Articles'


Make build more verbose

Make build more verbose

--- tools/extractDocs.coffee
+++ tools/extractDocs.coffee
@@ -1,4 +1,5 @@
 fs = require 'fs'
+chalk = require 'chalk'

 SRC_PATH = './src/index.coffee'
 README_TEMPLATE = './docs/README_TEMPLATE.md'
@@ -6,6 +7,7 @@
 OUTPUT_PATH = './README.md'

 apiDescription = ''
+console.log "Processing #{chalk.cyan SRC_PATH}..."
 code = fs.readFileSync SRC_PATH, 'utf8'
 lines = code.split '\n'
 fCode = false
@@ -27,6 +29,9 @@

 apiDescription = apiDescription.trim()

+console.log "Reading #{chalk.cyan README_TEMPLATE}..."
 readme = fs.readFileSync README_TEMPLATE, 'utf8'
 finalReadme = readme.replace API_PLACEHOLDER, apiDescription
+console.log "Writing #{chalk.cyan OUTPUT_PATH}..."
 fs.writeFileSync OUTPUT_PATH, finalReadme, 'utf8'
+console.log "Done"


Use -> instead of =>

Use -> instead of =>

--- src/command-registry.coffee
+++ src/command-registry.coffee
@@ -115,7 +115,7 @@

     @commandRegistered(commandName)

-    new Disposable =>
+    new Disposable ->
       listenersForElement.splice(listenersForElement.indexOf(listener), 1)
       listenersForCommand.delete(element) if listenersForElement.length is 0


whoops! no cusses

whoops! no cusses

--- src/command/proof_base.iced
+++ src/command/proof_base.iced
@@ -68,8 +68,6 @@
   allocate_proof_gen : (cb) ->
     klass = S.classes[@service_name]
     assert.ok klass?
-    console.log "fuuuuck"
-    console.log @supersede
     await @me.gen_remote_proof_gen { @klass, @remote_name_normalized, @supersede }, defer err, @gen
     cb err


Use max z-index for box positioning

Use max z-index for box positioning

--- lib/assets/javascripts/xray.js.coffee
+++ lib/assets/javascripts/xray.js.coffee
@@ -220,8 +220,11 @@
       for element in specimens
         continue unless element.isVisible()
         element.makeBox()
-        element.$box.css(zIndex: Math.ceil((10000 + element.bbox.top + element.bbox.left)))
-        @shownBoxes .push element.$box
+        # A cheap way to "order" the boxes, where boxes closer to the top
+        # have a lower z-index than those positioned lower.
+        element.$box.css
+          zIndex: Math.ceil(MAX_ZINDEX*0.9 + element.bbox.top + element.bbox.left)
+        @shownBoxes.push element.$box
         $('body').append element.$box

   reset: ->


defaults for compression algo

defaults for compression algo

--- src/compressed-image.coffee
+++ src/compressed-image.coffee
@@ -27,6 +27,7 @@
   constructor: (header, view, offset) ->
     super

+    # Get compression values
     @zcmptype = header.get("ZCMPTYPE")
     @zbitpix  = header.get("ZBITPIX")
     @znaxis   = header.get("ZNAXIS")
@@ -42,8 +43,15 @@
     @width  = header.get("ZNAXIS1")
     @height = header.get("ZNAXIS2") or 1

-    # Get algorithm specific parameters
+    # Storage for compression algorithm parameters
     @algorithmParameters = {}
+
+    # Set default parameters
+    if @zcmptype is 'RICE_1'
+      @algorithmParameters["BLOCKSIZE"] = 32
+      @algorithmParameters["BYTEPIX"] = 4
+
+    # Get compression algorithm parameters (override defaults when keys present)
     i = 1
     loop
       key = "ZNAME#{i}"
@@ -54,23 +62,17 @@

       i += 1

-    # Set default parameters unless already set
-    if @zcmptype is 'RICE_1'
-      @algorithmParameters["BLOCKSIZE"] = 32 unless "BLOCKSIZE" of @algorithmParameters
-      @algorithmParameters["BYTEPIX"] = 4 unless "BYTEPIX" of @algorithmParameters
-
     @zmaskcmp = header.get("ZMASKCMP")
     @zquantiz = header.get("ZQUANTIZ") or "LINEAR_SCALING"

     @bzero  = header.get("BZERO") or 0
     @bscale = header.get("BSCALE") or 1

+    # Define the internal _getRow function
+    hasBlanks = @zblank? or @blank? or @cols.indexOf("ZBLANK") > -1
+    @_getRow = if hasBlanks then @_getRowHasBlanks else @_getRowNoBlanks
+
     @setAccessors(header)
-    @defGetRow()
-
-  defGetRow: ->
-    hasBlanks = @zblank? or @blank? or @cols.indexOf("ZBLANK") > -1
-    @getRow = if hasBlanks then @_getRowHasBlanks else @_getRowNoBlanks

   # TODO: Test this function.  Need example file with blanks.
   # TODO: Implement subtractive dithering


dot dot slash?

dot dot slash?

--- src/pseudositer.coffee
+++ src/pseudositer.coffee
@@ -797,7 +797,7 @@
   # default options
   $.pseudositer.defaultOptions =

-    linkSelector   : 'a:not([href^="?"],[href^="/"],[href^="."])' # Find relative links from an index page that go deeper
+    linkSelector   : 'a:not([href^="?"],[href^="/"],[href^="../"])' # Find relative links from an index page that go deeper

     # default handlers
     update         : [ hideError ]


Fix Admin JS manifest file

Fix Admin JS manifest file

Include jquery so that bootstrap works correctly. Fix comment styling
(don't use CSS style comments).

--- app/assets/javascripts/admin.js.coffee
+++ app/assets/javascripts/admin.js.coffee
@@ -1,5 +1,4 @@
-/*
- *
- *= require bootstrap
- *= require_tree ./admin/
- */
+//= require jquery
+//= require jquery_ujs
+//= require bootstrap
+//= require_tree ./admin/


Audio js updates.

Audio js updates.

--- app/assets/javascripts/audio.js.coffee
+++ app/assets/javascripts/audio.js.coffee
@@ -1,6 +1,20 @@
 window.feedbin ?= {}

 $.extend feedbin,
+
+  nowPlayingdata: {}
+
+  hasDuration: ->
+    if isNaN(window.player.duration) || window.player.duration == 0
+      false
+    else
+      true
+
+  loadProgress: (entryId) ->
+    if (entryId of feedbin.data.progress)
+      feedbin.data.progress[entryId]
+    else
+      false

   initPlayer: (play = true) ->
     $('body').removeClass('audio-panel-minimized')
@@ -14,18 +28,17 @@
       defaultAudioWidth: 'auto'
       defaultAudioHeight: '5px'
       success: (mediaElement, domObject) ->
-        data = $(domObject).data()
-        if (data.entryId of feedbin.data.progress)
-          progress = feedbin.data.progress[data.entryId]
+        feedbin.nowPlayingData = $(domObject).data()
+
+        if progress = feedbin.loadProgress(feedbin.nowPlayingData.entryId)
           mediaElement.setCurrentTime(progress.progress)

         mediaElement.addEventListener 'timeupdate', (e) ->
-          console.log 'timeupdate'
-          if !isNaN(window.player.duration) && window.player.duration != 0
-            feedbin.data.progress[data.entryId] =
+          if feedbin.hasDuration()
+            feedbin.data.progress[feedbin.nowPlayingData.entryId] =
               progress: window.player.currentTime
               duration: window.player.duration
-          feedbin.playTime(data.entryId)
+          feedbin.timeRemaining(feedbin.nowPlayingData.entryId)

         mediaElement.addEventListener 'seeked', _.throttle(feedbin.updateProgress, 1000, {leading: false})
         mediaElement.addEventListener 'timeupdate', _.throttle(feedbin.updateProgress, 5000, {leading: false})
@@ -35,9 +48,8 @@
           mediaElement.play()

   updateProgress: ->
-    if !isNaN(window.player.duration) && window.player.duration != 0
-      data = $(window.player.domNode).data()
-      form = $("[data-behavior~=audio_target] [data-behavior~=audio_progress_form_#{data.entryId}]")
+    if feedbin.hasDuration()
+      form = $("[data-behavior~=audio_target] [data-behavior~=audio_progress_form_#{feedbin.nowPlayingData.entryId}]")
       if form.length > 0
         field = form.find('#recently_played_entry_progress').val(window.player.currentTime)
         field = form.find('#recently_played_entry_duration').val(window.player.duration)
@@ -55,9 +67,8 @@
       minutes = Math.floor(duration / 60);
       durationElement.text("#{minutes} minutes")

-  playTime: (entryId) ->
-    if (entryId of feedbin.data.progress)
-      progress = feedbin.data.progress[entryId]
+  timeRemaining: (entryId) ->
+    if progress = feedbin.loadProgress(entryId)
       durationElement = $("[data-behavior~=audio_duration_#{entryId}]")
       left = progress.duration - progress.progress
       minutes = Math.ceil(left / 60);
@@ -69,12 +80,10 @@

   playState: ->
     if typeof(window.player) != "undefined"
-      data = $(window.player.domNode).data()
-      duration = window.player.duration
-      if !isNaN(duration)
-        feedbin.setDuration(data.entryId, duration)
+      if feedbin.hasDuration()
+        feedbin.setDuration(feedbin.nowPlayingData.entryId, window.player.duration)

-      play = $("[data-behavior~=audio_play_#{data.entryId}]")
+      play = $("[data-behavior~=audio_play_#{feedbin.nowPlayingData.entryId}]")
       if window.player.paused
         play.addClass('paused')
         play.removeClass('playing')
@@ -106,17 +115,14 @@
         else
           size = feedbin.data.audio_panel_size || "minimized"
           $('body').addClass("audio-panel-#{size}")
-          data = $(window.player.domNode).data()
-          if data.entryId == $(@).data('entry-id')
+          if feedbin.nowPlayingData.entryId == $(@).data('entry-id')
             feedbin.togglePlay()
           else
             init()

     togglePanel: ->
       $(document).on 'click', '[data-behavior~=toggle_audio_panel]', (event) ->
-        console.log event
         if $(event.target).has('[data-behavior~=toggle_audio_panel]')
-          console.log 'yest'
           if $('body').hasClass('audio-panel-minimized')
             $('body').removeClass('audio-panel-minimized')
             $('body').addClass('audio-panel-maximized')
@@ -128,9 +134,6 @@
           form = $("[data-behavior~=audio_target] [data-behavior~=audio_panel_size]")
           form.find('#audio_panel_size').val(feedbin.data.audio_panel_size)
           form.submit()
-        else
-          console.log 'no'
-

     skipForward: ->
       $(document).on 'click', '[data-behavior~=audio_skip_forward]', (event) ->
@@ -141,7 +144,6 @@
       $(document).on 'click', '[data-behavior~=audio_skip_backward]', (event) ->
         feedbin.audioJump(-30)
         event.stopPropagation()
-

     playPause: ->
       $(document).on 'click', '[data-behavior~=audio_play]', (event) ->
@@ -160,9 +162,6 @@
         $('body').removeClass('audio-panel-maximized')
         event.stopPropagation()

-
-
-
 jQuery ->
   $.each feedbin.audioInit, (i, item) ->
     item()


d3 mekko: don't scale unit. Closes #870

d3 mekko: don't scale unit. Closes #870

--- app/assets/javascripts/d3/mekko.coffee
+++ app/assets/javascripts/d3/mekko.coffee
@@ -19,8 +19,7 @@
     label: => @get('label') || @get('gquery')
     key:   => "#{@get 'carrier'}_#{@get 'sector'}"
     tooltip_text: =>
-      "#{@get 'carrier'} #{@get 'sector'}
" +
-      Metric.autoscale_value @val(), 'MJ', 2
+      "#{@get 'carrier'} #{@get 'sector'}
#{parseInt @val()}PJ"

   NodeGroup: class extends Backbone.Model
       initialize: ->
@@ -136,7 +135,7 @@
           event: 'mouseout'  # silly IE
         position:
           my: 'bottom right'
-          at: 'top right'
+          at: 'top center'

     refresh: =>
       total_value = @node_list.grand_total()
@@ -159,7 +158,7 @@
         data(@sector_list.models, (d) -> d.get 'key' ).
         transition().duration(500).
         attr("dy", (d) => @x(d.total_value() / 2) + 5 ).
-        text((d) -> "#{d.get 'key'} #{Metric.autoscale_value d.total_value(), 'MJ', 2}")
+        text((d) -> "#{d.get 'key'} #{parseInt d.total_value()}PJ")

       # we need to track the offset for every sector
       offsets = {}


Get rid of math error logging.

Get rid of math error logging.

This only shows up in teardown and adds noise.

--- app/assets/javascripts/utils.js.coffee
+++ app/assets/javascripts/utils.js.coffee
@@ -25,8 +25,6 @@
     try
       max = Math.max.apply(Math, heights)
     catch error
-      console.log "Math error, setting height to 20"
-      console.log error
       max = 20

     $headers.css('height', max)


add: comments to docs.coffee

add: comments to docs.coffee

--- src/server/docs.coffee
+++ src/server/docs.coffee
@@ -1,10 +1,26 @@
+###
+@providesModule Docs
+###
+
 fs = require 'fs'
 config = require './stateInitializer/initializeStateConfig'

+
+###
+Convert TypeDoc json to Docs object
+
+@param {string} path to json
+###
 class Docs
-  constructor: ->
-    @json = JSON.parse(fs.readFileSync(config.typedoc.path_to_json))
+  constructor: (path)->
+    @json = JSON.parse(fs.readFileSync(path || config.typedoc.path_to_json))

+  ###
+  get global class typedoc json as object
+
+  @param {string|number} id of doc
+  @api public
+  ###
   getGlobalClassById: (id) ->
     for group, i in @json.groups
       if group.title == "External modules"


clean up unused/outdated comments

clean up unused/outdated comments

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -114,7 +114,6 @@

     asteroidTool:
       enter: ->
-        # console.log "STATE: \'asteroidTool/enter\'"
         @activateFrame 0
         # create new asteroid
         @currAsteroid = new Sighting({type:"asteroid"})
@@ -127,7 +126,6 @@
         @doneButton.prop 'disabled', true

       exit: ->
-        # console.log "STATE: \'asteroidTool/exit\'"
         @disableMarkingSurfaces()
         @el.find('.asteroid-classifier').hide()
         @doneButton.hide()
@@ -135,11 +133,9 @@

     artifactTool:
       enter: ->
-        # console.log "STATE: \'artifactTool/enter\'"
         @enableMarkingSurfaces()
         @el.find('.artifact-classifier').show()
       exit: ->
-        # console.log "STATE: \'artifactTool/exit\'"
         @disableMarkingSurfaces()
         @el.find('.artifact-classifier').hide()

@@ -153,7 +149,7 @@
     @el.attr 'flicker', "true"
     artifactSubtype = "other" # not sure what this is for?

-    @setState 'whatKind'      # set initial state
+    @setState 'whatKind'
     @invert = false
     @currFrameIdx = 0

@@ -183,13 +179,10 @@
       if @state is 'asteroidTool'
         # enforce one mark per frame
         if @asteroidMarkedInFrame[@currFrameIdx]
-          console.log 'frame already marked!'
-          # undo last mark
-          # @masterMarkingSurface.marks.pop().destroy()
+          # console.log 'frame already marked!'
           @destroyMarksInFrame @currFrameIdx, @currAsteroid.id
         else
-          console.log 'frame was empty'
-          # new mark
+          # console.log 'frame was empty'
           @el.find(".asteroid-frame-complete-#{@currFrameIdx+1}").prop 'checked', true
           @asteroidMarkedInFrame[@currFrameIdx] = true

@@ -197,7 +190,6 @@
         # this could probably be cleaned up
         numFramesComplete = 0
         for status in @asteroidMarkedInFrame
-          # console.log status
           if status is true
             numFramesComplete++
         if numFramesComplete is 4
@@ -305,7 +297,6 @@
     @startLoading()

   onSubjectSelect: (e, subject) =>
-    #reset the marking surface and load classifcation
     @resetMarkingSurfaces()
     @classification = new Classification {subject}
     @loadFrames()
@@ -435,31 +426,13 @@
     console.log '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'
     console.log 'onClickAsteroidNotVisible: '

-    # console.log 'completeChecked: ', @asteroidCompleteCheckboxes[@currFrameIdx].checked
-    # console.log 'visibleChecked: ', @asteroidVisibilityCheckboxes[@currFrameIdx].checked
-
     # get checkbox states
     completeChecked   = @asteroidCompleteCheckboxes[@currFrameIdx].checked
     visibilityChecked = @asteroidVisibilityCheckboxes[@currFrameIdx].checked

-
     if @asteroidMarkedInFrame[@currFrameIdx]
       @currAsteroid.clearSightingsInFrame @currFrameIdx
       @destroyMarksInFrame @currFrameIdx, @currAsteroid.id
-
-    # # this needs work!
-    # # handle checkmark behavior
-    # if @asteroidMarkedInFrame[@currFrameIdx] and visibilityChecked
-    #   console.log 'case 1'
-    #   @asteroidVisibilityCheckboxes[@currFrameIdx].checked = true
-    #   @asteroidCompleteCheckboxes[@currFrameIdx].checked = true
-    # else if @asteroidMarkedInFrame[@currFrameIdx] and not visibilityChecked
-    #   console.log 'case 2'
-    #   @currAsteroid.clearSightingsInFrame @currFrameIdx
-    #   @asteroidVisibilityCheckboxes[@currFrameIdx].checked = false
-    #   @asteroidCompleteCheckboxes[@currFrameIdx].checked = false
-    #   @currAsteroid.clearSightingsInFrame @currFrameIdx
-    #   @destroyMarksInFrame @currFrameIdx

     @updateIconsForNotVisible()

@@ -575,8 +548,7 @@
     @el.attr 'data-on-frame', @currFrameIdx

   hideAllFrames: ->
-    for i in [0...4]
-      @hideFrame(i)
+    @hideFrame(i) for i in [0...4]

   showFrame: (frame_idx) ->
     @hideAllFrames()


hide console logs

hide console logs

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -263,7 +263,7 @@
     @course.idx_last = 0

   handleSplitDesignation: ->
-    console.log '*** SETTING UP SPLIT DESIGNATION ***'
+    # console.log '*** SETTING UP SPLIT DESIGNATION ***'
     if User.current.project.splits?.mini_course_sup_tutorial?
       @splitDesignation = User.current.project.splits.mini_course_sup_tutorial
     else
@@ -272,26 +272,26 @@
     unless @getParameterByName("split") is ""
       @splitDesignation = @getParameterByName("split")

-    console.log '    SPLIT DESIGNATION IS: ', @splitDesignation
+    # console.log '    SPLIT DESIGNATION IS: ', @splitDesignation

     # SET MINI-COURSE INTERVAL
     if @splitDesignation in ['b', 'e', 'h', 'k']
-      console.log '    Setting mini-course interval to 5'
+      # console.log '    Setting mini-course interval to 5'
       @course.setRate 5
       $('#course-interval-setter').remove() # destroy custom course interval setter

     else if @splitDesignation in ['c', 'f', 'i', 'l']
-      console.log '    Setting mini-course interval to 10'
+      # console.log '    Setting mini-course interval to 10'
       @course.setRate 10
       $('#course-interval-setter').remove() # destroy custom course interval setter

     else if @splitDesignation in ['a', 'd', 'g', 'j']
-      console.log '    Setting mini-course interval to 5'
+      # console.log '    Setting mini-course interval to 5'
       # console.log 'Allowing custom course interval.'
       @course.setRate 5 # set default
       @allowCustomCourseInterval = true
     else
-      console.log '    Setting mini-course interval to 5 (default)'
+      # console.log '    Setting mini-course interval to 5 (default)'
       @allowCustomCourseInterval = false
       @course.setRate 5 # set default

@@ -509,8 +509,8 @@
     @showSummaryScreen()

   onClickNextSubject: ->
-    console.log 'COUNT: ', @course.count # DEBUG CODE
-    console.log 'SIM COUNT: ', @sim_count
+    # console.log 'COUNT: ', @course.count # DEBUG CODE
+    # console.log 'SIM COUNT: ', @sim_count
     @hideMarkingButtons()
     @course.prompt_el.hide()
     @classifySummary.fadeOut(150)
@@ -543,12 +543,12 @@
     @sim_rate = 0.20

     sim_roll = Math.random()
-    console.log "sim roll #{sim_roll} rate #{@sim_rate}"
+    # console.log "sim roll #{sim_roll} rate #{@sim_rate}"

     if Math.random() < @sim_rate
       Subject.group = SIMULATION_GROUP
       Subject.fetch limit: 1, (subjects) ->
-        console.log "got sim subjects ", subjects
+        # console.log "got sim subjects ", subjects
         Subject.current?.destroy()
         subjects[0].select()
         Subject.group = MAIN_SUBJECT_GROUP
@@ -704,7 +704,7 @@
     @classification.annotate
       recordedClickEvents: [@recordedClickEvents...]

-    console.log JSON.stringify( @classification ) # DEBUG CODE
+    # console.log JSON.stringify( @classification ) # DEBUG CODE

     # send classification (except for tutorial subject)
     unless @classification.subject.id is 'TUTORIAL_SUBJECT'


Delete subjects before adding training

Delete subjects before adding training

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -715,9 +715,10 @@

     if @shouldShowTraining()
       app.api.get("projects/asteroid/groups/#{TRAINING_SUBJECT_GROUP}/subjects").then (subjects) ->
-        subject = new zooniverse.models.Subject subjects[0]
-        queued = zooniverse.models.Subject.instances.pop()
-        zooniverse.models.Subject.instances.unshift queued
+        Subject.current.destroy
+        subject = new Subject subjects[0]
+        queued = Subject.instances.pop()
+        Subject.instances.unshift queued
         subject.select()
     else
       Subject.next()


Document TextBuffer API

Document TextBuffer API

--- src/text-buffer.coffee
+++ src/text-buffer.coffee
@@ -9,6 +9,8 @@
 BufferPatch = require './buffer-patch'
 {spliceArray} = require './helpers'

+# Public: A mutable text container with undo/redo support and the ability to
+# annotate logical regions in the text.
 module.exports =
 class TextBuffer
   @Point: Point
@@ -24,6 +26,8 @@
   @delegatesMethods 'markRange', 'markPosition', 'getMarker', 'getMarkers',
     'findMarkers', toProperty: 'markers'

+  # Public:
+  # * text: An optional string of Text with which to initialize the buffer.
   constructor: (params) ->
     text = params if typeof params is 'string'
     @lines = ['']
@@ -33,49 +37,79 @@
     @history = params?.history ? new History(this)
     @markers = params?.markers ? new MarkerManager(this)

+  # Private: Called by {Serializable} mixin during deserialization.
   deserializeParams: (params) ->
     params.markers = MarkerManager.deserialize(params.markers, buffer: this)
     params.history = History.deserialize(params.history, buffer: this)
     params

+  # Private: Called by {Serializable} mixin during serialization.
   serializeParams: ->
     text: @getText()
     markers: @markers.serialize()
     history: @history.serialize()

+  # Public: Returns a {String} representing the entire contents of the buffer.
   getText: ->
     text = ''
     for row in [0..@getLastRow()]
       text += (@lineForRow(row) + @lineEndingForRow(row))
     text

+  # Public: Returns an {Array} of {String}s representing all the lines in the
+  # buffer, without line endings.
   getLines: ->
     @lines.slice()

+  # Public:
   isEmpty: ->
     @getLastRow() is 0 and @lineLengthForRow(0) is 0

+  # Public: Returns a {Number} representing the number of lines in the buffer.
   getLineCount: ->
     @lines.length

+  # Public: Returns a {Number} representing the last zero-indexed row number of
+  # the buffer.
   getLastRow: ->
     @getLineCount() - 1

+  # Public: Returns a {String} representing the contents of the line at the
+  # given row.
+  #
+  # * row - A {Number} representing a zero-indexed row.
   lineForRow: (row) ->
     @lines[row]

+  # Public: Returns a {String} representing the line ending for the given row.
+  #
+  # * row - A {Number} indicating the row.
+  #
+  # Returns '\n', '\r\n', or '' for the last line of the buffer.
   lineEndingForRow: (row) ->
     @lineEndings[row]

+  # Public: Returns a {Number} representing the line length for the given row,
+  # exclusive of its line-ending character(s).
+  #
+  # row - A {Number} indicating the row.
   lineLengthForRow: (row) ->
     @lines[row].length

+  # Public: Sets the text in the given range.
+  #
+  # * range: A {Range}
+  # * text: A {String}
+  #
+  # Returns the {Range} of the inserted text.
   setTextInRange: (range, text) ->
     patch = @buildPatch(range, text)
     @history?.recordNewPatch(patch)
     @applyPatch(patch)
     patch.newRange

+  # Private: Builds a {BufferPatch}, which is used to modify the buffer and is
+  # also pushed into the undo history so it can be undone.
   buildPatch: (oldRange, newText) ->
     oldRange = Range.fromObject(oldRange)
     oldText = @getTextInRange(oldRange)
@@ -84,6 +118,8 @@
     @markers?.handleBufferChange(patch)
     patch

+  # Private: Applies a {BufferPatch} to the buffer based on its old range and
+  # new text. Also applies any {MarkerPatch}es associated with the {BufferPatch}.
   applyPatch: ({oldRange, newRange, oldText, newText, markerPatches}) ->
     startRow = oldRange.start.row
     endRow = oldRange.end.row
@@ -122,6 +158,7 @@
     @markers?.resumeChangeEvents()
     @emit 'markers-updated'

+  # Public: Returns a {String} of text in the given {Range}.
   getTextInRange: (range) ->
     range = @clipRange(Range.fromObject(range))
     startRow = range.start.row
@@ -143,6 +180,15 @@
         text += @lineEndingForRow(row)
       text

+  # Public: Clips the given range so it starts and ends at valid positions if
+  # its start or end are out of bounds. For example, the position [1, 100] is
+  # out of bounds if the line at row 1 is only 10 characters long, and it would
+  # be clipped to (1, 10).
+  #
+  # * range: A {Range} to clip.
+  #
+  # Returns: The given {Range} if it is already in bounds, or a new clipped
+  # {Range} if the given range is out-of-bounds.
   clipRange: (range) ->
     range = Range.fromObject(range)
     start = @clipPosition(range.start)
@@ -152,6 +198,9 @@
     else
       new Range(start, end)

+  # Public: Clips the given point so it is at a valid position in the buffer.
+  # For example, the position (1, 100) is out of bounds if the line at row 1 is
+  # only 10 characters long, and it would be clipped to (1, 10)
   clipPosition: (position) ->
     position = Point.fromObject(position)
     {row, column} = position
@@ -166,13 +215,18 @@
       else
         new Point(row, column)

+  # Public: Returns a {Point} at [0, 0]
   getFirstPosition: ->
     new Point(0, 0)

+  # Public: Returns a {Point} representing the maximal position in the buffer.
   getLastPosition: ->
     lastRow = @getLastRow()
     new Point(lastRow, @lineLengthForRow(lastRow))

+  # Public: Given a {Point} representing a position in the buffer, returns a
+  # {Number} representing the absolute character offset of that location in the
+  # buffer, inclusive of newlines. The position is clipped prior to translating.
   characterIndexForPosition: (position) ->
     {row, column} = @clipPosition(Point.fromObject(position))

@@ -182,6 +236,10 @@
     {characters} = @offsetIndex.totalTo(row, 'rows')
     characters + column

+  # Public: Given a {Number} represting an absolute offset in the buffer,
+  # inclusive of newlines, returns a {Point} representing that numbers
+  # corresponding position in row/column coordinates. The offset is clipped
+  # prior to translating.
   positionForCharacterIndex: (offset) ->
     offset = Math.max(0, offset)
     offset = Math.min(@getMaxCharacterIndex(), offset)
@@ -192,5 +250,6 @@
     else
       new Point(rows, offset - characters)

+  # Public: Returns the length of the buffer in characters.
   getMaxCharacterIndex: ->
     @offsetIndex.totalTo(Infinity, 'rows').characters


Rename path variables to filePath

Rename path variables to filePath

--- src/text-buffer.coffee
+++ src/text-buffer.coffee
@@ -165,14 +165,14 @@

   # Sets the path for the file.
   #
-  # path - A {String} representing the new file path
-  setPath: (path) ->
-    return if path == @getPath()
+  # filePath - A {String} representing the new file path
+  setPath: (filePath) ->
+    return if filePath == @getPath()

     @file?.off()

-    if path
-      @file = new File(path)
+    if filePath
+      @file = new File(filePath)
       @subscribeToFile()
     else
       @file = null
@@ -188,12 +188,12 @@

   # Saves the buffer at a specific path.
   #
-  # path - The path to save at.
-  saveAs: (path) ->
-    unless path then throw new Error("Can't save buffer with no file path")
+  # filePath - The path to save at.
+  saveAs: (filePath) ->
+    unless filePath then throw new Error("Can't save buffer with no file path")

     @emit 'will-be-saved', this
-    @setPath(path)
+    @setPath(filePath)
     @cachedDiskContents = @getText()
     @file.write(@getText())
     @conflict = false


Fix typo

Fix typo

--- src/text-editor.coffee
+++ src/text-editor.coffee
@@ -3036,7 +3036,7 @@

   autoIndentBufferRow: (bufferRow, options) -> @languageMode.autoIndentBufferRow(bufferRow, options)

-  autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startNow, endRow)
+  autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startRow, endRow)

   autoDecreaseIndentForBufferRow: (bufferRow) -> @languageMode.autoDecreaseIndentForBufferRow(bufferRow)


Add quotes

Add quotes

Multiple additions to the library of classic Simpsons' quotes.

--- src/thesimpsons.coffee
+++ src/thesimpsons.coffee
@@ -118,6 +118,60 @@
    "I was saying \"Boo-urns.\" -Hans Moleman",
    "I can't promise I'll try, but I'll try to try. -Bart Simpson",
    "To alcohol! The cause of, and solution to, all of life's problems. -Homer Simpson"
+   "Oh boy, Liver! Iron helps us play! - Rod and Todd"
+   "Look at those poor saps back on land with their laws and ethics! They'll never know the simple joys of a monkey knife fight. - Home Simpson"
+   "Beer. Now there's a temporary solution. - Homer Simpson"
+   "All right, brain. You don't like me and I don't like you, but let's just do this and I can get back to killing you with beer. - Homer Simpson"
+   "And how is education supposed to make me feel smarter? Besides, every time I learn something new, it pushes some old stuff out of my brain. Remember when I took that home winemaking course, and I forgot how to drive? - Homer Simpson"
+   "I hope I didn't brain my damage. - Homer Simpson"
+   "Oh, Lisa, you and your stories: Bart's a vampire, beer kills brain cells. Now let's go back to that... building... thingie... where our beds and TV... is. - Homer Simpson"
+   "What are you gonna do? Sick your dogs on me? Or your bees? Or dogs with bees in their mouth so when they bark they shoot bees at me? --Homer Simpson"
+   "I have misplaced my pants. - Homer Simpson"
+   "Mmmm, 52 slices of American cheese. - Homer Simpson"
+   "Mmmm, forbidden donut. - Homer Simpson"
+   "Mmmm, free goo. - Homer Simpson"
+   "Mmmm, Gummy-beer. - Homer Simpson"
+   "Mmmm, purple. - Homer Simpson"
+   "Mmmm, sacrilicious. - Homer Simpson"
+   "Mmmm...fuzzy. - Homer Simpson"
+   "Mmmm...open faced club sand wedge. - Homer Simpson"
+   "Duff Man can't breathe! Oh no! - Duff Man"
+   "Ooh, sorry, kid, sorry. I'm not used to the laughter of children. It cuts through me like a dentist drill. But no, no, that was funny, that was funny taking away my dignity like that, ha ha ha. - Moe the Bartender"
+   "Everything's coming up Milhouse! - Milhouse"
+   "And this is the snack holder where I put my beverage or, if you will, cupcake. - Homer Simpson"
+   "My eyes. The goggles, they do nothing. - Radioactive Man"
+   "You go through life, you try to be nice to people, you struggle to resist the urge to punch em in the face, and for what? - Moe the Bartender"
+   "Hello Simpson. I'm riding the bus today because Mother hid my car keys to punish me for talking to a woman on the phone. She was right to do it. - Principal Skinner"
+   "Slow down sir. You're going to give yourself a skin failure. - Dr Nick Riviera"
+   "In his house, we obey the laws of thermodynamics. - Homer Simpson"
+   "Y'ello? You'll have to speak up, I'm wearing a towel. - Homer Simpson"
+   "Hmm. Your ideas are intriguing to me and I wish to subscribe to your newsletter. - Homer Simpson"
+   "I don't even believe in Jebus! Save me Jebus! - Homer Simpson"
+   "There's a 4:30 in the morning now? - Bart Simpson"
+   "Oh wow, windows. I don't think I could afford this place. - Otto"
+   "Shoplifting is a victimless crime, like punching someone in the dark. - Nelson Munz"
+   "Can't we have one meeting that doesn't end with us digging up a corpse? - Mayor Quimby"
+   "Um, can you repeat the part of the stuff...where you said about all the...things? - Homer Simpson"
+   "Honey, if we didn't turn it down for the cops, what chance do you have? - Homer Simpson"
+   "Oh boy, sleep! That's where I'm a Viking! - Ralph Wiggum"
+   "A shiny new donkey to the man who brings me the head of Homer Simpson! - Mr Burns"
+   "Sure, I'm flattered, maybe even a little curious, but the answer is no! - Homer Simpson"
+   "Oh, if only we'd listened to that young man, instead of walling him up in the abandoned coke oven. - Mr Burns"
+   "You've made a powerful enemy today, my friend. - Mr Burns"
+   "All right, let's make this sporting, Leonard. If you can tell me why I shouldn't fire you without using the letter "e," you can keep your job. - Mr Burns"
+   "Okay Mr. Burns Here are your messages: You have thirty minutes to move your car. You have ten minutes to move your car. Your car has been impounded. Your car has been crushed into a cube. You have thirty minutes to move your cube. - Homer Simpson"
+   "Ooh, don't poo-poo a nickel, Lisa. A nickel will buy you a steak and kidney pie, a cup of coffee, a slice of cheesecake and a newsreel... with enough change left over to ride the trolley from Battery Park to the polo grounds. - Mr Burns"
+   "Oh, so mother nature needs a favor? Well, maybe she should have thought of that when she was besetting us with droughts and floods and poison monkeys. - Mr Burns"
+   "Release the hounds. - Mr Burns"
+   "I'm afraid all of those players have retired and, uh... passed on. In fact, your right-fielder has been dead for a hundred and thirty years. - Mr Smithers"
+   "Smithers, this monkey is going to need most of your skin. - Mr Burns"
+   "Now to enjoy the Miami of Canada: Chicago. - Mr Burns"
+   "I'm afraid it's not that simple. As punishment for your desertion, it's company policy to give you the plague. - Mr Burns"
+   "Oh, Smithers. I would have said anything to get your stem cells. - Mr Burns"
+   "Oh, balderdash. It's not important how old you are on parchment, it's how old you feel in the humours! - Mr Burns"
+   "Compadres, it is imperative that we crush the freedom fighters before the start of the rainy season. And remember, a shiny new donkey for whomever brings me the head of Colonel Montoya. - Mr Burns"
+   "Have the Rolling Stones killed. - Mr Burns"
+   "Uh, did I say corpse hatch? I meant innocence tube. - Mr Burns"
 ]

 module.exports = (robot) ->


disable theme swtich

disable theme swtich

--- app/js/controllers/unlockwallet.coffee
+++ app/js/controllers/unlockwallet.coffee
@@ -1,7 +1,8 @@
 angular.module("app").controller "UnlockWalletController", ($scope, $rootScope, $interval, $location, $q, Wallet, Observer, Info, Growl) ->
     $rootScope.splashpage = true
-    Wallet.get_setting("interface_theme").then (result) ->
-        $rootScope.theme = if result && result.value then result.value else 'default'
+    $rootScope.theme = 'default'
+    # Wallet.get_setting("interface_theme").then (result) ->
+    #     $rootScope.theme = if result && result.value then result.value else 'default'

     $scope.stopIdleWatch()


fallback for erroring translations

fallback for erroring translations


model: fixed stray parse error

model: fixed stray parse error

The following:

  class Foo
     @bar = =>
       new @ aoe : 3

  Foo.bar()

fails to parse (with Unexpected 'CALL_START'). Whereas the same code with parens around the object after `new`, succeeds:

  class Foo
    @bar = =>
      new @(aoe : 3)

  Foo.bar()

--- coffee/src/model.coffee
+++ coffee/src/model.coffee
@@ -76,4 +76,4 @@
     new @ data

   @withShell = (shell) =>
-    new @ shell: shell.data
+    new @(shell: shell.data)


lod_and_effect: got the phe vs genotype plot working

  - Now need to re-calculate the QTL effect means and SEs using log10 insulin

--- lod_and_effect/lod_and_effect.coffee
+++ lod_and_effect/lod_and_effect.coffee
@@ -1,11 +1,17 @@
 # function that does all of the work
 draw = (data) ->
+
+  # take log of phenotype
+  log = (x) -> Math.log(x)/Math.LN10
+  for i of data.phevals
+    data.phevals[i] = log data.phevals[i]
+  data.phenotype = "log10 #{data.phenotype}"

   # dimensions of SVG
   w = 1350
   h = 450
   botLw = 650
-  pad = {left:60, top:20, right:40, bottom: 40}
+  pad = {left:60, top:40, right:40, bottom: 40}
   innerPad = 4
   wInner = []
   wInner[0] = w - pad.left - pad.right
@@ -30,6 +36,12 @@
   for i in [0..3]
     top[i] = pad.top
     bottom[i] = pad.top + hInner[i]
+
+  # jitter amounts for PXG plot
+  jitterAmount = (right[3] - left[3])/50
+  jitter = []
+  for i of data.phevals
+    jitter[i] = (2.0*Math.random()-1.0) * jitterAmount

   # colors definitions
   lightGray = d3.rgb(230, 230, 230)
@@ -232,6 +244,7 @@
          .attr("stroke", "black")
          .attr("stroke-width", "2")

+
   # background rectangles for each chromosome, alternate color
   chrRect = topsvg.append("g").selectAll("empty")
      .data(data.chr)
@@ -254,7 +267,6 @@

   nTicks = [10, 10, 6, 6]
   nLabels = [6, 6, 6, 6]
-  padMult = [0.15, 0.15, 0.25, 0.05]
   for j in [0..3]
     YaxisGrp[j].selectAll("empty")
                .data(yScale[j].ticks(nTicks[j]))
@@ -272,13 +284,9 @@
                .enter()
                .append("text")
                .text((d) -> d)
-               .attr("x", left[j] - pad.left*padMult[j])
+               .attr("x", left[j] - pad.left*0.05)
                .attr("y", (d) -> yScale[j](d))
-               .attr("class",
-                   if j == 3
-                      "alignright"
-                   else
-                      "axis")
+               .attr("class", "alignright")

   # y-axis titles
   ylab = ["LOD score", "LOD score", data.phenotype, data.phenotype]
@@ -329,7 +337,61 @@
           .x((d) -> xScale[1][j](d))
           .y((d,i) -> yScale[1](data.lod[j].lod[i]))

-  randomChr = data.chr[Math.floor(Math.random()*data.chr.length)]
+  randomDraw = (x) -> x[Math.floor(Math.random()*x.length)]
+
+  randomChr = randomDraw(data.chr)
+  randomMarker = randomDraw(data.markers[randomChr])
+
+  # initial phenotype vs genotype plot
+  initialPXG = (chr, marker) ->
+    botsvg.selectAll("empty")
+          .data(data.phevals)
+          .enter()
+          .append("circle")
+          .attr("class", "plotPXG")
+          .attr("cx", (d,i) ->
+              g = Math.abs(data.geno[marker][i])
+              sx = data.sex[i]
+              if(chr=="X")
+                return xScale[3](sx*2+g-1)+jitter[i]
+              xScale[3](sx*3+g-1)+jitter[i])
+          .attr("cy", (d) -> yScale[3](d))
+          .attr("r", "3")
+          .attr("fill", (d,i) ->
+              g = data.geno[marker][i]
+              return pink if g < 0
+              darkGray)
+           .attr("stroke", (d,i) ->
+               g = data.geno[marker][i]
+               return purple if g < 0
+               "black")
+          .attr("stroke-width", (d,i) ->
+               g = data.geno[marker][i]
+               return "2" if g < 0
+               "1")
+
+  # function to revise phenotype vs genotype plot
+  revPXG = (chr, marker) ->
+    botsvg.selectAll(".plotPXG")
+           .transition().duration(1000)
+           .attr("cx", (d,i) ->
+               g = Math.abs(data.geno[marker][i])
+               sx = data.sex[i]
+               if(chr=="X")
+                 return xScale[3](sx*2+g-1)+jitter[i]
+               xScale[3](sx*3+g-1)+jitter[i])
+           .attr("fill", (d,i) ->
+               g = data.geno[marker][i]
+               return pink if g < 0
+               darkGray)
+           .attr("stroke", (d,i) ->
+               g = data.geno[marker][i]
+               return purple if g < 0
+               "black")
+           .attr("stroke-width", (d,i) ->
+               g = data.geno[marker][i]
+               return "2" if g < 0
+               "1")

   botsvg.append("g").append("path")
        .attr("d", botlodcurve(randomChr)(data.lod[randomChr].pos))
@@ -344,7 +406,7 @@
         .attr("id", "botLtitle")
         .attr("fill", "blue")
   botsvg.append("text")
-        .attr("x", (left[2]+right[2])/2)
+        .attr("x", (left[2]+right[3])/2)
         .attr("y", pad.top/2)
         .text("")
         .attr("id", "botRtitle")
@@ -406,12 +468,28 @@
                  markerClick[td] = 1
                  d3.select(this).attr("opacity", 1).attr("fill",pink).attr("stroke",purple)
                  effectPlot chr, td
+                 revPXG chr, td
+                 unless randomMarker is ""
+                   d3.select("#circle#{randomMarker}")
+                     .attr("opacity", 0)
+                     .attr("fill",purple)
+                     .attr("stroke","none")
+                   randomMarker = ""

   dotsAtMarkers(randomChr)
+
+  # Initial "click" of the random marker
+  pos = data.lod[randomChr].pos[data.markerindex[randomChr][randomMarker]]
+  title = "#{randomMarker} (chr #{randomChr}, #{onedig(pos)} cM)"
+  d3.select("text#botRtitle").text(title)
+  d3.select("#circle#{randomMarker}").attr("opacity", 1).attr("fill",pink).attr("stroke",purple)
+  effectPlot randomChr, randomMarker
+  initialPXG randomChr, randomMarker

   # select chromosome for lower LOD detailed curve
   lastChr = randomChr
   topsvg.select("#rect#{randomChr}").attr("fill", pink)
+
   chrRect.on "click", (d) ->
              d3.select(this).attr("fill", pink)
              if lastChr != d


Adjust atom config.

Adjust atom config.

--- .atom/config.cson
+++ .atom/config.cson
@@ -91,11 +91,14 @@
     highlightInPanes: false
   "ide-php":
     memoryLimit: "512M"
+  "ide-typescript":
+    javascriptSupport: false
   linter:
     lintOnChange: false
     lintOnOpen: true
     lintPreviewTabs: false
   "linter-eslint":
+    autofix: {}
     disabling: {}
     global:
       eslintrcPath: ".eslintrc*"


Hides atom ide terminal message.

Hides atom ide terminal message.

--- .atom/config.cson
+++ .atom/config.cson
@@ -20,6 +20,7 @@
       cursorBlink: true
       cursorStyle: "bar"
       cyan: "#8cd0d3"
+      documentationMessage: false
       fontFamily: "Source Code Pro"
       green: "#60b48a"
       magenta: "#dc8cc3"


Add disable a html preview shortcut

Add disable a html preview shortcut

--- .atom/keymap.cson
+++ .atom/keymap.cson
@@ -19,3 +19,5 @@
 # You can find more information about keymaps in these guides:
 # * https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
 # * https://atom.io/docs/latest/advanced/keymaps
+'atom-workspace':
+  'ctrl-p': 'unset!'


Fix wrong method

Fix wrong method