_onIceConnectionStateChange() test for Remote.Peer

--- src/tests/spec/public/models/remote.peer.spec.coffee
+++ src/tests/spec/public/models/remote.peer.spec.coffee
@@ -283,7 +283,7 @@

 				expect(fakeController.server.emitTo).not.toHaveBeenCalled()

-			it 'should send valid candidates to the central server'
+			it 'should send valid candidates to the central server', ->
 				fakeCandidate = 'asghlbasv8og348iwb viosu'

 				peer = new Peer(fakeController, '1', true, FakeRTCPeerConnection)
@@ -297,9 +297,9 @@
 				callArgs = fakeController.server.emitTo.mostRecentCall.args
 				expect(callArgs.length).toBe(4)
 				expect(callArgs[0]).toBe('1')
-				expect(callArgs[0]).toBe('peer.addIceCandidate')
-				expect(callArgs[0]).toBe(fakeController.id)
-				expect(callArgs[0]).toBe(fakeCandidate)
+				expect(callArgs[1]).toBe('peer.addIceCandidate')
+				expect(callArgs[2]).toBe(fakeController.id)
+				expect(callArgs[3]).toBe(fakeCandidate)

 		describe 'when adding an ICE candidate', ->
 			it 'should relay the candidate to the RTC connection', ->
@@ -312,3 +312,48 @@
 				callArgs = peer._connection.addIceCandidate.mostRecentCall.args
 				expect(callArgs.length).toBe(1)
 				expect(callArgs[0]).toBe('a')
+
+		describe 'when the ICE connection state changes', ->
+			it 'should trigger a connect event when connected', ->
+				peer = new Peer(fakeController, '1', true, FakeRTCPeerConnection)
+				peer._connection.iceConnectionState = 'connected'
+
+				fakeEvent = {
+					a: '1'
+					b: '2'
+				}
+
+				success = false
+				peer.on('connect', ( thePeer, event ) ->
+						expect(thePeer).toEqual(peer)
+						expect(event).toEqual(fakeEvent)
+						success = true
+					)
+
+				peer._onIceConnectionStateChange(fakeEvent)
+
+				waitsFor(->
+						return success
+					, 1000)
+
+			it 'should trigger a disconnect event when not connected', ->
+				peer = new Peer(fakeController, '1', true, FakeRTCPeerConnection)
+				peer._connection.iceConnectionState = 'disconnected'
+
+				fakeEvent = {
+					a: '1'
+					b: '2'
+				}
+
+				success = false
+				peer.on('disconnect', ( thePeer, event ) ->
+						expect(thePeer).toEqual(peer)
+						expect(event).toEqual(fakeEvent)
+						success = true
+					)
+
+				peer._onIceConnectionStateChange(fakeEvent)
+
+				waitsFor(->
+						return success
+					, 1000)


Use `@command` to handle CommandPanel commands

--- src/extensions/command-panel/command-panel.coffee
+++ src/extensions/command-panel/command-panel.coffee
@@ -50,20 +50,20 @@
     @history ?= []
     @historyIndex = @history.length

-    @on 'command-panel:unfocus', => @rootView.focus()
-    @on 'command-panel:close', => @detach()
+    @command 'command-panel:unfocus', => @rootView.focus()
+    @command 'command-panel:close', => @detach()
+    @command 'command-panel:execute', => @execute()

-    @rootView.on 'command-panel:toggle', => @toggle()
-    @rootView.on 'command-panel:toggle-preview', => @togglePreview()
-    @rootView.on 'command-panel:execute', => @execute()
-    @rootView.on 'command-panel:find-in-file', => @attach("/")
-    @rootView.on 'command-panel:find-in-project', => @attach("Xx/")
-    @rootView.on 'command-panel:repeat-relative-address', => @repeatRelativeAddress()
-    @rootView.on 'command-panel:repeat-relative-address-in-reverse', => @repeatRelativeAddressInReverse()
-    @rootView.on 'command-panel:set-selection-as-regex-address', => @setSelectionAsLastRelativeAddress()
+    @rootView.command 'command-panel:toggle', => @toggle()
+    @rootView.command 'command-panel:toggle-preview', => @togglePreview()
+    @rootView.command 'command-panel:find-in-file', => @attach("/")
+    @rootView.command 'command-panel:find-in-project', => @attach("Xx/")
+    @rootView.command 'command-panel:repeat-relative-address', => @repeatRelativeAddress()
+    @rootView.command 'command-panel:repeat-relative-address-in-reverse', => @repeatRelativeAddressInReverse()
+    @rootView.command 'command-panel:set-selection-as-regex-address', => @setSelectionAsLastRelativeAddress()

-    @on 'core:move-up', => @navigateBackwardInHistory()
-    @on 'core:move-down', => @navigateForwardInHistory()
+    @command 'core:move-up', => @navigateBackwardInHistory()
+    @command 'core:move-down', => @navigateForwardInHistory()

     @previewList.hide()


webgl large numbers: also for *small* numbers

--- bokehjs/src/coffee/renderer/glyph/glyph.coffee
+++ bokehjs/src/coffee/renderer/glyph/glyph.coffee
@@ -46,8 +46,8 @@
     wx = wy = 1  # Weights to scale our vectors
     [dx, dy] = @renderer.map_to_screen([0*wx, 1*wx, 2*wx], [0*wy, 1*wy, 2*wy])
     # Try again, but with weighs so we're looking at ~100 in screen coordinates
-    wx = 100 / Math.max(Math.abs(dx[1] - dx[0]), 1e-12)
-    wy = 100 / Math.max(Math.abs(dy[1] - dy[0]), 1e-12)
+    wx = 100 / Math.min(Math.max(Math.abs(dx[1] - dx[0]), 1e-12), 1e12)
+    wy = 100 / Math.min(Math.max(Math.abs(dy[1] - dy[0]), 1e-12), 1e12)
     [dx, dy] = @renderer.map_to_screen([0*wx, 1*wx, 2*wx], [0*wy, 1*wy, 2*wy])
     # Test how linear it is
     if (Math.abs((dx[1] - dx[0]) - (dx[2] - dx[1])) > 1e-6 ||


Make ObjectExplorer.onEvent's debounce configurable

--- bokehjs/src/coffee/util/object_explorer.coffee
+++ bokehjs/src/coffee/util/object_explorer.coffee
@@ -10,17 +10,16 @@
   class ObjectExplorerView extends ContinuumView.View
     initialize: (options) ->
       super(options)
+      @onEvent = _.debounce(@onEvent, options.debounce or 200)
       @render()

     delegateEvents: (events) ->
       super(events)

-      onEvent = _.debounce(@onEvent, 200)
       for type in _.keys(Base.locations)
-        Base.Collections(type).on("all", onEvent)
+        Base.Collections(type).on("all", @onEvent)

     onEvent: (event) =>
-      console.log(event)
       @reRender()

     createTree: (nonempty=true) ->


Removed dead code

Removed dead code

--- core/app/backbone/views/evidence/add_evidence_form_view.coffee
+++ core/app/backbone/views/evidence/add_evidence_form_view.coffee
@@ -75,9 +75,3 @@

   showError: -> @$('.js-error').show()
   hideError: -> @$('.js-error').hide()
-
-  addFromFact: (from_fact)->
-    @createFactRelation new FactRelation
-      evidence_id: from_fact.id
-      from_fact: from_fact
-      created_by: currentUser.toJSON()


SocialWorker: remove unnecessary permissions

--- workers/social/lib/social/models/apitoken.coffee
+++ workers/social/lib/social/models/apitoken.coffee
@@ -26,9 +26,6 @@
     sharedEvents       :
       static           : []
       instance         : []
-    permissions        :
-      'edit groups'    : ['moderator']
-      'edit own groups': ['member', 'moderator']
     indexes            :
       code             : 'unique'
     sharedMethods      :


put a 5 second timeout in getting redis lock

--- services/document-updater/app/coffee/LockManager.coffee
+++ services/document-updater/app/coffee/LockManager.coffee
@@ -13,6 +13,8 @@
 PID = process.pid
 RND = crypto.randomBytes(4).toString('hex')
 COUNT = 0
+
+MAX_REDIS_REQUEST_LENGTH = 5000 # 5 seconds

 module.exports = LockManager =
 	LOCK_TEST_INTERVAL: 50 # 50ms between each test of the lock
@@ -37,8 +39,11 @@
 			return callback(err) if err?
 			if gotLock == "OK"
 				metrics.inc "doc-not-blocking"
-				profile.log("got lock").end()
-				callback err, true, lockValue
+				timeTaken = profile.log("got lock").end()
+				if timeTaken > MAX_REDIS_REQUEST_LENGTH
+					callback err, false # took too long to get the lock, bail out
+				else
+					callback err, true, lockValue
 			else
 				metrics.inc "doc-blocking"
 				profile.log("doc is locked").end()


fixed suggestions

fixed suggestions

--- src/smc-webapp/project_new.cjsx
+++ src/smc-webapp/project_new.cjsx
@@ -240,8 +240,11 @@
         e.preventDefault()
         if @state.filename[@state.filename.length - 1] == '/'
             @create_folder()
-        else if @refs.project_new_filename.getValue().split(".").length > 1
+        else if @refs.project_new_filename.getValue().includes('.')
             @create_file()
+        else
+            @setState(warning : true)
+            @refs.project_new_filename.getInputDOMNode().disabled = true

     render_header: ->
         if @props.current_path?
@@ -273,24 +276,16 @@
             on_error     : on_error
             switch_over  : true

-    keydown : (e) ->
-        if e.keyCode==13 and @refs.project_new_filename.getValue().split(".").length < 2
-            @setState(warning : true)
-            ReactDOM.findDOMNode(@refs.project_new_filename.refs.input).disabled = true
-
-    accept_file : ->
-        @create_file()
-
     decline_file : ->
         @setState(warning : false)
-        ReactDOM.findDOMNode(@refs.project_new_filename.refs.input).disabled = false
+        @refs.project_new_filename.getInputDOMNode().disabled = false
         @refs.project_new_filename.getInputDOMNode().focus()

     render_alert : ->
         <Alert bsStyle='warning' style={marginTop: '10px', fontWeight : 'bold'}>

Warning: Are you sure you want to create a file with no extensions?

             <ButtonToolbar>
-                <Button onClick={@accept_file} bsStyle='success'>
+                <Button onClick={@create_file} bsStyle='success'>
                     Create file
                 </Button>
                 <Button onClick={@decline_file} bsStyle='default'>
@@ -313,7 +308,6 @@
                         <Input
                             autoFocus
                             ref         = 'project_new_filename'
-                            onKeyDown   = {@keydown}
                             value       = @state.filename
                             type        = 'text'
                             placeholder = 'Name your file, folder, or paste in a link...'


Don’t assume SpacePen views implement ::unsubscribe

Signed-off-by: Max Brunsfeld <78036c9b69b887700d5846f26a788d53b201ffbb@gmail.com>

--- src/space-pen-extensions.coffee
+++ src/space-pen-extensions.coffee
@@ -7,7 +7,7 @@
 jQuery = SpacePen.jQuery
 JQueryCleanData = jQuery.cleanData
 jQuery.cleanData = (elements) ->
-  jQuery(element).view()?.unsubscribe() for element in elements
+  jQuery(element).view()?.unsubscribe?() for element in elements
   JQueryCleanData(elements)

 SpacePenCallRemoveHooks = SpacePen.callRemoveHooks


Allow default timeout to be overriden

Allow default timeout to be overriden

--- lib/assets/javascripts/oojspec.js.coffee
+++ lib/assets/javascripts/oojspec.js.coffee
@@ -3,6 +3,7 @@

 window.oojspec = new class OojspecRunner
   constructor: ->
+    @timeout = 1000 # 1s - default timeout
     @runner = buster.create buster.eventEmitter
     @descriptions = []
     @assertions = buster.assertions
@@ -254,7 +255,7 @@
     else
       @waitsFor step...

-  waitsFor: (@condition, timeout=1000, @description)->
+  waitsFor: (@condition, timeout = @binding?.timeout or oojspec.timeout, @description)->
     @deadline = timeout + new Date().getTime()
     @keepTryingCondition()


Activity: private message pane minor fixes

--- client/Social/Activity/views/privatemessage/pane.coffee
+++ client/Social/Activity/views/privatemessage/pane.coffee
@@ -1,6 +1,4 @@
 class PrivateMessagePane extends MessagePane
-
-  TEST_MODE = off

   constructor: (options = {}, data) ->

@@ -224,7 +222,6 @@

     (event) ->

-      return
       return  if inProgress

       inProgress   = true
@@ -389,8 +386,6 @@

     return  unless value

-    @applyTestPatterns value  if TEST_MODE
-
     super value, clientRequestId
     @input.empty()

@@ -431,8 +426,6 @@

   glance: ->

-    return
-
     super

     @newMessagesMark?.destroy()
@@ -448,20 +441,6 @@

   defaultFilter: 'Most Recent'
   setFilter: ->
-
-
-  #
-  # TEST STUFF
-  #
-
-  applyTestPatterns: (value) ->
-
-    if value.match /^\/unleashtheloremipsum/
-      [_, interval, batchCount] = value.split " "
-      [interval, batchCount] = helper.parse interval, batchCount
-      PrivateMessageLoadTest.run this, interval, batchCount
-    else if value.match /^\/analyzetheloremipsum/
-      PrivateMessageLoadTest.analyze this

   #


teams: credentials: warning copy change

teams: credentials: warning copy change

--- client/admin/lib/views/stacks/credentiallistitem.coffee
+++ client/admin/lib/views/stacks/credentiallistitem.coffee
@@ -33,9 +33,9 @@

     @warningView = new kd.CustomHTMLView
       cssClass : 'warning-message hidden'
-      partial  : "This credential couldn't verified, please check credential
-                  details or add a new credential to be able to continue
-                  to next step"
+      partial  : "We couldn't verify these credentials, please check the
+                  ones you used or add new credentials to be able to continue
+                  to the next step."

   setVerified: (state, reason) ->


Remove old event for associating IRs with event

--- client/controllers/incidentReports/incidentTable.coffee
+++ client/controllers/incidentReports/incidentTable.coffee
@@ -163,16 +163,6 @@
     selectedIncidents.remove({})
     event.currentTarget.blur()

-  'click .add': (event, instance) ->
-    instance.data.incidents.find({selected: true}).forEach (incident) ->
-      incident = _id: incident._id
-      incident.userEventId = Template.instance().data.sourceId.get()._str
-      Meteor.call 'updateIncidentReport', incident, false, (error, result) ->
-        if error
-          notify('error', 'There was a problem updating your incident reports.')
-          return
-      event.currentTarget.blur()
-
   'click .select-all': (event, instance) ->
     _updateAllIncidentsStatus(instance, true, event)


Remove success stories link from Teams page

--- client/landing/site.landing/coffee/teams/AppView.coffee
+++ client/landing/site.landing/coffee/teams/AppView.coffee
@@ -18,7 +18,6 @@
       navItems : [
         { title : 'Blog',            href : 'http://blog.koding.com',   name : 'blog' }
         { title : 'Teams',           href : '/Teams',                   name : 'teams' }
-        { title : 'Success Stories', href : '/Features',                name : 'success' }
         { title : 'SIGN IN',         href : '/Team/Login',              name : 'buttonized white login',  attributes : testpath : 'login-link' }
       ]


Use native browser confirm instead of jquery.alert

--- backend/app/assets/javascripts/spree/backend/taxonomy.js.coffee
+++ backend/app/assets/javascripts/spree/backend/taxonomy.js.coffee
@@ -60,16 +60,15 @@
   last_rollback = data.rlbk
   node = data.rslt.obj
   delete_url = "#{base_url}/#{node.prop("id")}"
-  jConfirm Spree.translations.are_you_sure_delete, Spree.translations.confirm_delete, (r) ->
-    if r
-      Spree.ajax
-        type: "DELETE",
-        dataType: "json",
-        url: delete_url,
-        error: handle_ajax_error
-    else
-      $.jstree.rollback(last_rollback)
-      last_rollback = null
+  if confirm(Spree.translations.are_you_sure_delete)
+    Spree.ajax
+      type: "DELETE",
+      dataType: "json",
+      url: delete_url,
+      error: handle_ajax_error
+  else
+    $.jstree.rollback(last_rollback)
+    last_rollback = null

 root = exports ? this
 root.setup_taxonomy_tree = (taxonomy_id) ->


fix (Copy) Add success and next step instructions for init

--- src/steroids/module/init.coffee
+++ src/steroids/module/init.coffee
@@ -19,3 +19,14 @@
     .then(refreshModule)
     .then ->
       Help.SUCCESS()
+      steroidsCli.log """
+        Module Development Harness connected to Composer 2 application!
+
+        NEXT:
+        =====
+
+        - Start development by connecting with Steroids:
+          Run `cd mobile && steroids connect`
+        - If your Composer 2 application configuration changes:
+          Run `steroids module refresh`
+      """


Update author

Update author

--- plugins/item-info/index.cjsx
+++ plugins/item-info/index.cjsx
@@ -21,6 +21,7 @@
   name: 'ItemInfo'
   priority: 51
   displayName: [<FontAwesome name='rocket' key={0} />, ' 装备信息']
+  author: [Yunze]
   description: '提供装备详细信息查看'
   handleClick: ->
     itemInfoWindow.show()


removed log

removed log

--- src/main/coffeescript/view/BasicAuthButton.coffee
+++ src/main/coffeescript/view/BasicAuthButton.coffee
@@ -12,7 +12,6 @@
     "click #apply_basic_auth" : "applyPassword"

   applyPassword: ->
-    console.log "applying password"
     username = $(".input_username").val()
     password = $(".input_password").val()
     window.authorizations.add(@model.type, new PasswordAuthorization("basic", username, password))


4241: Adjusted height

4241: Adjusted height

--- app/assets/javascripts/backbone/views/reservation_calendar_view.coffee
+++ app/assets/javascripts/backbone/views/reservation_calendar_view.coffee
@@ -12,7 +12,7 @@
     @calendar.fullCalendar
       events: options.feedUrl,
       defaultView: @initialViewType(options.viewType)
-      height: 500,
+      height: 700,
       allDaySlot: false,
       eventOverlap: false,
       selectable: true,


Add button js logic

Add button js logic

--- app/assets/javascripts/backend/purchase_process/purchase_orders.coffee
+++ app/assets/javascripts/backend/purchase_process/purchase_orders.coffee
@@ -24,4 +24,27 @@
         # !! so we're sure disabled is a Boolean and not just truthy/falsy — for jQuery
         $newParcelBtn.toggleClass('disabled', !!disabled)

+  $(document).ready ->
+    $('#unreceived_purchase_orders-list').each ->
+      $newParcelBtn = $('#generate-parcel-btn')
+      newParcelUrl = $newParcelBtn.prop('href')
+
+      $(document).on 'change', 'input[data-list-selector]', ->
+        selectedOrders = $('input[data-list-selector]:checked').filter ->
+                           /\d/.test($(this).data('list-selector'))
+        selectedOrdersIds = selectedOrders.map ->
+                              $(this).data('list-selector')
+                            .toArray()
+        reconciledOrders = selectedOrders.filter ->
+                             $(this).closest('tr').data('reconciliation-state') == 'reconcile'
+
+        if selectedOrdersIds.length > 0
+          $newParcelBtn.prop('href', "#{newParcelUrl}?mode=prefilled&purchase_order_ids=#{selectedOrdersIds}")
+        else
+          $newParcelBtn.prop('href', newParcelUrl)
+
+        disabled = !selectedOrders.length || reconciledOrders.length
+        # !! so we're sure disabled is a Boolean and not just truthy/falsy — for jQuery
+        $newParcelBtn.toggleClass('disabled', !!disabled)
+
 ) ekylibre, jQuery


kitra710.coffee: Change the getting started links

Signed-off-by: Florin Sarbu <3a837a37a2ac9072a088641ec330e0e5d5b86f4e@resin.io>

--- kitra710.coffee
+++ kitra710.coffee
@@ -33,9 +33,9 @@
 	].concat(postProvisioningInstructions)

 	gettingStartedLink:
-		windows: 'http://docs.resin.io/#/pages/installing/gettingStarted-RushUp-Kitra710.md#windows'
-		osx: 'http://docs.resin.io/#/pages/installing/gettingStarted-RushUp-Kitra710.md#on-mac-and-linux'
-		linux: 'http://docs.resin.io/#/pages/installing/gettingStarted-RushUp-Kitra710.md#on-mac-and-linux'
+		windows: 'https://docs.resin.io/kitra710/nodejs/getting-started/#adding-your-first-device'
+		osx: 'https://docs.resin.io/kitra710/nodejs/getting-started/#adding-your-first-device'
+		linux: 'https://docs.resin.io/kitra710/nodejs/getting-started/#adding-your-first-device'

 	supportsBlink: true


prevent route execution if context was suspended or stopped but not destroyed

--- modules/http/lib/Context.coffee
+++ modules/http/lib/Context.coffee
@@ -54,7 +54,9 @@

                         ##
                         @_addRoute '/boot.js', (req, res, next)=>
-
+                            if @_status.isSuspended || @_status.isStopped
+                                return next()
+
                             @_createRemote req, res, (err, remote)=>
                                 return next(err) if err || !remote


activity/flux: remove parent message related store code

--- client/activity/lib/flux/stores/messagesstore.coffee
+++ client/activity/lib/flux/stores/messagesstore.coffee
@@ -84,18 +84,13 @@
    * @param {string} payload.clientRequestId
    * @return {IMMessageCollection} nextState
   ###
-  handleCreateMessageBegin: (messages, { body, clientRequestId, messageId }) ->
+  handleCreateMessageBegin: (messages, { body, clientRequestId }) ->

     { createFakeMessage, addMessage } = MessageCollectionHelpers

     message = createFakeMessage clientRequestId, body

-    _message = toImmutable message
-
-    if messageId
-      _message.set 'parentId', messageId
-
-    return addMessage messages, _message
+    return addMessage messages, toImmutable message

   ###*
@@ -203,16 +198,13 @@
    * @param {SocialMessage} payload.comment
    * @return {IMMessageCollection} nextState
   ###
-  handleCreateCommentSuccess: (messages, { clientRequestId, comment, messageId }) ->
+  handleCreateCommentSuccess: (messages, { clientRequestId, comment }) ->

     { addMessage, removeFakeMessage } = MessageCollectionHelpers

     if clientRequestId
       messages = removeFakeMessage messages, clientRequestId

-    if messageId
-      comment.parentId = messageId
-
     return addMessage messages, toImmutable comment

@@ -224,11 +216,9 @@
    * @param {SocialMessage} payload.comment
    * @param {IMMessageCollection} nextState
   ###
-  handleLoadCommentSuccess: (messages, { messageId, comment }) ->
-
-    { addMessage } = MessageCollectionHelpers
-
-    comment.parentId = messageId
+  handleLoadCommentSuccess: (messages, { comment }) ->
+
+    { addMessage } = MessageCollectionHelpers

     return addMessage messages, toImmutable comment


fix refresh of zones on file changes

fix refresh of zones on file changes

--- src/app/common/partials/directives/file-uploader.coffee
+++ src/app/common/partials/directives/file-uploader.coffee
@@ -84,7 +84,7 @@
     #
     # Data required for each upload zone
     #
-    $scope.uploadZones = _.map $scope.files, (uploadData, uploadName) ->
+    updateUploadZones = (files) -> _.map files, (uploadData, uploadName) ->
       type = uploadData.type
       typeData = ACCEPTED_TYPES[type]
       # No typeData found?
@@ -105,6 +105,12 @@
           # Whether or not a reject error is shown
           error:  false
       zone
+
+    $scope.uploadZones = updateUploadZones $scope.files
+
+    # What for changes in the files, and recreate the zones when they do change
+    $scope.$watch 'files', (files, oldFiles) ->
+      $scope.uploadZones = updateUploadZones files

     #
     # Checks if okay to upload (i.e., file models exist for each drop zone)


removed app shorthand from profile controller since it was almost never used

--- core/app/backbone/controllers/profile_controller.coffee
+++ core/app/backbone/controllers/profile_controller.coffee
@@ -1,5 +1,3 @@
-app = FactlinkApp
-
 class window.ProfileController extends Backbone.Factlink.BaseController

   routes: ['showProfile', 'showNotificationSettings', 'showFact']
@@ -61,9 +59,9 @@
       main_region.show(new NotificationSettingsView model: user)

   showPage: (username, options) ->
-    app.leftBottomRegion.close()
+    FactlinkApp.leftBottomRegion.close()
     @main = new TabbedMainRegionLayout();
-    app.mainRegion.show(@main)
+    FactlinkApp.mainRegion.show(@main)
     @getUser username,
       onInit: (user) =>
         FactlinkApp.Sidebar.showForChannelsOrTopicsAndActivateCorrectItem(window.Channels, null, user)
@@ -99,7 +97,7 @@

   showSidebarProfile: (user) ->
     sidebarProfileView = new SidebarProfileView(model: user)
-    app.leftTopRegion.show(sidebarProfileView)
+    FactlinkApp.leftTopRegion.show(sidebarProfileView)

   makePermalinkEvent: ->
     FactlinkApp.factlinkBaseUrl = null


CADS-507 : Circs breaks in care Where-was-person-other and Where-where-you-other fixup char count. Tidy up only in order to log change to git. ( last commit bad message whoops )

--- c3/app/assets/javascripts/circs/report_changes/breaksFromCaring.coffee
+++ c3/app/assets/javascripts/circs/report_changes/breaksFromCaring.coffee
@@ -14,7 +14,6 @@
     hidePermanentBreakDate()

   if not $("#" + expectStartCaringY).prop("checked")
-#    hideExpectStartCaring()
     hideExpectStartCaringDate()
     hidePermanentBreakDate()


MachineSettingsModal: Fix modal height.

MachineSettingsModal: Fix modal height.

--- client/app/lib/providers/machinesettingsmodal.coffee
+++ client/app/lib/providers/machinesettingsmodal.coffee
@@ -37,7 +37,7 @@
     options.cssClass  = 'machine-settings-modal AppModal'
     options.title     = 'VM Settings'
     options.width     = 805
-    options.height    = 400
+    options.height    = 445
     options.overlay  ?= yes

     super options, data


Fix unit tests with logger.warn stub

Fix unit tests with logger.warn stub

--- test/unit/coffee/DiffManager/DiffManagerTests.coffee
+++ test/unit/coffee/DiffManager/DiffManagerTests.coffee
@@ -8,7 +8,7 @@
 describe "DiffManager", ->
 	beforeEach ->
 		@DiffManager = SandboxedModule.require modulePath, requires:
-			"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
+			"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), warn: sinon.stub() }
 			"./UpdatesManager": @UpdatesManager = {}
 			"./DocumentUpdaterManager": @DocumentUpdaterManager = {}
 			"./DiffGenerator": @DiffGenerator = {}


client: welcome: inviteTeam step only available to admin

--- client/home/lib/flux/stores/welcomestepsstore.coffee
+++ client/home/lib/flux/stores/welcomestepsstore.coffee
@@ -36,6 +36,16 @@
           description: 'You have a stack ready to go, go ahead and build it.'
           isDone: no
           order: 3
+        inviteTeam :
+          path: '/Home/My-Team'
+          title: 'Invite Your Team'
+          actionTitle: 'Invite'
+          videoLink: ''
+          # videoLink: '//www.koding.com/docs'
+          miniTitle: 'Invite Teammates'
+          description: 'Get your teammates working together.'
+          isDone: no
+          order: 10
       member :
         pendingStack :
           path: '#'
@@ -72,16 +82,6 @@
         #   description: "You are all set, watch our short video to know how to use Koding."
         #   isDone: no
         #   order: 0
-        inviteTeam :
-          path: '/Home/My-Team'
-          title: 'Invite Your Team'
-          actionTitle: 'Invite'
-          videoLink: ''
-          # videoLink: '//www.koding.com/docs'
-          miniTitle: 'Invite Teammates'
-          description: 'Get your teammates working together.'
-          isDone: no
-          order: 10
         installKd :
           path: '/Home/Koding-Utilities'
           title: 'Install KD'


Use CustomerFinder component

Use CustomerFinder component

--- client/skr/screens/customer-maint/CustomerMaint.cjsx
+++ client/skr/screens/customer-maint/CustomerMaint.cjsx
@@ -3,16 +3,6 @@
     dataObjects:
         customer: ->
             @props.customer || new Skr.Models.Customer
-        query: ->
-            new Lanes.Models.Query({
-                syncOptions:
-                    include: ['billing_address', 'shipping_address']
-                src: Skr.Models.Customer, fields: [
-                    {id:'id', visible: false}
-                    'code', 'name', 'notes',
-                    { id: 'open_balance', flex: 0.5, textAlign: 'center' }
-                ]
-            })

     getInitialState: ->
         commands: new Lanes.Screens.Commands(this, modelName: 'customer')
@@ -24,10 +14,8 @@
             <Lanes.Screens.CommonComponents
                 activity={@state} commands={@state.commands} model={@customer} />
             <BS.Row>
-                <LC.RecordFinder ref="finder" sm=4 autoFocus
-                    model={@customer}
-                    commands={@state.commands}
-                    query={@query} />
+                <Skr.Components.CustomerFinder sm=4 editOnly
+                    commands={@state.commands} customer={@customer} />
                 <LC.Input sm=8 name="name" model={@customer} />
             </BS.Row>
             <BS.Row>


push not append

push not append

--- client.coffee
+++ client.coffee
@@ -117,9 +117,9 @@
             query = {}
             wherestrs = []
             if options.where?
-                wherestrs.append( (name + '="' + value + '"') for name,value of options.where)
+                wherestrs.push( (name + '="' + value + '"') for name,value of options.where)
             if options.wherestr?
-                wherestrs.append wherestr
+                wherestrs.push wherestr
             query['where'] = '&'.join(wherestrs)
             if options.select?
                 query['sel'] = options.select.join(',')


Client: Activity: Added markUserAsTroll, unmarkUserAsTroll and BlockUser actiontypes

--- client/app/lib/flux/actions/actiontypes.coffee
+++ client/app/lib/flux/actions/actiontypes.coffee
@@ -6,4 +6,16 @@
   'SEARCH_USERS_BEGIN'
   'SEARCH_USERS_SUCCESS'
   'SEARCH_USERS_FAIL'
+
+  'MARK_USER_AS_TROLL_BEGIN'
+  'MARK_USER_AS_TROLL_SUCCESS'
+  'MARK_USER_AS_TROLL_FAIL'
+
+  'UNMARK_USER_AS_TROLL_BEGIN'
+  'UNMARK_USER_AS_TROLL_SUCCESS'
+  'UNMARK_USER_AS_TROLL_FAIL'
+
+  'BLOCK_USER_BEGIN'
+  'BLOCK_USER_SUCCESS'
+  'BLOCK_USER_FAIL'
 }


app/flux: add load private stack templates action

--- client/app/lib/flux/environment/actions.coffee
+++ client/app/lib/flux/environment/actions.coffee
@@ -9,6 +9,7 @@
 showError               = require 'app/util/showError'
 toImmutable             = require 'app/util/toImmutable'
 getGroup                = require 'app/util/getGroup'
+whoami                  = require 'app/util/whoami'
 environmentDataProvider = require 'app/userenvironmentdataprovider'

@@ -438,6 +439,24 @@
     templates = templates.filter (t) -> t.accessLevel is 'group'

     reactor.dispatch actions.LOAD_TEAM_STACK_TEMPLATES_SUCCESS, { query, templates }
+
+
+loadPrivateStackTemplates = ->
+
+  { reactor } = kd.singletons
+
+  query = { group: getGroup().slug, originId: whoami()._id }
+
+  reactor.dispatch actions.LOAD_PRIVATE_STACK_TEMPLATES_BEGIN, { query }
+
+  remote.api.JStackTemplate.some query, { limit: 30 }, (err, templates) ->
+
+    if err
+      reactor.dispatch actions.LOAD_PRIVATE_STACK_TEMPLATES_FAIL, { query, err }
+
+    templates = templates.filter (t) -> t.accessLevel is 'private'
+
+    reactor.dispatch actions.LOAD_PRIVATE_STACK_TEMPLATES_SUCCESS, { query, templates }

 module.exports = {
@@ -467,4 +486,5 @@
   dispatchCollaborationInvitationRejected
   dispatchSharedVMInvitationRejected
   loadTeamStackTemplates
+  loadPrivateStackTemplates
 }


reactivity: remove debug code

reactivity: remove debug code

--- client/app/lib/util/isReactivityEnabled.coffee
+++ client/app/lib/util/isReactivityEnabled.coffee
@@ -1,6 +1,6 @@
 kd = require 'kd'
 isKoding = require 'app/util/isKoding'

-module.exports = -> yes
+module.exports = -> not isKoding()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/active_bounds.coffee
+++ test/active_bounds.coffee
@@ -12,7 +12,7 @@
     width: 32
     height: 32

-
+  obj.include ActiveBou

 test "should remove objects outside of activeBounds", 2, ->
   obj = GameObject


client: home: fixed private stack listings

--- client/home/lib/stacks/components/privatestackslist/view.coffee
+++ client/home/lib/stacks/components/privatestackslist/view.coffee
@@ -1,7 +1,8 @@
-kd              = require 'kd'
-React           = require 'kd-react'
+kd = require 'kd'
+React = require 'kd-react'
 EnvironmentFlux = require 'app/flux/environment'
-KDReactorMixin  = require 'app/flux/base/reactormixin'
+KDReactorMixin = require 'app/flux/base/reactormixin'
+showStackEditor = require 'app/util/showStackEditor'

 List = require 'app/components/list'
 TimeAgo = require 'app/components/common/timeago'
@@ -24,17 +25,17 @@
     template = @props.templates.toList().get(rowIndex)

-

+

         {template.get 'title'}

         Last updated <TimeAgo from={template.getIn ['meta', 'modifiedAt']} />

-

-        <button onClick={kd.noop}>RE-INITIALIZE</button>
-

-

-        <button onClick={kd.noop}>LAUNCH</button>
+

+        RE-INITIALIZE
+        LAUNCH

@@ -50,5 +51,7 @@
       renderSectionHeaderAtIndex={@bound 'renderSectionHeaderAtIndex'}
       renderRowAtIndex={@bound 'renderRowAtIndex'}
       renderEmptySectionAtIndex={@bound 'renderEmptySectionAtIndex'}
+      sectionClassName='HomeAppViewStackSection'
+      rowClassName='stack-type'
     />


Remove refresh now button when its not needed

--- client/landing/app/MainApp/maincontroller/maincontroller.coffee
+++ client/landing/app/MainApp/maincontroller/maincontroller.coffee
@@ -294,8 +294,8 @@
         overlay : yes
         buttons :
           "Refresh Now" :
-            style     : "modal-clean-red"
-            callback  : ->
+            style       : "modal-clean-red"
+            callback    : ->
               modal.destroy()
               location.reload yes
       # if location.hostname is "localhost"
@@ -304,7 +304,8 @@
     checkConnectionState = ->
       unless connectedState.connected
         fail()
-    ->
+
+    return ->
       @utils.wait @getOptions().failWait, checkConnectionState
       @on "AccountChanged", =>
         KD.track "Connected to backend"
@@ -312,4 +313,6 @@
         if modal
           modal.setTitle "Connection Established"
           modal.$('.modalformline').html "<b>It just connected</b>, don't worry about this warning."
+          modal.buttons["Refresh Now"].destroy()
+
           @utils.wait 2500, -> modal?.destroy()


Update old user in downloadSubmits if it changed group

--- server/cron/downloadSubmits.coffee
+++ server/cron/downloadSubmits.coffee
@@ -105,7 +105,7 @@
             delete oldSubmit.source
             delete oldSubmit.results
         # we can't compare oldUser and newUser because they will have different rating, etc
-        if (oldSubmit and newSubmit and deepEqual(oldSubmit, newSubmit.toObject()) and oldUser)
+        if (oldSubmit and newSubmit and deepEqual(oldSubmit, newSubmit.toObject()) and oldUser and oldUser.userList == newUser.userList)
             logger.debug "Submit already in the database"
             return res


Prepare readPod spec for migration.

Prepare readPod spec for migration.

--- spec/javascripts/application/seeds_store_spec.js.coffee
+++ spec/javascripts/application/seeds_store_spec.js.coffee
@@ -58,7 +58,14 @@
     it 'counts n', (done) ->
       expect(@subject.countForAll()).eventually.equal(6).notify(done)
     it 'readPod', (done) ->
-      expect(@subject.readPod('c')).eventually
+      p = @subject.readPod('c').then (docs) ->
+        doc = docs[0]
+        [{
+          name: doc.name
+          category: doc.category
+          stars: doc.stars
+        }]
+      expect(p).eventually
         .eql([@listByName()[2]]).notify(done)
     describe 'updateCategories()', ->
       beforeEach (done) ->


remove semi colons from coffee script

remove semi colons from coffee script

--- spec/javascripts/backbone/models/project_spec.js.coffee
+++ spec/javascripts/backbone/models/project_spec.js.coffee
@@ -12,7 +12,7 @@

   describe "#update", ->
     beforeEach ->
-      @build_changed = jasmine.createSpy();
+      @build_changed = jasmine.createSpy()

     describe "when the project contains only build information", ->
       beforeEach ->
@@ -25,7 +25,8 @@
         expect(@project.get("build").get("code")).toEqual("NEW PROJ")

       it "should fire build change event", ->
-        expect(@build_changed).toHaveBeenCalled();
+        expect(@build_changed).toHaveBeenCalled()
+
       describe "when tracker information is then added", ->
         beforeEach ->
           attributes = {
@@ -59,10 +60,10 @@
         expect(@project.get("tracker").get("velocity")).toEqual(99)

       it "should fire build change event", ->
-        expect(@build_changed).toHaveBeenCalled();
+        expect(@build_changed).toHaveBeenCalled()

       it "should fire tracker change event", ->
-        expect(@tracker_changed).toHaveBeenCalled();
+        expect(@tracker_changed).toHaveBeenCalled()

   describe "#refresh", ->
     beforeEach ->


Appended tooltip with defer to show it properly in dom. Added cssName to tooltip element.

--- client/app/CommonViews/introductiontooltip.coffee
+++ client/app/CommonViews/introductiontooltip.coffee
@@ -24,8 +24,12 @@
       cssClass : "close-icon"
       click    : => @close()

-    parentView.setTooltip { view }
-    parentView.tooltip.show()
+    parentView.setTooltip {
+      view,
+      cssClass: "introduction-tooltip"
+    }
+    @utils.defer =>
+      parentView.tooltip.show()

   close: ->
     @storage.setValue @introId, yes


fix url - previous returns 404

fix url - previous returns 404

the url http://emberjs.com/guides/models/using-the-store returns a 404

--- lib/generators/templates/store.js.coffee
+++ lib/generators/templates/store.js.coffee
@@ -1,4 +1,5 @@
-# http://emberjs.com/guides/models/using-the-store/
+# http://emberjs.com/guides/models/#toc_store
+# http://emberjs.com/guides/models/pushing-records-into-the-store/

 <%= application_name.camelize %>.Store = DS.Store.extend({


 Merge branch 'master.popularTopics' into 'master'

i-am-interested-in-fixing-random-topics-and-all-stuff

--- workers/social/lib/social/models/activeitems.coffee
+++ workers/social/lib/social/models/activeitems.coffee
@@ -65,7 +65,7 @@
     group = options.group or "koding"
     {select: selector} = nameMapping.topic
     selector.group = group
-    JTag.some selector, {limit:10}, callback
+    JTag.some selector, {limit:10, "counts.followers":-1}, callback

   @_fetchUsers = (options={}, callback)->
     {client}   = options


Fix save method for markdown doc

Fix save method for markdown doc

--- workers/social/lib/social/models/markdowndoc.coffee
+++ workers/social/lib/social/models/markdowndoc.coffee
@@ -2,7 +2,7 @@

 module.exports = class JMarkdownDoc extends Module

-  {daisy} = require 'bongo'
+  {daisy, secure, ObjectId} = require 'bongo'

   @share()

@@ -11,6 +11,7 @@
       content   : String
       html      : String
       checksum  : String
+      origin    : ObjectId
     sharedMethods   :
       static        : ['generateHTML']

@@ -48,22 +49,16 @@
     Module::update.apply this, arguments

   save:->
-    @html = @generateHTML @content
+    @html     = JMarkdownDoc.generateHTML @content
+    @checksum = JMarkdownDoc.generateChecksum @content
     super

+  @create$ = secure (client, formData, callback)->
+    formData.origin = client.connection.delegate.getId()
+    @create formData, callback
+
   @create = (formData, callback)->
-    data = formData
-    markdownDoc = null
-
-    daisy queue = [
-      =>
-        data.checksum = @generateChecksum data.content
-        queue.next()
-      =>
-        markdownDoc = new @ data
-        queue.next()
-      ->
-        markdownDoc.save (err)->
-          if err then callback err
-          else callback null, markdownDoc
-    ]
+    markdownDoc = new @ formData
+    markdownDoc.save (err)->
+      if err then callback err
+      else callback null, markdownDoc


Server: minor: fixed error message

Server: minor: fixed error message

--- workers/social/lib/social/render/scriptblock.coffee
+++ workers/social/lib/social/render/scriptblock.coffee
@@ -122,11 +122,11 @@
       {nickname} = client.connection.delegate.profile
       bongoModels.JUser.one username: nickname, (err, user) ->
         if err
-          console.error message: "[scriptblock] user not found"
+          console.error '[scriptblock] user not found', err
           return queue.fin()

         if user then userId = user.getId()
-        else console.error message: "[scriptblock] user not found"
+        else console.error '[scriptblock] user not found', err
         queue.fin()
   ]


fix toggle results view

fix toggle results view

--- keymaps/data-atom.cson
+++ keymaps/data-atom.cson
@@ -8,5 +8,5 @@
 # For more detailed documentation see
 # https://atom.io/docs/latest/advanced/keymaps
 '.workspace':
-  'ctrl-alt-r': 'data-atom:toggle-view'
+  'ctrl-alt-r': 'data-atom:toggle-results-view'
   'f5': 'data-atom:execute'


Update deprecated selectors

Update deprecated selectors

--- keymaps/tree-view.cson
+++ keymaps/tree-view.cson
@@ -47,6 +47,6 @@
   'j': 'core:move-down'
   'i': 'tree-view:toggle-vcs-ignored-files'

-'.tree-view-dialog .mini.editor':
+'.tree-view-dialog atom-text-editor[mini]':
   'enter': 'core:confirm'
   'escape': 'core:cancel'


Removed unused variable

Removed unused variable

--- core/app/backbone/views/evidence/evidence_container_view.coffee
+++ core/app/backbone/views/evidence/evidence_container_view.coffee
@@ -79,7 +79,6 @@
     if Factlink.Global.signed_in
       @addRegion.show new AddEvidenceFormView
         collection: @collection.realEvidenceCollection
-        fact_id: @collection.fact.id
     else
       @learnMoreRegion.show new LearnMoreView


Remove unnecessary field fetching.

Remove unnecessary field fetching.

--- src/views/search-results.coffee
+++ src/views/search-results.coffee
@@ -91,8 +91,7 @@
         cycleSorting: (ev) ->
             @fullCollection.cycleComparator()
             @expansion = 2 * PAGE_SIZE
-            @fullCollection.fetchFields(0, @expansion, @getDetailedFieldset()).done =>
-                @render()
+            @render()

         onBeforeRender: ->
             @collection = new @fullCollection.constructor @fullCollection.slice(0, @expansion)
@@ -110,10 +109,8 @@
             if @requestedExpansion == newExpansion then return
             @requestedExpansion = newExpansion

-            fields = @getDetailedFieldset()
-            @fullCollection.fetchFields(@requestedExpansion - delta, @requestedExpansion, fields).done =>
-                @expansion = @requestedExpansion
-                @render()
+            @expansion = @requestedExpansion
+            @render()

         getDetailedFieldset: ->
             switch @resultType
@@ -131,19 +128,13 @@
             @parent = opts.parent
             @$more = null
             @requestedExpansion = 0
-            fields = @getDetailedFieldset()
             @ready = false
             @onlyResultType = opts.onlyResultType
+            @ready = true
             if opts.onlyResultType
                 @expansion = 2 * PAGE_SIZE
-                @fullCollection.fetchFields(0, @expansion, fields).done =>
-                    @ready = true
-                    @parent?.expand @resultType
-                    @render()
-            else
-                @fullCollection.fetchFields(0, EXPAND_CUTOFF, fields).done =>
-                    @ready = true
-                    @render()
+                @parent?.expand @resultType
+            @render()
             @listenTo @fullCollection, 'hide', =>
                 @hidden = true
                 @render()


Enable changing radius filter radius.

Enable changing radius filter radius.

--- src/views/search-results.coffee
+++ src/views/search-results.coffee
@@ -182,7 +182,7 @@
             if @collection.length
                 crumb = switch @collectionType
                     when 'search'
-                        t('sidebar.search_results')
+                        i18n.t('sidebar.search_results')
                     when 'radius'
                         if @position?
                             @position.humanAddress()


refactor

refactor

--- client/landing/app/CommonViews/DNDUploader.coffee
+++ client/landing/app/CommonViews/DNDUploader.coffee
@@ -9,6 +9,7 @@
     options.defaultPath or= "/home/#{KD.nick()}/Uploads"

     super options, data
+
     @reset()

     @setPath options.path  if options.path
@@ -20,12 +21,10 @@
       @on "drop",      => @unsetClass "hover"

     @on "uploadFile", (fsFile, percent)=>
-      finder = KD.getSingleton "finderController"
       filePath  = "[#{fsFile.vmName}]#{fsFile.path}"
-      finder.treeController.nodes[filePath]?.updateProgressView percent
+      @finder.treeController.nodes[filePath]?.updateProgressView percent

     @on "uploadStart", (fsFile)=>
-      finder = KD.getSingleton "finderController"
       filePath   = "[#{fsFile.vmName}]#{fsFile.path}"
       parentPath = "[#{fsFile.vmName}]#{fsFile.parentPath}"

@@ -34,18 +33,24 @@
         nodeView.once "abortProgress", => fsFile.abort yes

       fsFile._isBeingUploaded = yes
-      nodeView = finder.treeController.nodes[filePath]
+      nodeView = @finder.treeController.nodes[filePath]
       if nodeView
       then bindAbort()
       else
-        finder.treeController.on "NodeWasAdded", (nodeView)->
+        @finder.treeController.on "NodeWasAdded", (nodeView)->
           if nodeView.getData().path is filePath and fsFile._isBeingUploaded
             bindAbort()

-        fsFile.save "", -> finder.revealPath parentPath
+        fsFile.save "", -> @finder.revealPath parentPath

     @on "uploadEnd", (fsFile)->
       fsFile._isBeingUploaded = no
+
+  viewAppended: ->
+    super
+    @finder = KD.getSingleton "finderController"
+    tc      = @finder.treeController
+    @notify = tc.notify.bind tc

   reset: ->
     {uploadToVM, defaultPath, title} = @getOptions()
@@ -65,13 +70,10 @@
       for item in items
         itemEntry = item.webkitGetAsEntry?()
         if itemEntry.isDirectory
-          return new KDNotificationView
-            title: "Folder uploads not available for now."
+          return @notify "Folder uploads not available for now.", "error"

-    finder = KD.getSingleton "finderController"
-    {notify} = finder.treeController
     if files.length >= 20
-      notify """
+      @notify """
       Too many files to transfer!<br>
       Archive your files and try again.
       """, "error", """
@@ -84,7 +86,7 @@
       for file, index in files
         sizeInMb = file.size/1024/1024
         if sizeInMb > 100 && @getOptions().uploadToVM
-          notify "Too big file to upload.", "error", "Max 100MB allowed per file."
+          @notify "Too big file to upload.", "error", "Max 100MB allowed per file."
           continue
         reader = new FileReader
         reader.onloadend = do (file=files[index])=> (readEvent)=>
@@ -129,8 +131,7 @@
       </div>
     """
     if uploadToVM
-      finder = KD.getSingleton "finderController"
-      finder?.revealPath @path
+      @finder?.revealPath @path

     @addSubView new KDCustomHTMLView
       tagName   : "a"


Add Authservice mock to contact controller test


Remove extra line

Remove extra line

--- dpr.coffee
+++ dpr.coffee
@@ -81,7 +81,6 @@
   # Apply the settings
   dpr[name] = option for name, option of options

-
   # Turn readyScan on or off
   if $
     $[if dpr.readyScan then 'on' else 'off'] 'ready', dpr.scan


Fix device init help OS X command

Fix device init help OS X command

--- lib/actions/device.coffee
+++ lib/actions/device.coffee
@@ -155,7 +155,7 @@
 		You may have to unmount the device before attempting this operation.

 		In Mac OS X:
-			$ sudo diskutil unmount /dev/xxx
+			$ sudo diskutil unmountDisk /dev/xxx

 		In GNU/Linux:
 			$ sudo umount /dev/xxx


Disable mirror notice in iframe

Disable mirror notice in iframe

--- lib/Site.coffee
+++ lib/Site.coffee
@@ -439,8 +439,8 @@
     ctrlType = config.location.ctrlType
     if proxyRes.statusCode != 200 || req.method != 'GET' || ctrlType == 'iframe'
       config.enableAppcache = false
-
-    config.showMirrorNotice = false if req.method != 'GET'
+      config.showMirrorNotice = false
+
     headers = proxyRes.headers
     #delete headers['expires'] # for firefox
     #delete headers['last-modified']


update to latest words

update to latest words

--- shared/src/helpers/step-helps.cjsx
+++ shared/src/helpers/step-helps.cjsx
@@ -1,5 +1,6 @@
 React = require 'react'
 _ = require 'underscore'
+capitalize = require 'lodash/capitalize'

 PERSONALIZED_GROUP = 'personalized'
 SPACED_PRACTICE_GROUP = 'spaced practice'
@@ -68,17 +69,15 @@

 getIntroText[TWO_STEP_ALIAS] = (project) ->
   [
-
Research shows quizzing yourself is a great way to boost learning.

-
Step 1: Free response

+
Research shows a great way to boost learning is to try recalling what you have learned.

+
Step 1: Free response for longer lasting learning

-      Read the question, then construct an answer in the
-      free response box. Recalling knowledge from memory (rather than looking up
-      the answer or recognizing it in a list) helps your learning last longer.
+      Help your learning last longer by constructing an answer in the free response box from memory.
+      For greatest benefit, try not to refer to notes or text.

-
Step 2: Multiple choice

+
Step 2: {capitalize(getProject(project).feedbackType)} with multiple choice

-      Then select the best multiple choice answer so
-      {getProject(project).name} can give you {getProject(project).feedbackType}.
+      Receive {getProject(project).feedbackType} by selecting the best multiple-choice option.

       Both you and your instructor can review your answers later.


remove console.log

remove console.log

--- src/node_modules/round-model/round-model.coffee
+++ src/node_modules/round-model/round-model.coffee
@@ -67,7 +67,6 @@
     getFixedCostCents: ->
       @fixedCostCents =
         _.reduce(_.pluck(@fixedCosts, "amount"), (sum, num) ->
-          console.log(sum, num)
           sum.plus(num or new Decimal(0))
         , new Decimal(0))
         .times(100).toFixed(0)


fix bug editor doc has different settings than paste

--- src/paste-manager.coffee
+++ src/paste-manager.coffee
@@ -27,7 +27,7 @@
       @container.innerHTML = ""
       @container.focus()
       _.defer( =>
-        doc = new ScribeDocument(@container)
+        doc = new ScribeDocument(@container, @editor.options)
         delta = doc.toDelta()
         # Need to remove trailing newline so paste is inline
         delta = delta.compose(Tandem.Delta.makeDeleteDelta(delta.endLength, delta.endLength - 1, 1))


dont apply transition to non-fullscreen superarticles

--- components/article/client/super_article.coffee
+++ components/article/client/super_article.coffee
@@ -41,5 +41,5 @@
     @$(".article-container[data-id=#{@article.get('id')}] #{selector}").waypoint (direction) =>
       if direction == 'down'
         $stickyHeader.addClass 'visible'
-      else
+      else unless $stickyHeader.hasClass('no-transition')
         $stickyHeader.removeClass 'visible'


Changes mocha test to use ntb_test database

--- test/database-spec.coffee
+++ test/database-spec.coffee
@@ -43,7 +43,7 @@
   db = col = null

   before (done) ->
-    database.connect null, (err, database) ->
+    database.connect 'ntb_test', (err, database) ->
       throw err if err
       db = database
       db.collection 'turer', (err, collection) ->


Use `@command` in MarkdownPreview extension

--- src/extensions/markdown-preview/markdown-preview.coffee
+++ src/extensions/markdown-preview/markdown-preview.coffee
@@ -15,11 +15,11 @@

   initialize: (@rootView) ->
     super
-    @rootView.on 'markdown-preview:attach', =>
+    @rootView.command 'markdown-preview:attach', =>
       path = rootView.getActiveEditor()?.getPath()
       @attach() if @isMarkdownFile(path)

-    @on 'markdown-preview:detach', => @detach()
+    @command 'markdown-preview:detach', => @detach()

   attach: ->
     @rootView.append(this)


Basic sorting of problems.

Basic sorting of problems.

--- picoCTF-web/web/coffee/management-problems.coffee
+++ picoCTF-web/web/coffee/management-problems.coffee
@@ -1,11 +1,37 @@
 Panel = ReactBootstrap.Panel
 Button = ReactBootstrap.Button
+ButtonGroup = ReactBootstrap.ButtonGroup
 Glyphicon = ReactBootstrap.Glyphicon
 Col = ReactBootstrap.Col
 Input = ReactBootstrap.Input
 Label = ReactBootstrap.Label
+PanelGroup = ReactBootstrap.PanelGroup
+Row = ReactBootstrap.Row

 update = React.addons.update
+
+SortableButton = React.createClass
+  propTypes:
+    name: React.PropTypes.string.isRequired
+
+  getInitialState: ->
+    ascending: true
+    focused: false
+
+  #TODO: Needs reworked.
+  handleClick: (e) ->
+    if not @state.focused and false
+      @setState update @state,
+        focused: $set: true
+    else
+      @setState update @state,
+        ascending: $set: !@state.ascending
+
+     @props.onSortChange @props.name, !@state.ascending
+
+  render: ->
+    glyph = if @state.ascending then <Glyphicon glyph="chevron-up"/> else <Glyphicon glyph="chevron-down"/>
+    <Button active={@props.active} onClick={@handleClick}>{@props.name} {glyph}</Button>

 ProblemFilter = React.createClass
   propTypes:
@@ -22,12 +48,25 @@

   render: ->
     glyph = <Glyphicon glyph="search"/>
-    <Input type='text' className="form-control"
-      ref="filter"
-      label="Search"
-      addonBefore={glyph}
-      onChange={@onChange}
-      value={@state.filter}/>
+    <Panel>
+      <Col xs={12}>
+        Search
+        <Input type='text' className="form-control"
+          ref="filter"
+          addonBefore={glyph}
+          onChange={@onChange}
+          value={@state.filter}/>
+      </Col>
+      <Col xs={12}>
+        <SortableButton name="score" onSortChange={@props.onSortChange}/>
+        <SortableButton name="name" onSortChange={@props.onSortChange}/>
+        <SortableButton name="category" onSortChange={@props.onSortChange}/>
+      </Col>
+    </Panel>
+
+ProblemClassifier = React.createClass
+  render: ->
+

 Problem = React.createClass
   getInitialState: ->
@@ -69,12 +108,33 @@

     </Panel>

+ProblemList = React.createClass
+  propTypes:
+    problems: React.PropTypes.array.isRequired
+
+  render: ->
+    if @props.problems.length == 0
+      return
No problems have been loaded. Click here to get started.

+
+    problemComponents = @props.problems.map (problem, i) ->
+      <Col xs={6} lg={4} key={i}>
+        <Problem {...problem}/>
+      </Col>
+
+

+      {problemComponents}
+

+
 ProblemTab = React.createClass
   propTypes:
     problems: React.PropTypes.array.isRequired

   getInitialState: ->
     filterRegex: /.*/
+    activeSort:
+      name: "score"
+      ascending: true
+    problemClassifier: (problem) -> true

   onFilterChange: (filter) ->
     try
@@ -84,31 +144,32 @@
     catch
       # We shouldn't do anything.

-  render: ->
+  onSortChange: (name, ascending) ->
+    @setState update @state,
+      activeSort: $set: {name: name, ascending: ascending}

-    if @props.problems.length == 0
-      return
No problems have been loaded. Click here to get started.

-
-    problems = _.filter @props.problems, ((problem) ->
+  filterProblems: (problems) ->
+    visibleProblems = _.filter problems, ((problem) ->
       @state.filterRegex.exec problem.name
     ).bind this

-    problemComponents = problems.map (problem, i) ->
-      <Col xs={6} lg={4} key={i}>
-        <Problem {...problem}/>
+    sortedProblems = _.sortBy visibleProblems, @state.activeSort.name
+    if @state.activeSort.ascending
+      sortedProblems
+    else
+      sortedProblems.reverse()
+
+  render: ->
+    <Row className="pad">
+      <Col xs={3} md={3}>
+        <Row>
+          <ProblemFilter onSortChange={@onSortChange} filter="" onFilterChange={@onFilterChange}/>
+        </Row>
+        <Row>
+          <ProblemClassifier/>
+        </Row>
       </Col>
-
-    filterDisplay =
-

-      <Col xs={3}>
-
Challenges

+      <Col xs={9} md={9}>
+        <ProblemList problems={@filterProblems(@props.problems)}/>
       </Col>
-      <Col xs={9} className="pad">
-        <ProblemFilter filter="" onFilterChange={@onFilterChange}/>
-      </Col>
-

-
-

-      {filterDisplay}
-      {problemComponents}
-

+    </Row>


Remove commented-out code and add test.

Remove commented-out code and add test.

--- cms/static/coffee/spec/views/overview_spec.coffee
+++ cms/static/coffee/spec/views/overview_spec.coffee
@@ -63,7 +63,6 @@
     afterEach ->
         delete window.analytics
         delete window.course_location_analytics
-        # @xhr.restore()
         @notificationSpy.reset()

     it "should save model when save is clicked", ->
@@ -83,6 +82,12 @@
       expect(deleteSpy).toHaveBeenCalled()
       expect(@requests[0].url).toEqual('/delete_item')

+    it "should not delete model when cancel is clicked", ->
+      deleteSpy = spyOn(window, '_deleteItem').andCallThrough()
+      $('a.delete-section-button').click()
+      $('a.action-secondary').click()
+      expect(@requests.length).toEqual(0)
+
     it "should show a confirmation on delete", ->
       $('a.delete-section-button').click()
       $('a.action-primary').click()


Decouple "mkdirp"

Decouple "mkdirp"

Make coffee completely independent.

--- command.coffee
+++ command.coffee
@@ -10,7 +10,6 @@
 helpers        = require './helpers'
 optparse       = require './optparse'
 CoffeeScript   = require './coffee-script'
-mkdirp         = require 'mkdirp'
 {spawn, exec}  = require 'child_process'
 {EventEmitter} = require 'events'

@@ -330,6 +329,20 @@
     dir = path.join opts.output, path.relative base, srcDir
   path.join dir, basename + extension

+# Recursively mkdir, like `mkdir -p`.
+mkdirp = (dir, fn) ->
+  mode = 0o777 & ~process.umask()
+
+  do mkdirs = (p = dir, fn) ->
+    fs.exists p, (exists) ->
+      if exists
+        fn()
+      else
+        mkdirs path.dirname(p), ->
+          fs.mkdir p, mode, (err) ->
+            return fn err if err
+            fn()
+
 # Write out a JavaScript source file with the compiled code. By default, files
 # are written out in `cwd` as `.js` files with the same name, but the output
 # directory can be customized with `--output`.


Use absolute paths in CLI

Use absolute paths in CLI

  * Use absolute paths for source files and target paths
  * Memorize and explicitly check for watched directories
  * Make path comparison and construction more precise and clear
  * Remove now unnecessary check for special relative paths

--- command.coffee
+++ command.coffee
@@ -58,6 +58,7 @@
 sources      = []
 sourceCode   = []
 notSources   = {}
+watchedDirs  = {}
 optionParser = null

 # Run `coffee` by parsing passed options and determining what action to take.
@@ -79,8 +80,12 @@
   literals = if opts.run then sources.splice 1 else []
   process.argv = process.argv[0..1].concat literals
   process.argv[0] = 'coffee'
+
+  opts.output = path.resolve opts.output  if opts.output
+  opts.join   = path.resolve opts.join    if opts.join
   for source in sources
-    compilePath source, yes, path.normalize source
+    source = path.resolve source
+    compilePath source, yes, source

 # Compile a path, which could be a script or a directory. If a directory
 # is passed, recursively compile all '.coffee', '.litcoffee', and '.coffee.md'
@@ -221,6 +226,7 @@
 watchDir = (source, base) ->
   readdirTimeout = null
   try
+    watchedDirs[source] = yes
     watcher = fs.watch source, ->
       clearTimeout readdirTimeout
       readdirTimeout = wait 25, ->
@@ -231,7 +237,7 @@
             return unwatchDir source, base
           for file in files when not hidden(file) and not notSources[file]
             file = path.join source, file
-            continue if sources.some (s) -> s.indexOf(file) >= 0
+            continue if file in sources or watchedDirs[file]
             sources.push file
             sourceCode.push null
             compilePath file, no, base
@@ -239,8 +245,9 @@
     throw e unless e.code is 'ENOENT'

 unwatchDir = (source, base) ->
+  delete watchedDirs[source]
   prevSources = sources[..]
-  toRemove = (file for file in sources when file.indexOf(source) >= 0)
+  toRemove = (file for file in sources when source is path.dirname file)
   removeSource file, base, yes for file in toRemove
   return unless sources.some (s, i) -> prevSources[i] isnt s
   compileJoin()
@@ -263,8 +270,12 @@
 outputPath = (source, base, extension=".js") ->
   basename  = helpers.baseFileName source, yes, useWinPathSep
   srcDir    = path.dirname source
-  baseDir   = if base in ['.', './'] then srcDir else srcDir.substring base.length
-  dir       = if opts.output then path.join opts.output, baseDir else srcDir
+  if not opts.output
+    dir = srcDir
+  else if source is base
+    dir = opts.output
+  else
+    dir = path.join opts.output, path.relative base, srcDir
   path.join dir, basename + extension

 # Write out a JavaScript source file with the compiled code. By default, files


fix for array

fix for array

--- coffeescript/004-webworkers/multiplication.coffee
+++ coffeescript/004-webworkers/multiplication.coffee
@@ -6,9 +6,10 @@
 define [
   'underscore'
 ], (_) ->
+    self.postMessage('before binding')
     self.onmessage = (e) ->
         self.postMessage('hello from worker!')
-        result = _.reduce(_.values(e.data.split(',')), ((memo, elem) -> memo * elem), 1)
+        result = _.reduce(e.data[1], ((memo, elem) -> memo * elem), 1)
         self.postMessage(result)
         false
     self.postMessage('after binding')


Killed redundant require

Killed redundant require

--- src/zombie/jsdom_patches.coffee
+++ src/zombie/jsdom_patches.coffee
@@ -2,7 +2,6 @@
 core = require("jsdom").dom.level3.core
 URL = require("url")
 http = require("http")
-html5 = require("html5").HTML5

 core.HTMLElement.prototype.__defineGetter__ "offsetLeft",   -> 0


Issue #665. Recompile on --watch when file changes size, or mtime changes.

--- command.coffee
+++ command.coffee
@@ -133,7 +133,7 @@
 # such as `--lint` or `--print`.
 watch = (source, base) ->
   fs.watchFile source, {persistent: true, interval: 500}, (curr, prev) ->
-    return if curr.mtime.getTime() is prev.mtime.getTime()
+    return if curr.size is prev.size and curr.mtime.getTime() is prev.mtime.getTime()
     fs.readFile source, (err, code) ->
       throw err if err
       compileScript(source, code.toString(), base)


Simplify `removeSource` and make it synchronous

--- command.coffee
+++ command.coffee
@@ -259,11 +259,11 @@
   sourceCode.splice index, 1
   if removeJs and not opts.join
     jsPath = outputPath source, base
-    fs.exists jsPath, (itExists) ->
-      if itExists
-        fs.unlink jsPath, (err) ->
-          throw err if err and err.code isnt 'ENOENT'
-          timeLog "removed #{source}"
+    try
+      fs.unlinkSync jsPath
+    catch err
+      throw err unless err.code is 'ENOENT'
+    timeLog "removed #{source}"

 # Get the corresponding output JavaScript path for a source file.
 outputPath = (source, base, extension=".js") ->


Fixed deleting friends and groups

Fixed deleting friends and groups

--- lib/atox-toxWorker.coffee
+++ lib/atox-toxWorker.coffee
@@ -328,7 +328,7 @@
       return @err "Failed to delete group chat", error.stack

     @groups[e.gID].destructor() if @groups[e.gID].destructor?
-    @groups.splice e.gID
+    @groups.splice e.gID, 1
     @inf "Removed group chat #{e.gID}"

   groupInviteCB: (e) ->
@@ -519,7 +519,7 @@

     @friends[e.fID].destructor()
     @inf "Deleted friend #{@friends[e.fID].getName()}"
-    @friends.splice e.fID
+    @friends.splice e.fID, 1

   sendToFriend: (e) ->
     try


Add atom prefix to project

Add atom prefix to project

--- lib/bookmarks-view.coffee
+++ lib/bookmarks-view.coffee
@@ -34,7 +34,7 @@
   populateBookmarks: ->
     bookmarks = []
     attributes = class: 'bookmark'
-    for buffer in project.getBuffers()
+    for buffer in atom.project.getBuffers()
       for marker in buffer.findMarkers(attributes)
         bookmark = {marker, buffer}
         bookmark.fitlerText = @getFilterText(bookmark)


refactor: Don't use JQuery to find the parent tr node

--- app/web/caretaker-data-table/caretaker-data-table.coffee
+++ app/web/caretaker-data-table/caretaker-data-table.coffee
@@ -1,5 +1,7 @@
 eventToItemId = (e) ->
-  $(e.target).parents('tr')[0].attributes['data-item-id'].value
+  rowNode = e.target.parentNode
+  rowNode = rowNode.parentNode while rowNode.localName != 'tr'
+  rowNode.attributes['data-item-id'].value

 Polymer 'caretaker-data-table',


fix writeCommandTable to async editor.save aware from Atom 1.19

--- lib/base.coffee
+++ lib/base.coffee
@@ -258,7 +258,6 @@
   # -------------------------
   @writeCommandTableOnDisk: ->
     commandTable = @generateCommandTableByEagerLoad()
-    console.warn commandTable # investigate why sometime this get empty?
     _ = _plus()
     if _.isEqual(@commandTable, commandTable)
       atom.notifications.addInfo("No change commandTable", dismissable: true)
@@ -274,10 +273,9 @@
       #{CSON.stringify(commandTable)}\n
       """
     commandTablePath = path.join(__dirname, "command-table.coffee")
-    atom.workspace.open(commandTablePath, activateItem: false).then (editor) ->
+    atom.workspace.open(commandTablePath).then (editor) ->
       editor.setText(loadableCSONText)
       editor.save()
-      editor.destroy()
       atom.notifications.addInfo("Updated commandTable", dismissable: true)

   @generateCommandTableByEagerLoad: ->


Finished dlg rename

Finished dlg rename

--- maproulette/static/js/maproulette.coffee
+++ maproulette/static/js/maproulette.coffee
@@ -143,7 +143,7 @@
   ###
   msg currentTask.text if currentTask.text

-dlg = (h) ->
+dlgOpen = (h) ->
   ###
   #  Display the data (html) in a dialog box. Must be closed with dlgClose()
   ###


Update mention regex to match @org/team correctly

--- src/scripts/github-pull-request-notifier.coffee
+++ src/scripts/github-pull-request-notifier.coffee
@@ -46,7 +46,7 @@

 announcePullRequest = (data, cb) ->
   if data.action == 'opened'
-    mentioned = data.pull_request.body.match(/(^|\s)(@[\w\-]+)/g)
+    mentioned = data.pull_request.body.match(/(^|\s)(@[\w\-\/]+)/g)

     if mentioned
       unique = (array) ->


fix #5, test use UUID.

fix #5, test use UUID.

--- test/support/index.coffee
+++ test/support/index.coffee
@@ -1,5 +1,6 @@
 odata = require("../../")
 mongoose = odata.mongoose
+uuid = require 'node-uuid'
 fixtures = require("pow-mongoose-fixtures")
 callback = undefined
 done = undefined
@@ -8,7 +9,7 @@
 #import data.
 data = require("./data.json")
 for item in data
-  item._id = mongoose.Types.ObjectId()
+  item._id = uuid.v4()
 fixtures.load books: data, mongoose.connection, (err) ->
   module.exports.app = odata._app
   module.exports.books = data


made shacharit late on 1st 2 days of pesach

--- source/javascripts/schedule.coffee
+++ source/javascripts/schedule.coffee
@@ -38,6 +38,8 @@
         shaharit_is_fixed_at(day, 7, 0)
       else if hebrew_date.is1stDayOfShabuot()
         new Vatikin(day_iterator, hebrew_date).updateDOM()
+      else if hebrew_date.is1stDayOfPesach() || hebrew_date.is2ndDayOfPesach()
+        shaharit_is_fixed_at(day, 8, 45)
       else if hebrew_date.isYomTov() || hebrew_date.isShabbat()
         # TODO: Shofar 2:30 after Hodu on Rosh Hashana that isn't Shabbat
         shaharit_is_fixed_at(day, 7, 45)


improve test

improve test

--- test/scripts/hello.coffee
+++ test/scripts/hello.coffee
@@ -1,4 +1,4 @@
-{Robot, TextMessage} = require 'hubot'
+{Robot, User, TextMessage} = require 'hubot'
 assert = require 'power-assert'
 path = require 'path'
 sinon = require 'sinon'
@@ -25,9 +25,9 @@

     describe 'receive "@hubot hello"', ->
       beforeEach ->
-        sender = { id: 'bouzuya', room: 'hitoridokusho' }
+        @sender = new User 'bouzuya', room: 'hitoridokusho'
         message = '@hubot hello'
-        @robot.adapter.receive new TextMessage(sender, message)
+        @robot.adapter.receive new TextMessage(@sender, message)

       it 'calls *hello* with "@hubot hello"', ->
         assert @callback.callCount is 1


Only register fuzzy-finder:invert-confirm on the fuzzy finder mini editor

--- keymaps/fuzzy-finder.cson
+++ keymaps/fuzzy-finder.cson
@@ -3,18 +3,18 @@
   'cmd-p': 'fuzzy-finder:toggle-file-finder'
   'cmd-b': 'fuzzy-finder:toggle-buffer-finder'
   'cmd-B': 'fuzzy-finder:toggle-git-status-finder'
-  'shift-enter': 'fuzzy-finder:invert-confirm'

 '.platform-win32':
   'ctrl-t': 'fuzzy-finder:toggle-file-finder'
   'ctrl-p': 'fuzzy-finder:toggle-file-finder'
   'ctrl-b': 'fuzzy-finder:toggle-buffer-finder'
   'ctrl-B': 'fuzzy-finder:toggle-git-status-finder'
-  'shift-enter': 'fuzzy-finder:invert-confirm'

 '.platform-linux':
   'ctrl-t': 'fuzzy-finder:toggle-file-finder'
   'ctrl-p': 'fuzzy-finder:toggle-file-finder'
   'ctrl-b': 'fuzzy-finder:toggle-buffer-finder'
   'ctrl-B': 'fuzzy-finder:toggle-git-status-finder'
+
+'.fuzzy-finder atom-text-editor[mini]':
   'shift-enter': 'fuzzy-finder:invert-confirm'


update spec new course

update spec new course

--- tutor/specs/components/new-course/build-course.spec.cjsx
+++ tutor/specs/components/new-course/build-course.spec.cjsx
@@ -24,13 +24,13 @@
     it 'redirects to Tutor for Tutor', ->
       NewCourseActions.created({id: '42', is_concept_coach: false})
       wrapper = shallow(<BuildCourse />, @options)
-      NewCourseStore.emit('change')
+      NewCourseStore.emit('created')
       expect(@options.context.router.transitionTo).to.have.been.calledWith('/course/42?showIntro=true')
       undefined

     it 'redirects to CC', ->
       NewCourseActions.created({id: '21', is_concept_coach: true})
       wrapper = shallow(<BuildCourse />, @options)
-      NewCourseStore.emit('change')
+      NewCourseStore.emit('created')
       expect(@options.context.router.transitionTo).to.have.been.calledWith('/course/21/cc/help?showIntro=true')
       undefined


Yuqiang/cppregex (#6293)

Yuqiang/cppregex (#6293)

* . do not match \n

* add ; to prevent cross cpp line

Co-authored-by: smallst_wsl <6c42689ff77371401bf43b7d56b93ac1ca3e92d3@163.com>


Added more metadata to be retrieved from Torrents

--- app/helpers/torrent.coffee
+++ app/helpers/torrent.coffee
@@ -153,8 +153,10 @@
           files: (file.path for file in torrent.files)

           health:
-            seeders: torrent.seeders
+            seeders : torrent.seeders
             leechers: torrent.leechers
+            updated : new Date().getTime()
+            accessed: new Date().getTime()
         }, torrent.parsedTorrent

         torrent.remove()


use normalizedPath instead of path

use normalizedPath instead of path

--- src/coffee/helpers/project-credentials-config.coffee
+++ src/coffee/helpers/project-credentials-config.coffee
@@ -44,10 +44,10 @@
     configsP = _.map @_lookupFiles, (path) =>
       normalizedPath = @_normalizePath path

-      fs.exists path
+      fs.exists normalizedPath
       .then (exists) =>
         if exists
-          fs.read path, 'r'
+          fs.read normalizedPath, 'r'
           .then (contents) =>
             if _.endsWith(normalizedPath, ".json")
               @_readJsonConfig "#{contents}"


Changed name for responseText, messages are now synced

--- src/scripts/steam.coffee
+++ src/scripts/steam.coffee
@@ -25,10 +25,8 @@

 module.exports = (robot) ->
   robot.respond /daily deal/i, (msg) ->
-    getDeals msg, (responseText) ->
-      msg.send responseText[0]
-      msg.send responseText[1]
-
+    getDeals msg, (deal) ->
+      msg.send deal[0], deal[1]

 getDeals = (msg, callback) ->
     location = "http://store.steampowered.com"


remove nonsense "do"s

remove nonsense "do"s

--- core/KD.coffee
+++ core/KD.coffee
@@ -159,9 +159,9 @@
           router.openSection options.name, name, query
         router.addRoute slug, handler

-      if KD.singletons.router
-      then do -> cb KD.getSingleton('router')
-      else KodingRouter.on 'RouterReady', do -> cb
+      if KD.getSingleton 'router'
+      then @utils.defer -> cb KD.getSingleton('router')
+      else KodingRouter.on 'RouterReady', cb

     if options.navItem?.order
       @registerNavItem options.navItem


add ajaxError

add ajaxError


use at instead of -

use at instead of -

--- app/assets/javascripts/pt/tags/datetime.js.coffee
+++ app/assets/javascripts/pt/tags/datetime.js.coffee
@@ -9,7 +9,7 @@

       unless $el.data 'ptDatetimeLoaded'
         $el.datetimepicker
-          format: attr.datetime or 'mm/dd/yyyy - HH:ii P'
+          format: attr.datetime or 'mm/dd/yyyy at HH:ii P'
           showMeridian: true
           autoclose: true


Use data attrs of script tag only for integration setting

--- app/assets/javascripts/uploadcare/settings.coffee
+++ app/assets/javascripts/uploadcare/settings.coffee
@@ -67,16 +67,13 @@
       all: 'file camera url facebook gdrive gphotos dropbox instagram evernote flickr skydrive box vk huddle'
       default: defaults.tabs

-  # settings from data attributes of script tag
+  # integration setting from data attributes of script tag
   script = document.currentScript || do ->
-    scripts = document.getElementsByTagName("script")
+    scripts = document.getElementsByTagName('script')
     scripts[scripts.length - 1]
-  scriptSettings = {}
-  for key of defaults
-    value = $(script).data(key)
-    if value isnt undefined
-      scriptSettings[key] = value
-  defaults = $.extend(defaults, scriptSettings)
+  integration = $(script).data('integration')
+  if integration isnt undefined
+    defaults = $.extend(defaults, {integration})

   str2arr = (value) ->
     if not $.isArray(value)


Refactor procedures to update form to function

--- app/assets/javascripts/views/restrooms/new.coffee
+++ app/assets/javascripts/views/restrooms/new.coffee
@@ -29,9 +29,7 @@
             console.log result[0]
             @_getNewForm(coords).then (data, textStatus) =>
               console.log data
-              $('.form-container').html(data).hide().fadeIn()
-              @_requestNearbyRestrooms(coords)
-              @_updateMap(coords)
+              @_updateForm(coords, data, textStatus)

   _bindPreviewButton: =>
@@ -70,6 +68,10 @@
       success: (data, textStatus) ->
         # $('.new-restrooms-form-container').html(data)

+  _updateForm: (coords, data, textStatus) =>
+    $('.form-container').html(data).hide().fadeIn()
+    @_requestNearbyRestrooms(coords)
+    @_updateMap(coords)

   _requestNearbyRestrooms: (coords) ->
     $.ajax


use an en dash for time ranges

use an en dash for time ranges

--- app/assets/transit/lib/models/itinerary.js.coffee
+++ app/assets/transit/lib/models/itinerary.js.coffee
@@ -17,7 +17,7 @@
 		start = Transit.format_time(@get('startTime'))
 		end   = Transit.format_time(@get('endTime'))
 		total = Transit.format_duration(@get('duration') / 1000)
-		"#{start} - #{end} (#{total})"
+		"#{start}–#{end} (#{total})"

 	duration: =>
 		walk = Transit.format_duration(@get('walkTime'), true)


Form RPC submission test

Form RPC submission test

--- app/coffee/modules/packages/core/test-unit.coffee
+++ app/coffee/modules/packages/core/test-unit.coffee
@@ -134,3 +134,56 @@
 				expect(submissionCleared).toBe true

 		]
+
+	it 'should handle rpc submission', ->
+
+		inject [
+			'$compile', '$rootScope', '$timeout', 'comm/socket'
+			($compile, $rootScope, $timeout, socket) ->
+
+				tpl = $compile '

'
+
+				scope = $rootScope.$new()
+
+				rpcSubmission = ''
+				submissionCleared = false
+
+				socket.catchEmit 'rpc://test', (data, fn) ->
+					rpcSubmission = data.text
+
+					fn result: 420
+
+				scope.test =
+					text:
+						type: 'text'
+						label: "text"
+					submit:
+						rpc: true
+						type: 'submit'
+						label: "Submit"
+						handler: (error, result) ->
+							submissionCleared = result is 420
+
+				elm = tpl scope
+
+				scope.text = 'test'
+
+				scope.$digest()
+
+				$form = elm.find 'form'
+
+				for input in $form.find 'input'
+					$input = angular.element input
+
+					input.click() if 'submit' is input.type
+
+				$timeout.flush()
+				$rootScope.$apply()
+
+				# RPC received correct data.
+				expect(rpcSubmission).toBe 'test'
+
+				# Form was submitted with correct values.
+				expect(submissionCleared).toBe true
+
+		]


fix: minor change

fix: minor change

--- app/mixins/paginate.coffee
+++ app/mixins/paginate.coffee
@@ -36,8 +36,8 @@
     targetObject = @get "targetObject"
     objects = @get('store').query targetObject, query
     objects.then (result) ->
-      # that.set "meta", result.meta
-      that.set "meta", total: 200
+      that.set "meta", result.meta
+      # that.set "meta", total: 200
     objects
   ).property  "version"


commenting onConsoleMessage bridge in crawler

--- crawler.coffee
+++ crawler.coffee
@@ -2,7 +2,7 @@
 page = require('webpage').create()
 url = phantom.args[ 0 ]

-page.onConsoleMessage=( msg )-> console.log msg
+# page.onConsoleMessage=( msg )-> console.log msg

 page.open url, ->
 	setInterval ->


ChangeListener cannot be draggable

ChangeListener cannot be draggable

--- app/pages/lab/project.cjsx
+++ app/pages/lab/project.cjsx
@@ -96,16 +96,16 @@

Workflows

             <PromiseRenderer promise={getWorkflowsInOrder @props.project}>{(workflows) =>
               renderWorkflowListItem = (workflow) =>
+                <Link to={@labPath "/workflow/#{workflow.id}"} className="nav-list-item" activeClassName="active">
+                  {workflow.display_name}
+                  {if workflow.id is @props.project.configuration?.default_workflow
+                    {' '}*{' '}}
+                </Link>
+
+              renderWorkflowListItemListener = (workflow) =>

-                  <Link to={@labPath "/workflow/#{workflow.id}"} className="nav-list-item" activeClassName="active">
-                    {workflow.display_name}
-                    {if workflow.id is @props.project.configuration?.default_workflow
-                      {' '}*{' '}}
-                  </Link>
+                  <ChangeListener target={workflow} eventName="save" handler={renderWorkflowListItem.bind null, workflow} />

-
-              renderWorkflowListItemListener = (workflow) =>
-                <ChangeListener key={workflow.id} target={workflow} eventName="save" handler={renderWorkflowListItem.bind null, workflow} />

               <DragReorderable tag="ul" className="nav-list" items={workflows} render={renderWorkflowListItemListener} onChange={@handleWorkflowReorder} />
             }</PromiseRenderer>


whoops. fixed the file path

whoops. fixed the file path

--- app/lib/field-guide-content/sable_antelope.coffee
+++ app/lib/field-guide-content/sable_antelope.coffee
@@ -58,5 +58,5 @@
     '''
   },{
     title: 'Distribution'
-    content: ''
+    content: ''
   }]


cacheing added and specs seem to pass

cacheing added and specs seem to pass

--- lib/models/vehicle.coffee
+++ lib/models/vehicle.coffee
@@ -36,16 +36,19 @@
     #   if (lastJourney.state() == 'finished') && (lastJourney.getPath('endTime.milliseconds') != @getPath('_stops.lastObject.arriveTime.milliseconds'))
     #     @createStop(lastJourney.getPath('messages.lastObject'))
     # _stops
+    console.log "calculating stops"
     journeys = @getPath('journeys.content').slice(0)
-    journeys.filter((j) -> j.state() == 'finished').map (j) -> j.get('stop')
-  ).property()
+    if journeys
+      journeys.filter((j) -> j.state() == 'finished').map (j) -> j.get('stop')
+  ).property('_journeys.length').cacheable()
   journeys: ( ->
+    console.log "calculating journeys"
     _journeys = @get('_journeys')
-    filteredJourneys = _journeys.filter (j) -> j.valid()
-    console.log "filtering journeys", filteredJourneys.length
-    @setPath('_journeys.content', filteredJourneys)
-    @get('_journeys')
-  ).property()
+    if _journeys
+      filteredJourneys = _journeys.filter (j) -> j.valid()
+      @setPath('_journeys.content', filteredJourneys)
+      @get('_journeys')
+  ).property('_journeys.length').cacheable()
   lastMessageBinding: '.messages.lastObject'
   latBinding: '.lastMessage.lat'
   lonBinding: '.lastMessage.lon'


make hub proxy server a bit less impatient

--- src/smc-hub/proxy.coffee
+++ src/smc-hub/proxy.coffee
@@ -341,7 +341,7 @@
                     dbg("used cached proxy object: #{misc.walltime(tm)}")
                 else
                     dbg("make a new proxy server connecting to this remote location")
-                    proxy = http_proxy.createProxyServer(ws:false, target:t, timeout:3000)
+                    proxy = http_proxy.createProxyServer(ws:false, target:t, timeout:7000)
                     # and cache it.
                     proxy_cache[t] = proxy
                     dbg("created new proxy: #{misc.walltime(tm)}")


Do not require jade here

Do not require jade here

Let the project that is using Fran decide what engine to use.

--- lib/fran.coffee
+++ lib/fran.coffee
@@ -1,5 +1,3 @@
-require('jade')
-
 w = require('when')
 express = require('express')

@@ -15,9 +13,6 @@

   start: ->
     app.use express.static(Project.publicPath)
-
-    app.set('views', Project.viewsPath)
-    app.set('view engine', 'jade')

     w.all Config.ports.map (port) ->
       w.promise (resolve, reject) ->


Add smoke to boss leaving

Add smoke to boss leaving

--- app/scripts/lazerscripts/stage1/stage1boss.coffee
+++ app/scripts/lazerscripts/stage1/stage1boss.coffee
@@ -21,7 +21,7 @@
       @blast(@location(),
         radius: 10
         duration: 480
-        z: @entity.z
+        z: @entity.z - 3
         alpha: options.alpha
         lightness: 1.0
         ->
@@ -554,7 +554,10 @@
     @sequence(
       @animate 'slow', -1, 'eye'
       @pickTarget('PlayerControlledShip')
-      @moveTo(@targetLocation(), x: .845, speed: 200)
+      @while(
+        @moveTo(@targetLocation(), x: .845, speed: 200)
+        @smoke('medium')
+      )
       @attackCycle()
       @laugh()
       @leaveScreen()
@@ -580,13 +583,7 @@
       @parallel(
         @while(
           @moveTo(x: -.15, speed: 400)
-          @sequence(
-            @smallExplosion()
-            @while(
-              @wait 300
-              @smoke()
-            )
-          )
+          @smoke()
         )
         @scale(0.7, duration: 3000)
       )
@@ -611,7 +608,10 @@
       )
       @animate 'emptyWing', 0, 'wing'
       @parallel(
-        @moveTo(@targetLocation(offsetY: -20), x: .845)
+        @while(
+          @moveTo(@targetLocation(offsetY: -20), x: .845)
+          @smoke('medium')
+        )
         @sequence(
           @animate 'reload', 0, 'wing'
           @wait 1000


:bug: Fix a bug with Path Separator on Windows Fixes steelbrain/AutoComplete-Hack#4

--- lib/hack.coffee
+++ lib/hack.coffee
@@ -11,7 +11,7 @@
   exec:(Command, CWD)->
     return new Promise (Resolve, Reject)=>
       if @config.type is 'remote'
-        CWD = @config.remoteDir + Path.sep + Path.relative(atom.project.getPaths()[0], CWD).replace(Path.sep, '/');
+        CWD = @config.remoteDir + '/' + Path.relative(atom.project.getPaths()[0], CWD).replace(Path.sep, '/');
         @SSH.exec(Command, {cwd: CWD}).then Resolve
       else
         CP.exec(Command, {cwd: CWD}, (error, stdout, stderr)->


removed statSync for sync with callback

removed statSync for sync with callback

--- lib/http.coffee
+++ lib/http.coffee
@@ -47,21 +47,22 @@
         res.writeHead 404
         return res.end()

-      if fs.statSync(filename).isDirectory()
-        filename += '/' + config.index
-        path.exists filename, (exists) ->
-          unless exists
-            res.writeHead 404
+      fs.stat filename, (err, stat) ->
+        if stat.isDirectory()
+          filename += '/' + config.index
+          path.exists filename, (exists) ->
+            unless exists
+              res.writeHead 404
+              return res.end()
+
+        fs.readFile path.normalize(filename), 'binary', (err, file) ->
+          if err
+            res.writeHead 500
             return res.end()

-      fs.readFile path.normalize(filename), 'binary', (err, file) ->
-        if err
-          res.writeHead 500
-          return res.end()
-
-        res.writeHead 200, 'Content-Type': mime.lookup(filename)
-        res.write file, 'binary'
-        res.end()
+          res.writeHead 200, 'Content-Type': mime.lookup(filename)
+          res.write file, 'binary'
+          res.end()

 http.processRequest = (req, res, cb) ->
   userIP = req.connection.remoteAddress


Remove rail in the event of a fetch error

--- apps/home_2/client/setup_home_page_modules.coffee
+++ apps/home_2/client/setup_home_page_modules.coffee
@@ -44,6 +44,7 @@
       req: { user: user }
     ).then ({ home_page_module }) ->
       module = home_page_module
+
       $el = $("#hpm-#{module.key}-#{index}")

       return $el.remove() unless module.results?.length
@@ -72,6 +73,7 @@

       view.render()
     .catch (err) ->
+      $("#hpm-#{module.key}-#{index}").remove()
       console.warn('Error rendering homepage rails', err.stack)


Lower log level

Lower log level

--- lib/product-import.coffee
+++ lib/product-import.coffee
@@ -20,7 +20,7 @@
     @_configErrorHandling(options)
     @_resetCache()
     @_resetSummary()
-    if @logger then @logger.info "Product Importer initialized with config -> errorDir: #{@errorDir}, errorLimit: #{@errorLimit}, blacklist actions: #{options.blackList}, ensureEnums: #{@ensureEnums}"
+    debug "Product Importer initialized with config -> errorDir: #{@errorDir}, errorLimit: #{@errorLimit}, blacklist actions: #{options.blackList}, ensureEnums: #{@ensureEnums}"

   _configureSync: (blackList) =>
     @_validateSyncConfig(blackList)
@@ -188,7 +188,7 @@
       if _.isEmpty(enumUpdateActions)
         resolve()
       else
-        @logger.info "Updating product type(s): #{_.keys(enumUpdateActions)}"
+        debug "Updating product type(s): #{_.keys(enumUpdateActions)}"
         Promise.all [
           for productTypeId in _.keys(enumUpdateActions)
             updateRequest =


Fix cleanup issue on unload

Fix cleanup issue on unload

--- lib/project-config.coffee
+++ lib/project-config.coffee
@@ -175,6 +175,6 @@

     destroy: ->
         @emitter.dispose()
-        disposable.dispose() for disposable in disposables
+        disposable.dispose() for disposable in @disposables
         fs.unwatchFile(config.configFile) for config in @configs
         fs.unwatchFile(@globalConfigPath)


plugin.on

plugin.on

--- lib/init.coffee
+++ lib/init.coffee
@@ -17,6 +17,8 @@
 child_process = require('child_process')

 plugin = child_process.fork(__dirname + '/plugin')
+bar = -> console.log("AAAAA")
+plugin.on('message', bar)
 plugin.send({type: 'whatever'})

 foo = () -> plugin.send({type: 'whatever'})


Shortcuts detection fix.

Shortcuts detection fix.

--- packages/artificialengines/control/keyboardstate.coffee
+++ packages/artificialengines/control/keyboardstate.coffee
@@ -27,6 +27,14 @@
     return if shortcut.alt and not @isKeyDown AC.Keys.alt
     return if shortcut.control and not @isKeyDown AC.Keys.control

+    # Make sure non of the other modifiers are down.
+    return if @isCommandOrCtrlDown() and not (shortcut.command or shortcut.control or shortcut.commandOrControl)
+    return if @isMetaDown() and not (shortcut.command or shortcut.win or shortcut.super or shortcut.commandOrControl)
+
+    for keyName in ['shift', 'alt', 'control']
+      key = AC.Keys[keyName]
+      return if @isKeyDown(key) and not (shortcut[keyName] or (shortcut.key is key) or (shortcut.holdKey is key))
+
     # Make sure the main key is down.
     keyDown = true if shortcut.key and @isKeyDown shortcut.key
     holdKeyDown = true if shortcut.holdKey and @isKeyDown shortcut.holdKey


stray log

stray log

--- apps/channel/client.coffee
+++ apps/channel/client.coffee
@@ -31,7 +31,6 @@
     @listener = new Bp.Backpusher @pusher, @blocks

   checkUserAbilities: (collaborators) ->
-    console.log 'checkUserAbilities'
     collaborator = _.contains collaborators.pluck('id'), mediator.shared.current_user.id

     if collaborator or mediator.shared.current_user.canAddToChannel(@channel)


Fixed ecosystem

Fixed ecosystem

--- test/knockback/view-model/test.coffee
+++ test/knockback/view-model/test.coffee
@@ -877,6 +877,9 @@
   it '23. Issue 94', (done) ->
     kb.statistics = new kb.Statistics() # turn on stats

+    # ECOSYSTEM
+    return done() if kb.Parse
+
     Child = kb.Model.extend()

     Parent = kb.Model.extend({


Add engines info

Add engines info

--- lib/skeleton/index.coffee
+++ lib/skeleton/index.coffee
@@ -61,6 +61,9 @@

     this.displayLine ''
     this.displayLine '  ============================================='.cyan
+    this.displayLine "  #{'template engine:'.cyan} #{opts.renderer}"
+    this.displayLine "  #{'stylesheet engine:'.cyan} #{opts.css}"
+    this.displayLine ''
     this.displayLine "  #{'$'.cyan} cd #{opts.appName} && npm install"
     this.displayLine "  #{'$'.cyan} node server.js"
     this.displayLine '  ============================================='.cyan


handle else, duh

handle else, duh

--- lib/main.coffee
+++ lib/main.coffee
@@ -25,11 +25,13 @@
     switch s.type
       when 'content' then s.string
       when 'block'
-
         params = if s.mustache?.params?.length > 0 then ' ' + _(s.mustache.params).map((p) -> p.string).join(' ') else ''
         r = ["{{#{(if _(tokens).include(s.mustache.id.original) then '#' else '')}#{s.mustache.id.original} #{params}}}"]
         if s.program?
           r.push processStatements(s.program.statements)
+        if s.inverse?
+          r.push ['{{else}}']
+          r.push processStatements(s.inverse.statements)
         r.push "{{/#{s.mustache.id.original}}}" if _(tokens).include(s.mustache.id.original)
         r
       when 'mustache'


:art: no need to observe onDidChangeScrollLeft

And calling refreshEditor on this event only clear decoration but not
render highlight.
But I’m OK since I no longer track this event.

--- lib/main.coffee
+++ lib/main.coffee
@@ -92,7 +92,6 @@

       editorElement = getView(editor)
       editorSubs.add editorElement.onDidChangeScrollTop => @refreshEditor(editor)
-      editorSubs.add editorElement.onDidChangeScrollLeft => @refreshEditor(editor)

       # [FIXME]
       # @refreshEditor depend on editorElement.getVisibleRowRange() but it return


Respect Grim.includeDeprecatedAPIs

Respect Grim.includeDeprecatedAPIs

--- lib/main.coffee
+++ lib/main.coffee
@@ -1,4 +1,3 @@
-{$} = require 'atom-space-pen-views'
 Grim = require 'grim'
 StatusBarView = require './status-bar-view'
 FileInfoView = require './file-info-view'
@@ -14,30 +13,32 @@
     @statusBar.initialize(state)
     @statusBarPanel = atom.workspace.addBottomPanel(item: @statusBar, priority: 0)

-    # Wrap status bar element in a jQuery wrapper for backwards compatibility
-    wrappedStatusBar = $.extend $(@statusBar),
-      appendLeft: (view) => @statusBar.appendLeft(view)
-      appendRight: (view) => @statusBar.appendRight(view)
-      prependLeft: (view) => @statusBar.prependLeft(view)
-      prependRight: (view) => @statusBar.prependRight(view)
-      getActiveBuffer: => @statusBar.getActiveBuffer()
-      getActiveItem: => @statusBar.getActiveItem()
-      subscribeToBuffer: (event, callback) => @statusBar.subscribeToBuffer(event, callback)
+    if Grim.includeDeprecatedAPIs
+      {$} = require 'atom-space-pen-views'
+      # Wrap status bar element in a jQuery wrapper for backwards compatibility
+      wrappedStatusBar = $.extend $(@statusBar),
+        appendLeft: (view) => @statusBar.appendLeft(view)
+        appendRight: (view) => @statusBar.appendRight(view)
+        prependLeft: (view) => @statusBar.prependLeft(view)
+        prependRight: (view) => @statusBar.prependRight(view)
+        getActiveBuffer: => @statusBar.getActiveBuffer()
+        getActiveItem: => @statusBar.getActiveItem()
+        subscribeToBuffer: (event, callback) => @statusBar.subscribeToBuffer(event, callback)

-    if atom.__workspaceView?
-      Object.defineProperty atom.__workspaceView, 'statusBar',
-        get: ->
-          Grim.deprecate """
-            The atom.workspaceView.statusBar global is deprecated. The global was
-            previously being assigned by the status-bar package, but Atom packages
-            should never assign globals.
+      if atom.__workspaceView?
+        Object.defineProperty atom.__workspaceView, 'statusBar',
+          get: ->
+            Grim.deprecate """
+              The atom.workspaceView.statusBar global is deprecated. The global was
+              previously being assigned by the status-bar package, but Atom packages
+              should never assign globals.

-            In the future, this problem will be solved by an inter-package communication
-            API available on `atom.services`. For now, you can get a reference to the
-            `status-bar` element via `document.querySelector('status-bar')`.
-          """
-          wrappedStatusBar
-        configurable: true
+              In the future, this problem will be solved by an inter-package communication
+              API available on `atom.services`. For now, you can get a reference to the
+              `status-bar` element via `document.querySelector('status-bar')`.
+            """
+            wrappedStatusBar
+          configurable: true

     atom.commands.add 'atom-workspace', 'status-bar:toggle', =>
       if @statusBarPanel.isVisible()


:memo: Update v4 preview setting description

--- lib/main.coffee
+++ lib/main.coffee
@@ -84,7 +84,7 @@
     v4Preview:
       type: 'boolean'
       default: false
-      description: "Require Atom restart. Plugins will be disabled."
+      description: "Require Atom restart. Some plugins may be disabled if they don't support the new API."

   # Internal: The activation state of the minimap package.
   active: false


Add missing changes from previous commit

--- lib/main.coffee
+++ lib/main.coffee
@@ -17,6 +17,7 @@
       character = helper.getTokenizedAlignCharacter tokenized.tokens, scope

       if character
+        indentLevel = editor.indentationForBufferRow origRow
         indentRange = helper.getSameIndentationRange editor, origRow, character
         config      = operatorConfig.getConfig character, scope
         textBlock   = ""
@@ -25,6 +26,9 @@
           tokenizedLine = helper.getTokenizedLineForBufferRow(editor, row)
           lineCharacter = helper.getTokenizedAlignCharacter tokenizedLine.tokens, scope
           parsed        = helper.parseTokenizedLine tokenizedLine, lineCharacter, config
+
+          # Construct new line
+          currentLine = editor.buildIndentString indentLevel

           for parsedItem, i in parsed
             offset = parsedItem.offset + (if parsed.prefix then 1 else 0)
@@ -47,20 +51,21 @@
             rightSpace  = if alignment is "right" then newSpace else ""
             rightSpace += " " if config.rightSpace

+
             if config.multiple
               if i is 0
-                textBlock += parsedItem.before
+                currentLine += parsedItem.before
               else
-                textBlock += leftSpace + parsedItem.before.trim()
+                currentLine += leftSpace + parsedItem.before.trim()

-              textBlock += rightSpace + lineCharacter unless i is parsed.length - 1
+              currentLine += rightSpace + lineCharacter unless i is parsed.length - 1

             else
-              textBlock += parsedItem.before
-              textBlock += leftSpace + lineCharacter + rightSpace
-              textBlock += parsedItem.after
+              currentLine += parsedItem.before
+              currentLine += leftSpace + lineCharacter + rightSpace
+              currentLine += parsedItem.after

-          textBlock += "\n"
+          textBlock += "#{currentLine}\n"

         # Replace the whole block
         editor.setTextInBufferRange([[indentRange.start, 0], [indentRange.end + 1, 0]], textBlock)


Removed the https protocol. Use just //

Removed the https protocol. Use just //

--- assets/js/_networks.coffee
+++ assets/js/_networks.coffee
@@ -2,30 +2,30 @@
   supportedNetworks = new App.Collections.SocialNetworks([
     {
       name: 'mt-facebook'
-      imagePath: 'https://mojotech-static.s3.amazonaws.com/facebook@2x.png'
-      shareUrl: (url) -> "https://www.facebook.com/sharer/sharer.php?u=#{url}"
+      imagePath: '//mojotech-static.s3.amazonaws.com/facebook@2x.png'
+      shareUrl: (url) -> "//www.facebook.com/sharer/sharer.php?u=#{url}"
       selected: true
     },
     {
       name: 'mt-twitter'
-      imagePath: 'https://mojotech-static.s3.amazonaws.com/twitter@2x.png'
-      shareUrl: (url, text) -> "https://twitter.com/intent/tweet?text=#{text}&url=#{url}"
+      imagePath: '//mojotech-static.s3.amazonaws.com/twitter@2x.png'
+      shareUrl: (url, text) -> "//twitter.com/intent/tweet?text=#{text}&url=#{url}"
       selected: true
     },
     {
       name: 'mt-linkedin'
-      imagePath: 'https://mojotech-static.s3.amazonaws.com/linkedin@2x.png'
-      shareUrl: (url, text) -> "https://www.linkedin.com/shareArticle?mini=true&url=#{url}&summary=#{text}"
+      imagePath: '//mojotech-static.s3.amazonaws.com/linkedin@2x.png'
+      shareUrl: (url, text) -> "//www.linkedin.com/shareArticle?mini=true&url=#{url}&summary=#{text}"
     },
     {
       name: 'mt-google'
-      imagePath: 'https://mojotech-static.s3.amazonaws.com/google@2x.png'
-      shareUrl: (url) -> "https://plus.google.com/share?url=#{url}"
+      imagePath: '//mojotech-static.s3.amazonaws.com/google@2x.png'
+      shareUrl: (url) -> "//plus.google.com/share?url=#{url}"
     },
     {
       name: 'mt-pinterest'
-      imagePath: 'https://mojotech-static.s3.amazonaws.com/pinterest@2x.png'
-      shareUrl: (url, text, mediaUrl) -> "https://www.pinterest.com/pin/create/button/?url=#{url}&media=#{mediaUrl}&guid=1234&description=#{text}"
+      imagePath: '//mojotech-static.s3.amazonaws.com/pinterest@2x.png'
+      shareUrl: (url, text, mediaUrl) -> "//www.pinterest.com/pin/create/button/?url=#{url}&media=#{mediaUrl}&guid=1234&description=#{text}"
     }
   ])