Fix misc stringify

Fix misc stringify

--- src/misc.coffee
+++ src/misc.coffee
@@ -728,7 +728,7 @@
           out += eol
         out += child
       out
-    stringify_square_then_curly: (content, depth=0, options) ->
+    stringify_square_then_curly: (content, depth=0, options={}) ->
       if arguments.length is 2
         options = depth
         depth = 0


Hound linter comment fix

Hound linter comment fix

--- app/assets/javascripts/admin/form_answers.js.coffee
+++ app/assets/javascripts/admin/form_answers.js.coffee
@@ -33,7 +33,8 @@
   # Move the attach document button
   $(".attachment-link").removeClass("if-js-hide")
   $(".attachment-link").addClass("btn btn-default btn-block btn-attachment")
-  $(".attachment-link").prepend(" Attach Document")
+  $(".attachment-link").prepend("Attach Document")
+  $(".attachment-link").prepend("")
   $(".attachment-link").prependTo("#new_form_answer_attachment")

   $(".js-attachment-form .btn-cancel").on "click", (e) ->


fix for adjusting position

fix for adjusting position

--- app/assets/javascripts/comparative_genome.js.coffee
+++ app/assets/javascripts/comparative_genome.js.coffee
@@ -410,7 +410,7 @@
       return
     return
   resize: ->
-    @$speciesSelector.width window.innerWidth - (@speciesSelectorWidthMargin)
+    @$speciesSelector.width 'calc(100% - 24px)'
     return
 Species.prototype =
   $container: undefined
@@ -446,11 +446,12 @@
   scroll: ->
     scrollTop = @$window.scrollTop()
     windowHeight = @$window.innerHeight()
+    PADDING_TOP = 46
     @sections.forEach (section) ->
       top = section.$section.offset().top
       height = section.$heading.height()
       position = 0
-      if scrollTop > top - (section.top)
+      if scrollTop > top - (section.top) - PADDING_TOP
         position = -1
       if scrollTop + windowHeight < top + height + section.bottom
         position = 1
@@ -460,7 +461,7 @@
           when -1
             section.$section.addClass('sticked').removeClass 'bottom'
             section.$heading.css
-              top: section.top
+              top: section.top + PADDING_TOP
               bottom: ''
           when 0
             section.$section.removeClass('sticked').addClass 'bottom'
@@ -816,6 +817,8 @@
     ).join ' '
 $ ->
   application = new Application
+  # TogoGenome 埋め込みにあたっての処置
+  $('#search-methods-selector').css zIndex: 10000
   # taxon の読み込み
   d3.json 'taxonomy.json', (data) ->
     application.initialize data


t push origin master git push loomio-production master Merge branch 'master' of github.com:loomio/loomio

--- app/assets/javascripts/keyboard_shortcuts.js.coffee
+++ app/assets/javascripts/keyboard_shortcuts.js.coffee
@@ -9,10 +9,11 @@
         when 38 # select prev group with up arrow
           target = active.parent().prev('.group-item').find('.selector-link')
           target = $('#group-dropdown-items').find('.selector-link').last() if target.length is 0
-      target.focus() if target?
-      event.preventDefault()
+      if target?
+        target.focus()
+        event.preventDefault()

-    if active.not('input, textarea, select') or event.which == 27
+    if !active.is('input, textarea, select') or event.which == 27
       switch event.which
         when 71, 27 # G or ESC for groups search dropdown
           $('#groups>a').click()


Immediately update the total points when highest point value changes. Fixes #11649

Fixes regression.

Testing Notes:
==========
* Create or edit an outcome
* Edit the highest criterion rating to change the point value.
* When "OK" is clicked, the "totals" should update to reflect
   the updated points value.
* Insert a new criterion rating and give it the highest point
  value. When hit "OK", the totals should update to reflect.

Change-Id: If530931c5bcf2dd6ef498e4deb58bfbe7d54e016
Reviewed-on: https://gerrit.instructure.com/15052
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Marc LeGendre <d33c80bc45d65303e33ca83108a9952b745af9ef@instructure.com>
Reviewed-by: Zach Pendleton <514dbb4d54d4f29e454990df7d075678f43f92aa@instructure.com>

--- app/coffeescripts/views/outcomes/OutcomeView.coffee
+++ app/coffeescripts/views/outcomes/OutcomeView.coffee
@@ -40,14 +40,14 @@

     validations: _.extend
       mastery_points: (data) ->
-        if _.isEmpty(data.mastery_points) or parseInt(data.mastery_points) < 0
+        if _.isEmpty(data.mastery_points) or parseFloat(data.mastery_points) < 0
           I18n.t('mastery_error', 'Must be greater than or equal to 0')
     , OutcomeContentBase::validations

     # Validate before submitting.
     submit: (e) =>
       # set so handlebars doesn't put in placeholder text
-      points_possible = _.max _.map(_.pluck(@getFormData().ratings, 'points'), (n) -> parseInt n)
+      points_possible = _.max _.map(_.pluck(@getFormData().ratings, 'points'), (n) -> parseFloat n)
       @model.set {points_possible: points_possible}, silent: true
       super e

@@ -82,6 +82,7 @@
       $editWrapper.attr('aria-expanded', false).hide()
       $showWrapper.show()
       $showWrapper.find('.edit_rating').focus()
+      @updateRatings()

     insertRating: (e) =>
       e.preventDefault()
@@ -96,13 +97,13 @@
       total = 0
       for r in @$('.rating')
         rating = $(r).find('.outcome_rating_points').val() or 0
-        total = _.max [total, parseInt rating]
+        total = _.max [total, parseFloat rating]
         index = _i
         for i in $(r).find('input')
           # reset indices
           $(i).attr 'name', i.name.replace /\[[0-9]+\]/, "[#{index}]"
       points = @$('.points_possible')
-      points.html points.html().replace /[0-9]+/, total
+      points.html points.html().replace /[0-9/.]+/, total

     showRatingDialog: (e) =>
       e.preventDefault()


Destruction fix for text controls

Destruction fix for text controls

Prevents #setEnabled to be re-called for a zombie item.

--- js/controls/textcontrol/textcontrol.coffee
+++ js/controls/textcontrol/textcontrol.coffee
@@ -192,8 +192,9 @@
     @base(_flag)
     if @markupElemIds? and @markupElemIds.value?
       ELEM.get(@markupElemIds.value).disabled = !@enabled
-    else
-      @pushTask => @setEnabled(_flag)
+    else if not @isDead
+      @pushTask =>
+        @setEnabled(_flag) unless @isDead

   _clipboardEventTimer: null
   _getChangeEventFn: ->


Increase time between checks to avoid HTTP 429

--- scripts/watch-web-resources.coffee
+++ scripts/watch-web-resources.coffee
@@ -18,7 +18,7 @@
 request = require "request"
 hasher = require './hash-web-resources.coffee'

-PERIODIC_CHECKS_INTERVAL = 10000
+PERIODIC_CHECKS_INTERVAL = 60000
 MAX_SIZE_DOWNLOADED_FILES = 1000000
 periodicCheckId = null
 firstPeriodicCheck = true


update based on character position instead of sprite, allows floor detection based on floor height

--- scrolling/player-controller.coffee
+++ scrolling/player-controller.coffee
@@ -5,6 +5,10 @@
     # These represent the upper left corner of the hit box
     xPosition: 0
     yPosition: 0
+
+    # The offset of the box's origin point from the stage's origin point
+    xOffset: 0
+    yOffset: 0

     xVelocity: 0
     yVelocity: 0
@@ -21,12 +25,14 @@
     jumpToPosition: (position) ->
         @xPosition = position.x
         @yPosition = position.y - @hitBoxHeight
+        @xOffset = position.x
+        @yOffset = position.y - @hitBoxHeight

     addToStage: (stage) ->
         @hitBox = new PIXI.Graphics()
         @hitBox.beginFill 0xFF0000
-        @hitBox.drawRect @xPosition, @yPosition, @hitBoxWidth, @hitBoxHeight
-
+        @hitBox.drawRect @xOffset, @yOffset, @hitBoxWidth, @hitBoxHeight
+        window.box = @hitBox
         stage.addChild @hitBox

     update: (elapsedTime, inputState) ->
@@ -48,6 +54,7 @@
             @checkFloorCollision timeRatio

         @updatePosition timeRatio
+        @updateSprite()

     accelerateRight: (timeRatio) ->
         @xVelocity += @xAccelerationStep * timeRatio
@@ -79,15 +86,19 @@
             @xVelocity = @xAccelerationCap

     updatePosition: (timeRatio) ->
-        @hitBox.position.x += @xVelocity * timeRatio
-        @hitBox.position.y -= @yVelocity * timeRatio
+        @xPosition += @xVelocity * timeRatio
+        @yPosition -= @yVelocity * timeRatio
+
+    updateSprite: ->
+        @hitBox.position.x = @xPosition - @xOffset
+        @hitBox.position.y = @yPosition - @yOffset

     checkFloorCollision: (timeRatio) ->
-        y = @hitBox.position.y
+        y = @yPosition
         yStep = y - @yVelocity * timeRatio
-        console.log y, yStep
+        platformHeight = 500 - @hitBoxHeight

-        if y < 0 and yStep >= 0
+        if y < platformHeight and yStep >= platformHeight
             @jumping = false
             @yVelocity = 0
-            @hitBox.position.y = 0
+            @yPosition = platformHeight


OX-103 fixed rightclick in 3d-view

OX-103 fixed rightclick in 3d-view

--- app/assets/javascripts/libs/mouse.coffee
+++ app/assets/javascripts/libs/mouse.coffee
@@ -156,7 +156,8 @@
       # on leftclick, return mouse position relative to the canvas
       @changedCallbackLeftclick [evt.pageX - $(@target).offset().left, evt.pageY - $(@target).offset().top], 0
     else
-      @changedCallbackRightclick [evt.pageX - $(@target).offset().left, evt.pageY - $(@target).offset().top], 0
+      if @changedCallbackRightclick
+        @changedCallbackRightclick [evt.pageX - $(@target).offset().left, evt.pageY - $(@target).offset().top], 0

     return false


Add markdown to clipboard buffer when pressing button

--- app/assets/javascripts/uploads.js.coffee
+++ app/assets/javascripts/uploads.js.coffee
@@ -5,6 +5,7 @@
 sv_post_body = '.posts #post_body_sv, #page_body_sv'

 $ ->
+  new Clipboard('.copy-file');

   $(en_post_body + sv_post_body).fileupload
     url: '/uploads.json',
@@ -63,7 +64,7 @@

 addToFileList = (fileName, url) ->
   content = "
" + fileName + ""
-  content += "<button class='button tiny copy-file-link' data-markdown='" + link_markdown(fileName, url) + "'>Copy link
"
+  content += "<button class='button tiny copy-file' data-clipboard-text='" + link_markdown(fileName, url) + "'>Copy link
"
   #content = fileName + "
"
   $("#file-list").html(content)


red usually means bad things on a map, recolor to green

--- app/assets/transit/lib/views/plan.coffee
+++ app/assets/transit/lib/views/plan.coffee
@@ -58,7 +58,7 @@
     itinerary = Transit.plan.get('itineraries').first()
     colors = {'BUS': 'blue', 'WALK': 'black'}
     for leg in itinerary.get('legs')
-      @draw_polyline(leg.legGeometry.points, colors[leg.mode] ? 'red')
+      @draw_polyline(leg.legGeometry.points, colors[leg.mode] ? 'green')
     @map.addLayer(@plan_route)


Fix unit tests

Fix unit tests

--- test/lib/11-wsServerListener.coffee
+++ test/lib/11-wsServerListener.coffee
@@ -176,7 +176,7 @@

       it "should still receive log records", ->
         mainStory.info "Msg2 through web sockets"
-        h.waitUntil(1000, -> _spy.callCount > 0)
+        h.waitUntil(3000, -> _spy.callCount > 0)
         .then (res) ->
           expect(_spy).to.have.been.calledOnce
           msg = _spy.args[0][0]
@@ -215,7 +215,7 @@

     it "should receive log records", ->
       mainStory.info "Msg through web sockets"
-      h.waitUntil(1000, -> _spy.callCount > 0)
+      h.waitUntil(3000, -> _spy.callCount > 0)
       .then (res) ->
         expect(_spy).to.have.been.calledOnce
         msg = _spy.args[0][0]


tern -> atom-ternjs in menus

tern -> atom-ternjs in menus

--- menus/atom-ternjs.cson
+++ menus/atom-ternjs.cson
@@ -4,14 +4,14 @@
     {
       label: 'Atom Ternjs'
       submenu: [
-        {label: 'Find definition', command: 'tern:definition'},
-        {label: 'Find references', command: 'tern:references'},
-        {label: 'Documentation', command: 'tern:documentation'},
-        {label: 'Rename', command: 'tern:rename'},
-        {label: 'Configure project', command: 'tern:openConfig'},
-        {label: 'Restart server', command: 'tern:restart'},
-        {label: 'List analyzed files (console)', command: 'tern:listFiles'},
-        {label: 'Fetch all files and reanalyze', command: 'tern:flush'}
+        {label: 'Find definition', command: 'atom-ternjs:definition'},
+        {label: 'Find references', command: 'atom-ternjs:references'},
+        {label: 'Documentation', command: 'atom-ternjs:documentation'},
+        {label: 'Rename', command: 'atom-ternjs:rename'},
+        {label: 'Configure project', command: 'atom-ternjs:openConfig'},
+        {label: 'Restart server', command: 'atom-ternjs:restart'},
+        {label: 'List analyzed files (console)', command: 'atom-ternjs:listFiles'},
+        {label: 'Fetch all files and reanalyze', command: 'atom-ternjs:flush'}
       ]
     }
   ]
@@ -22,14 +22,14 @@
       {
         label: 'Atom Ternjs'
         submenu: [
-          {label: 'Configure project', command: 'tern:openConfig'},
-          {label: 'Restart server', command: 'tern:restart'},
-          {label: 'Find definition', command: 'tern:definition'},
-          {label: 'Find references', command: 'tern:references'},
-          {label: 'Documentation', command: 'tern:documentation'},
-          {label: 'Rename', command: 'tern:rename'},
-          {label: 'List analyzed files (console)', command: 'tern:listFiles'},
-          {label: 'Fetch all files and reanalyze', command: 'tern:flush'}
+          {label: 'Configure project', command: 'atom-ternjs:openConfig'},
+          {label: 'Restart server', command: 'atom-ternjs:restart'},
+          {label: 'Find definition', command: 'atom-ternjs:definition'},
+          {label: 'Find references', command: 'atom-ternjs:references'},
+          {label: 'Documentation', command: 'atom-ternjs:documentation'},
+          {label: 'Rename', command: 'atom-ternjs:rename'},
+          {label: 'List analyzed files (console)', command: 'atom-ternjs:listFiles'},
+          {label: 'Fetch all files and reanalyze', command: 'atom-ternjs:flush'}
         ]
       }
     ]


set req.user on sucessful login

set req.user on sucessful login

--- server/authentication/index.coffee
+++ server/authentication/index.coffee
@@ -41,6 +41,7 @@
           next info, null
         else
           console.log 'user is authenticated via hmac'
+          req.user = user
           next null, user
       )(req, res, next)

@@ -54,6 +55,7 @@
         else if not user
           next info, null
         else
+          req.user = user
           console.log 'user is authenticated via play'
           next null, user
       )(req, res, next)


Fix level session creation to use classroom language setting for course-ladder levels

--- server/levels/level_handler.coffee
+++ server/levels/level_handler.coffee
@@ -110,7 +110,7 @@
       Session.findOne(sessionQuery).exec (err, doc) =>
         return @sendDatabaseError(res, err) if err
         return @sendSuccess(res, doc) if doc?
-        if level.get('type') is 'course' or req.query.course?
+        if level.get('type') in ['course', 'course-ladder'] or req.query.course?
           return @makeOrRejectCourseLevelSession(req, res, level, sessionQuery)
         requiresSubscription = level.get('requiresSubscription') or (req.user.isOnPremiumServer() and level.get('campaign') and not (level.slug in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'forgetful-gemsmith', 'signs-and-portents', 'true-names']))
         canPlayAnyway = req.user.isPremium() or level.get 'adventurer'


Remove from finalizing queue

Remove from finalizing queue

--- server/serversystem/manager.coffee
+++ server/serversystem/manager.coffee
@@ -34,7 +34,7 @@
       srvr.send "add_dire_player "+plyr.steam+" "+plyr.name
     console.log "server configured"
     new Fiber(->
-      finalizeInstance(serverObj, lobby)
+      finalizeInstance(serverObj, lobby, instance)
     ).run()
   ).on('response', (str)->
     console.log "rcon response: "+str
@@ -68,8 +68,9 @@
     started: new Date().getTime()
   console.log "server launched, id: "+id+" waiting for configure"

-finalizeInstance = (serv, lobby)->
-  lobbies.update {_id: lobby}, {$set: {status: 3, serverIP: serv.ip+":"+port}}
+finalizeInstance = (serv, lobby, instance)->
+  lobbies.update {_id: lobby}, {$set: {status: 3, serverIP: serv.ip+":"+serv.port}}
+  pendingInstances.remove {id: instance.id}

 queueProc = ->
   #Find elegible servers


<Host>.power_state

--- src/spec.coffee
+++ src/spec.coffee
@@ -373,9 +373,14 @@
             size: 0
           }

-      # TODO
-      # get values of current_operations and if "shutdown" state Halted
-      power_state: 'Running'
+      power_state: ->
+        if (
+          @genval.enabled or
+          not $_.contains @genval.current_operations, 'shutdown'
+        )
+          'Running'
+        else
+          'Halted'

       # Local SRs are handled directly in `SR.$container`.
       SRs: $set {


Make it easy to disable caching.

Make it easy to disable caching.

--- src/view.coffee
+++ src/view.coffee
@@ -14,15 +14,14 @@
     if @autoRender
       @render object

-  cacheTemplate: ->
+  cacheTemplate: (el) ->
     # Cache on prototype so it can be reused
     @::_cachedEl = el

   renderTemplate: (ctx) ->
     if @_cachedEl? and cache
       # Clone node, rather than re-rendering template for each instance.
-      @el = @_cachedEl.cloneNode true
-      return @
+      return @_cachedEl.cloneNode true

     # Generate element template
     el = @template.call @, ctx
@@ -34,11 +33,11 @@
       el = div.removeChild childNodes[0]

     # Use el
-    @el = el
+    el

-  render: (ctx) ->
-    @renderTemplate ctx
-    @cacheTemplate()
+  render: (ctx, cache=true) ->
+    @el = @renderTemplate ctx
+    @cacheTemplate @el if cache

     for prop, fn in @bindings
       if (value = @model[prop]?)


Remove console log

Remove console log

--- annotran/static/scripts/widget-controller.coffee
+++ annotran/static/scripts/widget-controller.coffee
@@ -78,7 +78,6 @@
         if offset < total
           _loadAnnotationsFrom query, offset, crossframe

-        console.log("Passing annotations to substitution function via 'passAnnotations' event")
         crossframe.call "passAnnotations", results.rows
         annotationMapper.loadAnnotations(results.rows, results.replies)


adding decimalTwo method to admin form validator

--- app/assets/javascripts/admin/gramgoods.js.coffee
+++ app/assets/javascripts/admin/gramgoods.js.coffee
@@ -32,3 +32,7 @@
         return this.optional(element) || postal_code.match(/(^\d{5}(-\d{4})?$)|(^[ABCEGHJKLMNPRSTVXYabceghjklmnpstvxy]{1}\d{1}[A-Za-z]{1} ?\d{1}[A-Za-z]{1}\d{1})$/)
     , "Please specify a valid postal code")

+    $.validator.addMethod("decimalTwo", (value, element) ->
+        this.optional(element) or /^(\d{1,3})(\.\d{1,2})?$/.test(value) && value > 0
+    , "Must be in US currency format 0.99")
+


More CKEditor tweaking.

More CKEditor tweaking.

--- app/assets/javascripts/ckeditor/config.js.coffee
+++ app/assets/javascripts/ckeditor/config.js.coffee
@@ -1,6 +1,8 @@
 CKEDITOR.editorConfig = (config) ->
   # config.language = "fr"
   config.uiColor = "#AADC6E"
+  config.width = '575'
+  config.height = '450'

   config.toolbar_Pure = [
     { name: 'styles',      items: [ 'Format' ] },


Move the cursor/selection when using the rich text buttons

--- app/assets/javascripts/sugar/rich_text.js.coffee
+++ app/assets/javascripts/sugar/rich_text.js.coffee
@@ -15,10 +15,24 @@
       i = document.createElement("i")
       a.title = name
       a.textArea = @textArea
+
       jQuery(a).click ->
         selection = textArea.selectedText()
+
+        if typeof textArea.selectionStart != "undefined"
+          selectionStart = textArea.selectionStart
+          selectionEnd = textArea.selectionEnd
+
         [prefix, replacement, postfix] = callback(selection)
         textArea.replaceSelection(prefix + replacement + postfix)
+        $(textArea).focus()
+
+        if typeof textArea.setSelectionRange != "undefined"
+          textArea.setSelectionRange(
+            (selectionStart + prefix.length),
+            (selectionEnd + (replacement.length - selection.length) + prefix.length)
+          )
+
       jQuery(a).addClass className
       jQuery(i).addClass "icon-#{className}"
       jQuery(a).append(i)


Persist disabled docs list visibility state

--- assets/javascripts/views/sidebar/doc_list.coffee
+++ assets/javascripts/views/sidebar/doc_list.coffee
@@ -37,23 +37,32 @@
   render: =>
     @html @tmpl('sidebarDoc', app.docs.all())
     @renderDisabled() unless app.isSingleDoc() or app.disabledDocs.size() is 0
-    @refreshElements()
     return

   renderDisabled: ->
     @append @tmpl('sidebarDisabled', count: app.disabledDocs.size())
+    @refreshElements()
     @renderDisabledList()
     return

   renderDisabledList: ->
+    if (hidden = app.store.get 'hideDisabled') is true
+      @removeDisabledList()
+    else
+      app.store.set 'hideDisabled', false unless hidden is false
+      @appendDisabledList()
+    return
+
+  appendDisabledList: ->
     @append @tmpl('sidebarDisabledList', docs: app.disabledDocs.all())
+    @disabledTitle.classList.add('open-title')
     @refreshElements()
-    @disabledTitle.classList.add('open-title')
     return

   removeDisabledList: ->
-    @disabledList.remove()
+    @disabledList?.remove()
     @disabledTitle.classList.remove('open-title')
+    @refreshElements()
     return

   reset: ->
@@ -117,10 +126,13 @@
   onClick: (event) =>
     return unless @disabledTitle and $.hasChild @disabledTitle, event.target
     $.stopEvent(event)
+
     if @disabledTitle.classList.contains('open-title')
       @removeDisabledList()
+      app.store.set 'hideDisabled', true
     else
-      @renderDisabledList()
+      @appendDisabledList()
+      app.store.set 'hideDisabled', false

   afterRoute: (route, context) =>


client: home: team/user name swapped

client: home: team/user name swapped

--- client/home/lib/commons/homeappavatarview.coffee
+++ client/home/lib/commons/homeappavatarview.coffee
@@ -44,14 +44,11 @@
     , groupsController.getCurrentGroup()

-    # helpers.makePopupButton @accountIcon, @accountPopup
-    # @once 'viewAppended', -> mainView.addSubView @accountPopup
-

   pistachio: ->

     """
+    {{> @teamName}}
     {{> @profileName}}
-    {{> @teamName}}
     {{> @avatar}}
     """


Give default admin write access explicitly

--- coffees/src/controllers/league_controller.coffee
+++ coffees/src/controllers/league_controller.coffee
@@ -32,6 +32,7 @@
       createAdminQuery = models.Admin.create
         UserId: request.user.id
         LeagueId: league.id
+        write: true
       createAdminQuery.then ->
         findLeague(league.id).then (league) -> response.status(201).json(league)
       createAdminQuery.catch (error) ->


Only fade in tooltips instead of re-showing them

--- core/app/backbone/factlink/tooltip_opener.coffee
+++ core/app/backbone/factlink/tooltip_opener.coffee
@@ -24,15 +24,9 @@
   onClose: -> @_positionedRegion?.reset()

   _openTooltip: ->
-    unless @_positionedRegion?
-      region_options = _.extend {fadeTime: 100} , @options.positioning
-      @_positionedRegion = new Backbone.Factlink.PositionedRegion region_options
-      @_positionedRegion.bindToElement @options.$tooltipElement, @options.$offsetParent
-
-      @_hoverintent @_positionedRegion.$el, 'inTooltip' if @options.stayWhenHoveringTooltip
-
-    @_positionedRegion.show @_tooltipView()
+    @_renderTooltip()
     @_positionedRegion.updatePosition()
+    @_positionedRegion.fadeIn()

     @_tooltipOpened = true

@@ -55,8 +49,15 @@

     @on 'close', -> $element.off('.hoverIntent')

-  _tooltipView: ->
-    tooltipOptions = _.extend {},
+  _renderTooltip: ->
+    return if @_positionedRegion?
+
+    region_options = _.extend {fadeTime: 100} , @options.positioning
+    @_positionedRegion = new Backbone.Factlink.PositionedRegion region_options
+    @_positionedRegion.bindToElement @options.$tooltipElement, @options.$offsetParent
+
+    @_positionedRegion.show new PopoverView _.extend {},
       contentView: @options.tooltipViewFactory(),
       @options.positioning
-    new PopoverView tooltipOptions
+
+    @_hoverintent @_positionedRegion.$el, 'inTooltip' if @options.stayWhenHoveringTooltip


Improving performance by not setting webkit* styles multiple times during applyDefaults

--- framer/Layer.coffee
+++ framer/Layer.coffee
@@ -54,12 +54,13 @@

 			mainElement = @_element if includeMainElement or not targetElement
 			subElement = @[targetElement] if targetElement?
-
 			if cssProperty isnt null
 				if name is cssProperty and not LayerStyle[cssProperty]?
 					mainElement?.style[cssProperty] = @_properties[name]
 					subElement?.style[cssProperty] = @_properties[name]
-				else
+				else if not @__applyingDefaults
+						# These values are set multiple times during applyDefaults, so ignore them here, and set the style in the constructor
+						or (cssProperty not in ["webkitTransform", "webkitFilter", "webkitPerspectiveOrigin", "webkitTransformOrigin"])
 					style = LayerStyle[cssProperty](@)
 					mainElement?.style[cssProperty] = style
 					subElement?.style[cssProperty] = style
@@ -203,7 +204,13 @@
 			options.parent = options.superLayer
 			delete options.superLayer

+		@__applyingDefaults = true
 		super Defaults.getDefaults("Layer", options)
+		delete @__applyingDefaults
+		@_element.style["webkitTransform"] = LayerStyle["webkitTransform"](@)
+		@_element.style["webkitFilter"] = LayerStyle["webkitFilter"](@)
+		@_element.style["webkitTransformOrigin"] = LayerStyle["webkitTransformOrigin"](@)
+		@_element.style["webkitPerspectiveOrigin"] = LayerStyle["webkitPerspectiveOrigin"](@)

 		# Add this layer to the current context
 		@_context.addLayer(@)


Update index.coffee

Update index.coffee

--- ui/tests/views/index.coffee
+++ ui/tests/views/index.coffee
@@ -0,0 +1,4 @@
+describe.skip('IndexView', ->
+    it('should show login or signup on logged out', ->)
+    it('should show links to sections on logged in', ->)
+)


#49 add click handle

#49 add click handle

--- app/assets/javascripts/components/course_tag.js.jsx.coffee
+++ app/assets/javascripts/components/course_tag.js.jsx.coffee
@@ -5,6 +5,10 @@
     super props
     @state =
       count: 0
+
+  handleClick: (_event) ->
+    count = @state.count
+    @setState(count: count + 1)

   render: ->
     div className: 'panel panel-danger',
@@ -18,5 +22,9 @@
             div className: 'col-md-2',
               input className: 'form-control', placeholder: 'Термин (rus/eng)',
             div className: 'col-md-2',
-              button className: 'btn btn-default btn-xs',
+              button {
+                type: 'button',
+                className: 'btn btn-default btn-xs',
+                onClick: ((e) => @handleClick(e))
+              },
                 i className: 'fa fa-fw fa-plus',


made families.js more generic

made families.js more generic

--- app/assets/javascripts/summer_residents/families.js.coffee
+++ app/assets/javascripts/summer_residents/families.js.coffee
@@ -1,51 +1,55 @@
 SR = window.SummerResidents

-edit_link = -> $('div.summer_residents_family div.summer_residents_resident a.edit_resident_link')
-type = (id) -> $("div.summer_residents_family div#summer_residents_resident_"+id+" input#resident_type_"+id).val()
-update_link = (id) -> $('div.summer_residents_family div.summer_residents_resident a#update_resident_link_'+id)
-show_link = (id) -> $('div.summer_residents_family div.summer_residents_resident a#show_resident_link_'+id)
-update_form = (id) -> $('div.summer_residents_family div.summer_residents_resident form#update_resident_form_'+id)
+edit_link = (model)-> $('div.summer_residents_family div.summer_residents_'+model+' a.edit_'+model+'_link')
+type = (id) -> 'type='+$("div.summer_residents_family div#summer_residents_resident_"+id+" input#resident_type_"+id).val()
+update_link = (id,model) -> $('div.summer_residents_family div.summer_residents_'+model+' a#update_'+model+'_link_'+id)
+show_link = (id,model) -> $('div.summer_residents_family div.summer_residents_'+model+' a#show_'+model+'_link_'+id)
+update_form = (id,model) -> $('div.summer_residents_family div.summer_residents_'+model+' form#update_'+model+'_form_'+id)
 delete_link = $('div.summer_residents_family a.delete_family_link')
-url = (id) -> "/summer_residents/residents/"+id
-edit_or_new_url = (id) -> if id then (url(id) + "/edit") else (url("new"))
+url = (id,model) -> '/summer_residents/'+model+'s/'+id
+edit_or_new_url = (id,model) -> if id then (url(id,model) + "/edit") else (url("new",model))
 fam_id = (elem) -> 'fam_id='+SR.item_id('summer_residents_family', $(elem).parent().parent().attr('id'))+'&'

 delete_link.keep_centered()

-ajax_show = (id, fam, update) ->
+ajax_show = (id, fam, model, update) ->
   xhr
   if update
     xhr = $.ajax
-      url: url(id),
+      url: url(id, model),
       type: if id then "PUT" else "POST",
-      data: fam+update_form(id).serialize()
+      data: fam+update_form(id,model).serialize()
   else
     xhr = $.ajax
-      url:  edit_or_new_url(id)
+      url:  edit_or_new_url(id, model)
       type: "GET",
-      data: fam+"type="+type(id)+"&cancel=true"
+      data: fam+"cancel=true" + (if 'resident' == model then '&'+type(id) else '')
   xhr.done ->
     xhr.responseText
-    edit_link().click -> ajax_edit this
+    set_edit_link(model)
   xhr.fail -> SR.ajax_fail(xhr)
   false

-ajax_edit = (elem) ->
-  id = SR.item_id('edit_resident_link', elem.id)
+ajax_edit = (elem, model) ->
+  id = SR.item_id('edit_'+model+'_link', elem.id)
   fam = fam_id(elem)
   xhr = $.ajax
-    url:  edit_or_new_url(id)
-    type: "GET",
-    data: fam+"type="+type(id)
+    url:  edit_or_new_url(id, model)
+    type: "GET"
+    data: fam + if 'resident' == model then type(id) else ''
   xhr.done ->
     xhr.responseText
-    update_link(id).click -> ajax_show(id, fam, true)
-    show_link(id).click -> ajax_show(id, fam)
+    update_link(id, model).click -> ajax_show(id, fam, model, true)
+    show_link(id, model).click -> ajax_show(id, fam, model)
   xhr.fail -> SR.ajax_fail(xhr)
   false

+set_edit_link = (model) -> edit_link(model).click -> ajax_edit(this, model)
+
 $ ->
-  edit_link().click -> ajax_edit this
+  delete_link.keep_centered()
+
+  set_edit_link(model) for model in ['resident']

   delete_link.click ->
     id = SR.item_id('delete_family_link', this.id)


Add section highlighting for .cabal files

Add missing section headings for Cabal package descriptions to
the grammar file for highlighting. e.g., test-suite, flag, etc.

--- grammars/cabal.cson
+++ grammars/cabal.cson
@@ -39,7 +39,7 @@
       }

       {
-          'match':'(executable)\\s+(\\S+)'
+          'match': '(benchmark|executable|flag|source-repository|test-suite)\\s+(\\S+)'
           'captures':
             '1':
                 'name':'entity.name.function'


Add object/string methods for each status type.


Workspace: Fix sidebar navigation item option

--- client/Main/navigation/navigationmachineitem.coffee
+++ client/Main/navigation/navigationmachineitem.coffee
@@ -31,7 +31,7 @@
       title            : "Open IDE for #{@alias}"

     unless machineOwner is KD.nick()
-      options.attributes.href += " (shared by @#{Encoder.htmlDecode machineOwner})"
+      options.attributes.title += " (shared by @#{Encoder.htmlDecode machineOwner})"

     super options, data


guest vms: don't initialize them from the client side

since guest accounts feature is somewhat "disabled", we should waste resources having the os kite prepare vms for guests.  Just don't call reset initially for guest accounts, as a dead-simple solution.

--- client/app/MainApp/sidebar/sidebarcontroller.coffee
+++ client/app/MainApp/sidebar/sidebarcontroller.coffee
@@ -34,7 +34,9 @@

     avatarAreaIconMenu.accountChanged account

-    finderController.reset()
+    # get registered users vms all ready to go (don't for guests right now):
+    finderController.reset()      if "registered" is account.type
+
     resourcesController.reset()

   resetAdminNavItems:->


Code refactoring

Code refactoring

--- client/app/lib/avatararea/avatarareaiconlink.coffee
+++ client/app/lib/avatararea/avatarareaiconlink.coffee
@@ -35,7 +35,7 @@
     popup = @getDelegate()
     popup.show()

-    popup.once 'NotificationListItemClicked', (event) =>
+    popup.once 'NotificationListItemClicked', (event) ->
       listItemClicked = yes

     popup.once 'ReceivedClickElsewhere', (event) =>


[grunt] install `textdomain()` for Nunjucks with other gettext globals

--- modules/gettext.coffee
+++ modules/gettext.coffee
@@ -140,6 +140,8 @@
       # i18n functions
       # --------------

+      env.addGlobal 'textdomain', (domain) => @textdomain(arguments...)
+
       env.addGlobal 'gettext', (string) => @gettext(arguments...)
       env.addGlobal 'dgettext', (domain, string) => @dgettext(arguments...)
       env.addGlobal 'ngettext', (string, pluralString, count) => @ngettext(arguments...)


just add link to wiki

just add link to wiki

--- src/smc-webapp/project_page.cjsx
+++ src/smc-webapp/project_page.cjsx
@@ -227,6 +227,15 @@
             height     : 0
         ×

+    render_learn_more: ->
+
+            learn more...
+
+        #@actions(project_id: @props.project_id).show_extra_free_warning()} style={color:'white', cursor:'pointer'}> learn more...
+
     render: ->
         if not @props.project_log?
             return null
@@ -266,7 +275,7 @@
         <Alert bsStyle='danger' style={styles}>
             <Icon name='exclamation-triangle' style={float:'right', marginTop: '3px'}/>
             <Icon name='exclamation-triangle' /> Upgrade this project, since it is {on a free server if host} {without internet access if internet}. —
-            @actions(project_id: @props.project_id).show_extra_free_warning()} style={color:'white', cursor:'pointer'}> learn more...
+            {@render_learn_more()}
             {@render_dismiss()}
             {@extra(host, internet)}
         </Alert>


Show the sub-menus on left if there is not enough space on right

--- client/Framework/components/contextmenu/contextmenu.coffee
+++ client/Framework/components/contextmenu/contextmenu.coffee
@@ -37,7 +37,7 @@
       @treeController.getView().on 'ReceivedClickElsewhere', => @destroy()

       @treeController.on "NodeExpanded", @bound "positionSubMenu"
-
+
     if options.arrow
       @on "viewAppended", @bound "addArrow"

@@ -121,4 +121,8 @@
       expandView = @treeController.listControllers[id].getView()
       fullViewHeight = expandView.getY() + expandView.getHeight()
       if fullViewHeight > window.innerHeight
-        expandView.$().css "bottom", 0+        expandView.$().css "bottom", 0
+      fullViewWidth = expandView.getX() + expandView.getWidth()
+      if fullViewWidth > window.innerWidth
+        expandView.$().css "left", - expandView.getWidth()
+        expandView.setClass "left-aligned"


updating status function to use new distinct collection count function

--- noddy/service/oabutton/status.coffee
+++ noddy/service/oabutton/status.coffee
@@ -11,5 +11,6 @@
     received: oab_request.count {status:'received'}
     supports: oab_support.count()
     availabilities: oab_availability.count()
-    users: Users.count {"roles.openaccessbutton":'*'}
+    users: Users.count {exists:{field:"roles.openaccessbutton"}}
+    requested: oab_request.count {exists:{field:'user.id'}}, 'user.id'
     #requested: oab_request.aggregate( [ { $group: { _id: "$user"}  } ] ).length # need an alternative to aggregate


Update text for outermost describe

Update text for outermost describe

--- spec/zip-spec.coffee
+++ spec/zip-spec.coffee
@@ -1,7 +1,7 @@
 archive = require '../lib/ls-archive'
 path = require 'path'

-describe "zip file listing", ->
+describe "zip files", ->
   fixturesRoot = null

   beforeEach ->


Always forceUpdate when editor component is visible

Fixes #5187. Giving up after 90 minutes on producing a failing test case
because this is all changing soon anyway and getting simpler. I’m
willing to risk this regressing to solve it now and move on.

--- src/text-editor-component.coffee
+++ src/text-editor-component.coffee
@@ -224,7 +224,7 @@
     @props.editor.setVisible(true)
     @performedInitialMeasurement = true
     @updatesPaused = false
-    @forceUpdate() if @updateRequestedWhilePaused and @canUpdate()
+    @forceUpdate() if @canUpdate()

   requestUpdate: ->
     return unless @canUpdate()


Rename to TextEditorPresenter::invalidateState

--- src/text-editor-presenter.coffee
+++ src/text-editor-presenter.coffee
@@ -35,7 +35,7 @@
     @observeModel()
     @observeConfig()
     @buildState()
-    @invalidate()
+    @invalidateState()
     @startBlinkingCursors() if @focused
     @startReflowing() if @continuousReflow
     @updating = false
@@ -128,7 +128,7 @@
     @shouldUpdateGutterOrderState = false
     @shouldUpdateCustomGutterDecorationState = false

-  invalidate: ->
+  invalidateState: ->
     @shouldUpdateFocusedState = true
     @shouldUpdateHeightState = true
     @shouldUpdateVerticalScrollState = true


Fixes #4377 - The local time zone overwrites the one set in Zammad

--- app/assets/javascripts/app/controllers/_plugin/default_timezone.coffee
+++ app/assets/javascripts/app/controllers/_plugin/default_timezone.coffee
@@ -1,35 +0,0 @@
-class DefaultTimezone extends App.Controller
-  constructor: ->
-    super
-
-    check = =>
-      timezone = App.i18n.detectBrowserTimezone()
-      return if !timezone
-
-      # check system timezone_default
-      if _.isEmpty(@Config('timezone_default')) && @permissionCheck('admin.system')
-        App.Setting.fetchFull(
-          => @updateSetting(timezone)
-          force: false
-        )
-
-      # prepare user based timezone
-      # check current user timezone
-      #preferences = App.Session.get('preferences')
-      #return if !preferences
-      #return if !_.isEmpty(preferences.timezone)
-      #@ajax(
-      #  id:          "i18n-set-user-timezone"
-      #  type:        'PUT'
-      #  url:         "#{App.Config.get('api_path')}/users/preferences"
-      #  data:        JSON.stringify(timezone: timezone)
-      #  processData: true
-      #)
-
-    if App.Session.get() isnt undefined
-      @delay(check, 8500, 'default_timezone')
-
-  updateSetting: (timezone) ->
-    App.Setting.set('timezone_default', timezone)
-
-App.Config.set('default_timezone', DefaultTimezone, 'Plugins')


Use translation for co-firing coal in profit table

Ref #1875

--- app/assets/javascripts/lib/views/plant_profitability_table_view.coffee
+++ app/assets/javascripts/lib/views/plant_profitability_table_view.coffee
@@ -62,6 +62,7 @@
     energy_power_turbine_network_gas: 'gas_turbine'
     energy_power_ultra_supercritical_ccs_coal: 'coal_pwd_ccs'
     energy_power_ultra_supercritical_coal: 'coal_pwd'
+    energy_power_ultra_supercritical_cofiring_coal: 'coal_pwd_cofiring'
     energy_power_ultra_supercritical_crude_oil: 'oil_plant'
     energy_power_ultra_supercritical_lignite: 'lignite'
     energy_power_ultra_supercritical_network_gas: 'gas_conv'


Fix wrong key and avoid error on null

Fix wrong key and avoid error on null

--- resources/assets/lib/store-xsolla.coffee
+++ resources/assets/lib/store-xsolla.coffee
@@ -23,7 +23,7 @@
       $.post route('payments.xsolla.token'), { orderNumber }
       .done (data) ->
         # Make sure laroute hasn't trolled us.
-        return reject(message: 'wrong token length') unless data.token.length == 32
+        return reject(message: 'wrong token length') unless data.access_token?.length == 32
         resolve(data)
       .fail (xhr) ->
         reject(xhr: xhr)


merged

merged

--- bokehjs/src/coffee/tool/zoom_tool.coffee
+++ bokehjs/src/coffee/tool/zoom_tool.coffee
@@ -47,9 +47,11 @@
       sy_high = yr.get('end')

       [xstart, xend] = @plot_view.xmapper.v_map_from_target([
-        sx_low  - (sx_low  - x)*factor, sx_high - (sx_high - x)*factor])
+        sx_low  - (sx_low  - x)*factor, sx_high - (sx_high - x)*factor
+      ])
       [ystart, yend] = @plot_view.ymapper.v_map_from_target([
-        sy_low  - (sy_low  - y)*factor, sy_high - (sy_high - y)*factor])
+        sy_low  - (sy_low  - y)*factor, sy_high - (sy_high - y)*factor
+      ])

       zoom_info = {
         xr: {start: xstart, end: xend}


Remove require statement

Remove require statement

--- src/RedisPort.coffee
+++ src/RedisPort.coffee
@@ -3,7 +3,6 @@
 { EventEmitter } = require "events"
 path             = require "path"
 redis            = require "redis"
-winston          = require "winston"
 _                = require "underscore"

 log = require "./log"


ApplicationManager:open optional showInstace, true by default

--- client/app/lib/applicationmanager.coffee
+++ client/app/lib/applicationmanager.coffee
@@ -108,9 +108,12 @@
       appParams = options.params or {}

       if appOptions?.multiple
-        if options.forceNew or appOptions.openWith is 'forceNew'
+        { forceNew, showInstance = yes } = options
+        if forceNew or appOptions.openWith is 'forceNew'
           return @create name, appParams, (appInstance) =>
-            @showInstance appInstance, callback
+            if showInstance
+            then @showInstance appInstance, callback
+            else kd.utils.defer -> callback appInstance

         switch appOptions.openWith
           when 'lastActive' then do defaultCallback


TEST:WELCOME Fix Pause Calls

TEST:WELCOME Fix Pause Calls

--- client/test/lib/dashboard/welcome.coffee
+++ client/test/lib/dashboard/welcome.coffee
@@ -50,10 +50,12 @@
       .url welcomeLink
       .waitForElementVisible WelcomeView, 20000
       .click teamLink
+      .pause 1000
       .waitForElementVisible teamSettings, 20000
       .url welcomeLink
       .waitForElementVisible WelcomeView, 20000
       .click installKDLink
+      .pause 1000
       .waitForElementVisible kodingUtilities, 20000

     #Test Team Billing Screen


videoLinkShell: integrate rangeslider widget

--- coffee/src/shells/videolink.shell.coffee
+++ coffee/src/shells/videolink.shell.coffee
@@ -173,13 +173,11 @@
       start: @model.timeStart()
       end: @model.timeEnd()

-    # TODO: add rangeslider functionality
-    # @setupSlider()
+    @setupSlider()

   setupSlider: =>
     max = @model.timeTotal()

-    # TODO: add rangeslider functionality
     @$('.time-slider').rangeslider
       min: 0
       max: max
@@ -276,9 +274,8 @@
     @$('.end').val secondsToTimestring(end, {forceMinutes: true})
     @$('.total-time').text time

-    # TODO: add rangeslider functionality
-    # if options.updateSlider or invalidTimes
-      # @$('.time-slider').rangeslider values: [start, end]
+    if options.updateSlider or invalidTimes
+      @$('.time-slider').rangeslider values: [start, end]

   timeError: =>
     # 2 seconds of error display


Add additional fields on block query

Add additional fields on block query

--- components/block_v2/queries/block.coffee
+++ components/block_v2/queries/block.coffee
@@ -9,8 +9,20 @@
     user {
       name
     }
+    source {
+      provider_name
+      url
+      title
+    }
     kind {
       __typename
+      ... on Channel {
+        visibility
+        href
+        counts {
+          blocks
+        }
+      }
       ... on Embed {
         image_url
         embed_html
@@ -19,7 +31,7 @@
         image_url
       }
       ... on Text {
-        content
+        content(format: MARKDOWN)
       }
       ... on Link {
         image_url


spec: {{friendlyDatetime}} handlebar helper

Change-Id: Ic5b697c48b6f5f133d240745b7cc82598df6a6cb
Reviewed-on: https://gerrit.instructure.com/31982
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Braden Anderson <a6cc2cef7d25f27847876bdb81651755fcebacf0@instructure.com>
Product-Review: Jacob Fugal <f862f167b85d41b225785c70d70808bc7337c1fe@instructure.com>
QA-Review: Jacob Fugal <f862f167b85d41b225785c70d70808bc7337c1fe@instructure.com>

--- spec/coffeescripts/handlebars_helpersSpec.coffee
+++ spec/coffeescripts/handlebars_helpersSpec.coffee
@@ -2,7 +2,9 @@
   'compiled/handlebars_helpers'
   'jquery'
   'underscore'
-], ({helpers}, $, _) ->
+  'timezone'
+  'vendor/timezone/America/Detroit'
+], ({helpers}, $, _, tz, detroit) ->

   module 'handlebars_helpers'

@@ -66,3 +68,23 @@
     text = "going to the store"
     truncText = helpers.truncate_left text, 15
     equal truncText, "...to the store", "Reverse truncates"
+
+  module 'friendlyDatetime',
+    setup: -> @snapshot = tz.snapshot()
+    teardown: -> tz.restore(@snapshot)
+
+  test 'can take an ISO string', ->
+    tz.changeZone(detroit, 'America/Detroit')
+    # the datetime attribute in the output element is (for now) inappropriately
+    # fudged, so we need to cover that in the spec. we'll correct it in a later
+    # commit where we can manage all the ramifications
+    datetime = $.fudgeDateForProfileTimezone(new Date(0)).toISOString()
+    equal helpers.friendlyDatetime('1970-01-01 00:00:00Z', hash: {pubDate: false}).string,
+      "<time title='Dec 31, 1969 at 7pm' datetime='#{datetime}' undefined>Dec 31, 1969</time>"
+
+  test 'can take a date object', ->
+    tz.changeZone(detroit, 'America/Detroit')
+    # ditto
+    datetime = $.fudgeDateForProfileTimezone(new Date(0)).toISOString()
+    equal helpers.friendlyDatetime(new Date(0), hash: {pubDate: false}).string,
+      "<time title='Dec 31, 1969 at 7pm' datetime='#{datetime}' undefined>Dec 31, 1969</time>"


:memo: describe --json flag

:memo: describe --json flag

--- src/available.coffee
+++ src/available.coffee
@@ -21,6 +21,7 @@
       List all the Atom packages that have been published to the apm registry.
     """
     options.alias('h', 'help').describe('help', 'Print this usage message')
+    options.boolean('json').describe('json', 'Output available packages as JSON array')

   showHelp: (argv) -> @parseOptions(argv).showHelp()


Fix up the xml schema collection integration tests.

--- test/integration/datatypes-in-results-test.coffee
+++ test/integration/datatypes-in-results-test.coffee
@@ -268,27 +268,31 @@
   xml = '<root/>'

   schemaName = 'test_tedious_schema'
+  tableName = 'test_tedious_table'
+
   schema = '''
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:element name="root">
       </xsd:element>
     </xsd:schema>'''

-  dropSchema = """
-    begin try
-      drop xml schema collection #{schemaName}
-    end try begin catch end catch;
+  sql = """
+    IF OBJECT_ID('#{tableName}', 'U') IS NOT NULL
+      DROP TABLE [#{tableName}];
+
+    IF EXISTS (SELECT * FROM [sys].[xml_schema_collections] WHERE [name] = '#{schemaName}' AND [schema_id] = SCHEMA_ID())
+      DROP XML SCHEMA COLLECTION [#{schemaName}];
+
+    CREATE XML SCHEMA COLLECTION [#{schemaName}] AS N'#{schema}';
+
+    EXEC('CREATE TABLE [#{tableName}] ([xml] [xml]([#{schemaName}]))');
+
+    INSERT INTO [#{tableName}] ([xml]) VALUES ('#{xml}');
+
+    SELECT [xml] FROM [#{tableName}];
   """

-  createSchema = "create xml schema collection #{schemaName} as N'#{schema}';"
-
-  tableName = 'test_tedious_table'
-  dropTable = "drop table #{tableName};"
-  createTable = "create table #{tableName} (xml XML (#{schemaName}));"
-  insert = "insert into #{tableName} (xml) values('#{xml}');"
-  select = "select xml from #{tableName};"
-
-  execSql(test, "#{dropTable} #{dropSchema} #{createSchema} #{createTable} #{insert} #{select}", xml, '7_2')
+  execSql(test, sql, xml, '7_2')

 exports.udt = (test) ->
   execSql(test, "select geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326) as geo", new Buffer([230,16,0,0,1,20,135,22,217,206,247,211,71,64,215,163,112,61,10,151,94,192,135,22,217,206,247,211,71,64,203,161,69,182,243,149,94,192]), '7_2')


fix typo in comment

fix typo in comment

--- app/assets/javascripts/components/signup/signup.js.coffee
+++ app/assets/javascripts/components/signup/signup.js.coffee
@@ -35,7 +35,7 @@
       anonymous: Portal.currentUser.isAnonymous

     onBasicDataSubmit: (data) ->
-      # Save the current path. Backed can use that information to redirect user to this page the first time he logs in.
+      # Save the current path. Backend can use that information to redirect user to this page the first time he logs in.
       data.sign_up_path = location.pathname
       @setState basicData: data


remove redundant test

remove redundant test

--- spec/tree-view-package-spec.coffee
+++ spec/tree-view-package-spec.coffee
@@ -3243,12 +3243,6 @@
         expect(treeView.list).toHaveClass('multi-select')
         fileView3.dispatchEvent(new MouseEvent('mousedown', {bubbles: true}))
         expect(treeView.list).toHaveClass('full-menu')
-
-    describe 'selecting multiple items', ->
-      it 'switches the contextual menu to muli-select mode', ->
-        fileView1.dispatchEvent(new MouseEvent('click', {bubbles: true, detail: 1}))
-        fileView2.dispatchEvent(new MouseEvent('mousedown', {bubbles: true, shiftKey: true}))
-        expect(treeView.list).toHaveClass('multi-select')

       describe 'using the shift key', ->
         it 'selects the items between the already selected item and the shift clicked item', ->


Still working on it...

Still working on it...

--- app/assets/javascripts/sprangular/services/catalog.coffee
+++ app/assets/javascripts/sprangular/services/catalog.coffee
@@ -34,7 +34,7 @@
     find: (id) ->
       $http.get("/api/products/#{id}", class: Sprangular.Product)
         .then (response) ->
-          console.log response.data
+          console.log response

     getPaged: (page=1, params={}) ->
       $http.get("/api/products", ignoreLoadingIndicator: params.ignoreLoadingIndicator, params: {per_page: @pageSize, page: page, "q[name_or_description_cont]": params.search, "q[taxons_permalink_eq]": params.taxon})


Fix intermittent test failure re: destroying tree view

--- spec/tree-view-package-spec.coffee
+++ spec/tree-view-package-spec.coffee
@@ -306,6 +306,8 @@

   describe "when the tree-view is destroyed", ->
     it "can correctly re-create the tree-view", ->
+      treeView.useSyncFS = true
+
       treeView = atom.workspace.getLeftDock().getActivePaneItem()
       treeViewHTML = treeView.element.outerHTML
       treeView.roots[0].collapse()


Get rid of cached sorting - it's just never necessary

As per @janpaul123's suggestion, this was premature optimization

--- app/js/jail_iframe/classes/performance_measurement.coffee
+++ app/js/jail_iframe/classes/performance_measurement.coffee
@@ -1,5 +1,4 @@
 load_moments = []
-last_sorted = 0

 add_timing_event = (name) ->
   add_existing_timing_event name, new Date().getTime()
@@ -7,12 +6,7 @@
 add_existing_timing_event = (name, time) ->
   load_moments.push(Object.freeze(name:name, time: time, idx: load_moments.length))

-get_sorted_moments = ->
-  if(load_moments.length > last_sorted)
-    load_moments.sort (x,y) ->
-      x.time - y.time || x.idx - y.idx
-    last_sorted = load_moments.length
-  load_moments.slice(0)
+get_sorted_moments = -> load_moments.sort (x,y) -> x.time - y.time || x.idx - y.idx

 get_relative_timings = ->
   sorted_moments = get_sorted_moments()


Workspace: Fixed isJoinedASession on workspace.

--- client/landing/app/CommonViews/workspace/collaborativeworkspace.coffee
+++ client/landing/app/CommonViews/workspace/collaborativeworkspace.coffee
@@ -166,7 +166,8 @@
     @loader.on "viewAppended", -> loaderView.show()
     @container.addSubView @loader

-  isJoinedASession: -> return @getOptions().joinedASession
+  isJoinedASession: ->
+    return @getHost() isnt KD.nick()

   joinSession: (newOptions) ->
     options                = @getOptions()


Workspace: Fixed starting a new session in disconnected modal.

--- client/landing/app/CommonViews/workspace/collaborativeworkspace.coffee
+++ client/landing/app/CommonViews/workspace/collaborativeworkspace.coffee
@@ -91,13 +91,15 @@
     notValid.addSubView new KDButtonView
       cssClass : "cupid-green"
       title    : "Start New Session"
-      callback : =>
-        @destroySubViews()
-        options = @getOptions()
-        delete options.sessionKey
-        @addSubView new CollaborativeWorkspace options
+      callback : @bound "startNewSession"

     @container.addSubView notValid
+
+  startNewSession: ->
+    @destroySubViews()
+    options = @getOptions()
+    delete options.sessionKey
+    @addSubView new CollaborativeWorkspace options

   showDisconnectedModal: ->
     @disconnectedModal = new KDModalView
@@ -111,7 +113,7 @@
           callback : =>
             @disconnectedModal.destroy()
             delete @disconnectedModal
-            @showSessionModal()
+            @startNewSession()
         Join       :
           title    : "Join Another Session"
           callback : =>


Adding collision FIXMEs.

Adding collision FIXMEs.

--- src/collision.coffee
+++ src/collision.coffee
@@ -60,6 +60,12 @@
         magnitude = velocity * @getMass()
         impulse = @getContactNormal().scale(magnitude)

+        # FIXME: I think this shouldn't be setting the velocity, but rather
+        # applying an impulse.
+
+        # FIXME: What about colliding with static objects? How do you add
+        # inverse gravity to make people not fall through the ground.
+
         # Apply the force of the collision to each element in proportion to
         # it's mass.
         impulse1 = impulse.scale(@element1.getInverseMass())


remove URL setting in create proposal; just slugify name

--- @client/edit_proposal.coffee
+++ @client/edit_proposal.coffee
@@ -142,26 +142,26 @@
               t('error_free')
             '.'

-        if fetch('/current_user').is_admin
-          DIV style: block_style,
-            LABEL htmlFor:'slug', style: label_style, 'URL:'
-
-            BR null
-            SPAN
-              style:
-                fontSize: 20
-                color: '#aaa'
-              "#{location.origin}/"
-            INPUT
-              id:'slug'
-              name:'slug'
-              pattern:'^.{3,}'
-              placeholder: t('url_instr')
-              required:'required'
-              defaultValue: if @props.fresh then null else proposal.slug
-              style: _.extend {}, input_style,
-                width: 400
-                display: 'inline-block'
+        # if fetch('/current_user').is_admin
+        #   DIV style: block_style,
+        #     LABEL htmlFor:'slug', style: label_style, 'URL:'
+
+        #     BR null
+        #     SPAN
+        #       style:
+        #         fontSize: 20
+        #         color: '#aaa'
+        #       "#{location.origin}/"
+        #     INPUT
+        #       id:'slug'
+        #       name:'slug'
+        #       pattern:'^.{3,}'
+        #       placeholder: t('url_instr')
+        #       required:'required'
+        #       defaultValue: if @props.fresh then null else proposal.slug
+        #       style: _.extend {}, input_style,
+        #         width: 400
+        #         display: 'inline-block'

         DIV style: block_style,
           LABEL htmlFor:'name', style: label_style, t('Summary') + ':'
@@ -423,7 +423,7 @@
     name = $el.find('#name').val()
     description = fetch("description-#{@data().key}").html

-    slug = $el.find('#slug').val() or slugify(name)
+    slug = slugify(name)

     cluster = $el.find('#cluster').val()
     cluster = null if cluster == ""


Adapt to Paw JS API version 0.2.0

Adapt to Paw JS API version 0.2.0

--- APIBlueprintGenerator.coffee
+++ APIBlueprintGenerator.coffee
@@ -1,4 +1,10 @@
-require "mustache.js"
+# in API v0.2.0 and below (Paw 2.2.2 and below), require had no return value
+((root) ->
+  if root.bundle?.minApiVersion('0.2.0')
+    root.Mustache = require("./mustache")
+  else
+    require("mustache.js")
+)(this)

 APIBlueprintGenerator = ->


Add animationloop settings

Add animationloop settings

--- framer/AnimationLoop.coffee
+++ framer/AnimationLoop.coffee
@@ -8,11 +8,18 @@
 else
 	getTime = -> Date.now()

+
+# Make the time ticks a "fixed" 1/60 of a second.
+# Framer.Loop.delta = 1/60
+
+# Include workaround for a WebKit2 browser bug
+# Framer.Loop.raf = false
+
 class exports.AnimationLoop extends EventEmitter

 	constructor: ->

-		@fps = 60
+		@delta = null
 		@raf = true

 		# Workaraound for RAF bug on 10.10
@@ -31,9 +38,12 @@

 		update = ->

-			timestamp = getTime()
-			delta = (timestamp - _timestamp) / 1000
-			_timestamp = timestamp
+			if animationLoop.delta
+				delta = animationLoop.delta
+			else
+				timestamp = getTime()
+				delta = (timestamp - _timestamp) / 1000
+				_timestamp = timestamp

 			animationLoop.emit("update", delta)
 			animationLoop.emit("render", delta)


Quick fix for inserting new fact link when pressing enter.

--- core/app/backbone/views/facts/auto_complete_fact_relations_view.coffee
+++ core/app/backbone/views/facts/auto_complete_fact_relations_view.coffee
@@ -42,11 +42,14 @@
       fact_relation_authority: '1.0'

   addCurrent: ->
-    selected_result = @_search_list_view.currentActiveModel()
+    selected_fact_base = @_search_list_view.currentActiveModel()

+    if not selected_fact_base?
+      @addNew()
+      return
     @createFactRelation
-      evidence_id: selected_result.id
-      fact_base: selected_result.toJSON()
+      evidence_id: selected_fact_base.id
+      fact_base: selected_fact_base.toJSON()
       fact_relation_type: @collection.type
       created_by: currentUser.toJSON()
       fact_relation_authority: '1.0'


Fix issue #707 by adding Atom-based EOL detection

Determines the default line ending based upon the Atom configuration
`line-ending-selector.defaultLineEnding`. If the Atom configuration
indicates "OS Default", the `process.platform` is queried, returning
CRLF for Windows systems and LF for all other systems.

--- src/beautifiers/js-beautify.coffee
+++ src/beautifiers/js-beautify.coffee
@@ -24,6 +24,9 @@
   beautify: (text, language, options) ->
     @verbose("JS Beautify language #{language}")
     @info("JS Beautify Options: #{JSON.stringify(options, null, 4)}")
+    #TODO reconsider handling of EOL once js-beautify adds EOL detection
+    #see https://github.com/beautify-web/js-beautify/issues/899
+    options.eol = getDefaultLineEnding() ? options.eol #fixes issue #707
     return new @Promise((resolve, reject) =>
       try
         switch language
@@ -52,3 +55,23 @@
         reject(err)

     )
+
+  # Retrieves the default line ending based upon the Atom configuration
+  #  `line-ending-selector.defaultLineEnding`. If the Atom configuration
+  #  indicates "OS Default", the `process.platform` is queried, returning
+  #  CRLF for Windows systems and LF for all other systems.
+  # Code modified from atom/line-ending-selector
+  # returns: The correct line-ending character sequence based upon the Atom
+  #  configuration, or `null` if the Atom line ending configuration was not
+  #  recognized.
+  # see: https://github.com/atom/line-ending-selector/blob/master/lib/main.js
+  getDefaultLineEnding= ->
+    switch atom.config.get('line-ending-selector.defaultLineEnding')
+      when 'LF'
+        return '\n'
+      when 'CRLF'
+        return '\r\n'
+      when 'OS Default'
+        return if process.platform is 'win32' then '\r\n' else '\n'
+      else
+        return null


JS + JSON support

JS + JSON support

--- grammars/latex.cson
+++ grammars/latex.cson
@@ -1171,6 +1171,8 @@
     comment: 'This groups together all the minted languages supported by this grammar.'
     patterns: [
       { include: '#mintPython' }
+      { include: '#mintJavascript' }
+      { include: '#mintJSON' }
       { include: '#mintGeneric' }
     ]
   }
@@ -1258,6 +1260,90 @@
       5:
         name: 'punctuation.definition.arguments.end.latex'
     patterns: [{ include: 'source.python' }]
+  }
+  mintJavascript: {
+    name: 'meta.environment.embedded.js.latex'
+    contentName: 'source.embedded.js'
+    begin: '((\\\\)begin)(\\{)((minted)\\*?)(\\})(?:(\\[)(.*?)(\\]))?(\\{)(js)(\\})'
+    beginCaptures:
+      1:
+        name: 'support.function.environment.begin.latex'
+      2:
+        name: 'punctuation.definition.function.begin.latex'
+      3:
+        name: 'punctuation.definition.arguments.begin.latex'
+      4:
+        name: 'variable.parameter.environment.minted.latex'
+      # 5: Used for meta scope name (basically just non starred version)
+      6:
+        name: 'punctuation.definition.arguments.end.latex'
+      7:
+        name: 'punctuation.definition.arguments.optional.begin.latex'
+      8:
+        name: 'variable.parameter.optional.function.environment.latex'
+      9:
+        name: 'punctuation.definition.arguments.optional.end.latex'
+      10:
+        name: 'punctuation.definition.arguments.begin.latex'
+      11:
+        name: 'variable.parameter.language.js.latex'
+      12:
+        name: 'punctuation.definition.arguments.end.latex'
+    end: '((\\\\)end)(\\{)(minted)(\\})'
+    endCaptures:
+      1:
+        name: 'support.function.environment.end.latex'
+      2:
+        name: 'punctuation.definition.function.latex'
+      3:
+        name: 'punctuation.definition.arguments.begin.latex'
+      4:
+        name: 'variable.parameter.environment.latex'
+      5:
+        name: 'punctuation.definition.arguments.end.latex'
+    patterns: [{ include: 'source.js' }]
+  }
+  mintJSON: {
+    name: 'meta.environment.embedded.json.latex'
+    contentName: 'source.embedded.json'
+    begin: '((\\\\)begin)(\\{)((minted)\\*?)(\\})(?:(\\[)(.*?)(\\]))?(\\{)(json)(\\})'
+    beginCaptures:
+      1:
+        name: 'support.function.environment.begin.latex'
+      2:
+        name: 'punctuation.definition.function.begin.latex'
+      3:
+        name: 'punctuation.definition.arguments.begin.latex'
+      4:
+        name: 'variable.parameter.environment.minted.latex'
+      # 5: Used for meta scope name (basically just non starred version)
+      6:
+        name: 'punctuation.definition.arguments.end.latex'
+      7:
+        name: 'punctuation.definition.arguments.optional.begin.latex'
+      8:
+        name: 'variable.parameter.optional.function.environment.latex'
+      9:
+        name: 'punctuation.definition.arguments.optional.end.latex'
+      10:
+        name: 'punctuation.definition.arguments.begin.latex'
+      11:
+        name: 'variable.parameter.language.json.latex'
+      12:
+        name: 'punctuation.definition.arguments.end.latex'
+    end: '((\\\\)end)(\\{)(minted)(\\})'
+    endCaptures:
+      1:
+        name: 'support.function.environment.end.latex'
+      2:
+        name: 'punctuation.definition.function.latex'
+      3:
+        name: 'punctuation.definition.arguments.begin.latex'
+      4:
+        name: 'variable.parameter.environment.latex'
+      5:
+        name: 'punctuation.definition.arguments.end.latex'
+    patterns: [{ include: 'source.json' }]
   }


Don't test for 'change' since SetProxy doesn't forward it.

--- tests/batman/set/set_test.coffee
+++ tests/batman/set/set_test.coffee
@@ -60,7 +60,7 @@
     equal @set.length, 1

   test "addAndRemove only adds item to the set if no items to remove are passed", ->
-    @set.on 'itemsWereAdded', 'change', listen = createSpy()
+    @set.on 'itemsWereAdded', listen = createSpy()
     @set.on 'itemsWereRemoved', removeSpy = createSpy()

     itemsToAdd = [o1 = {}, o2 = {}, o3 = {}]
@@ -72,7 +72,7 @@
     ok @set.has(o1)
     ok @set.has(o2)
     ok @set.has(o3)
-    equal listen.callCount, 2
+    equal listen.callCount, 1
     ok !removeSpy.called

   test "addAndRemove only removes item to the set if no items to add are passed", ->
@@ -80,7 +80,7 @@
     @set.add(itemsToAdd...)

     @set.on 'itemsWereAdded', addSpy = createSpy()
-    @set.on 'itemsWereRemoved', 'change', listen = createSpy()
+    @set.on 'itemsWereRemoved', listen = createSpy()

     change = @set.addAndRemove([], [o1, o2])

@@ -90,7 +90,7 @@
     ok !@set.has(o1)
     ok !@set.has(o2)
     ok @set.has(o3)
-    equal listen.callCount, 2
+    equal listen.callCount, 1
     ok !addSpy.called

   test "addAndRemove cleans up event prevention", ->


Add missing resources segment

Add missing resources segment

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -112,7 +112,7 @@
 addCommandsToPath = (callback) ->
   installCommands = (callback) ->
     atomCommandPath = path.join(binFolder, 'atom.cmd')
-    relativeAtomPath = path.relative(binFolder, path.join(appFolder, 'cli', 'atom.cmd'))
+    relativeAtomPath = path.relative(binFolder, path.join(appFolder, 'resources', 'cli', 'atom.cmd'))
     atomCommand = """
       @echo off
       "%~dp0\\#{relativeAtomPath}" %*


Implementing uninstalling context menus

Implementing uninstalling context menus

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -5,6 +5,24 @@

 updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe')
 exeName = path.basename(process.execPath)
+
+# Registry keys used for context menu
+fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom'
+directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom'
+backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom'
+
+# Spawn reg.exe and callback when it completes
+spawnReg = (args, callback) ->
+  regProcess = ChildProcess.spawn('reg.exe', args)
+
+  error = null
+  regProcess.on 'error', (processError) -> error ?= processError
+  regProcess.on 'close', (code, signal) ->
+    error ?= new Error("Command failed: #{signal ? code}") if code isnt 0
+    error?.code ?= code
+    callback(error)
+
+  undefined

 # Spawn the Update.exe with the given arguments and invoke the callback when
 # the command completes.
@@ -29,32 +47,30 @@
   fs.existsSync(updateDotExe)

 installContextMenu = (callback) ->
-  fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom'
-  directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom'
-  backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom'
-
-  spawnReg = (args, callback) ->
+  addToRegistry = (args, callback) ->
     args.unshift('add')
-    regProcess = ChildProcess.spawn('reg.exe', args)
-
-    error = null
-    regProcess.on 'error', (processError) -> error ?= processError
-    regProcess.on 'close', (code, signal) ->
-      error ?= new Error("Command failed: #{signal ? code}") if code isnt 0
-      error?.code ?= code
-      callback(error)
+    args.push('/f')
+    spawnReg(args, callback)

   installMenu = (keyPath, callback) ->
-    args = [keyPath, '/ve', '/d', 'Open with Atom', '/f']
+    args = [keyPath, '/ve', '/d', 'Open with Atom']
     spawnReg args, ->
-      args = [keyPath, '/v', 'Icon', '/d', process.execPath, '/f']
+      args = [keyPath, '/v', 'Icon', '/d', process.execPath]
       spawnReg args, ->
-        args = ["#{keyPath}\\command", '/ve', '/d', process.execPath, '/f']
+        args = ["#{keyPath}\\command", '/ve', '/d', process.execPath]
         spawnReg(args, callback)

   installMenu fileKeyPath, ->
     installMenu directoryKeyPath, ->
       installMenu(backgroundKeyPath, callback)
+
+uninstallContextMenu = (callback) ->
+  deleteFromRegistry = (keyPath, callback) ->
+    spawnReg(['delete', keyPath, '/f'], callback)
+
+  deleteFromRegistry fileKeyPath, ->
+    deleteFromRegistry directoryKeyPath, ->
+      deleteFromRegistry(backgroundKeyPath, callback)

 # Handle squirrel events denoted by --squirrel-* command line arguments.
 exports.handleStartupEvent = ->
@@ -65,7 +81,9 @@
           app.quit()
       true
     when '--squirrel-uninstall'
-      exports.spawn ['--removeShortcut', exeName], -> app.quit()
+      exports.spawn ['--removeShortcut', exeName], ->
+        uninstallContextMenu ->
+          app.quit()
       true
     when '--squirrel-obsolete'
       app.quit()


Refactor graphStore state-setting

Refactor graphStore state-setting

This puts the state variables that GraphStore controls in a single place
(`getGraphState`), instead of repeating it in `updateListeners`,
`getInitialState` and `onGraphChanges`.

--- src/code/stores/graph-store.coffee
+++ src/code/stores/graph-store.coffee
@@ -386,17 +386,22 @@
   toJsonString: (palette) ->
     JSON.stringify @serialize palette

+  getGraphState: ->
+    nodes = @getNodes()
+    links = @getLinks()
+
+    {
+      nodes
+      links
+    }
+
   updateListeners: ->
-    data =
-      nodes: @getNodes()
-      links: @getLinks()
-    GraphActions.graphChanged.trigger(data)
+    GraphActions.graphChanged.trigger(@getGraphState())

 mixin =
   getInitialState: ->
-    nodes: GraphStore.getNodes()
-    links: GraphStore.getLinks()
+    GraphStore.getGraphState()

   componentDidMount: ->
     @unsubscribe = GraphActions.graphChanged.listen @onGraphChanged
@@ -404,10 +409,9 @@
   componentWillUnmount: ->
     @unsubscribe()

-  onGraphChanged: (status) ->
-    @setState
-      nodes: status.nodes
-      links: status.links
+  onGraphChanged: (state) ->
+    @setState state
+
     # TODO: not this:
     @diagramToolkit?.repaint()


Add compatibility for upcoming react support in minimap

--- lib/minimap-highlight-selected-view.coffee
+++ lib/minimap-highlight-selected-view.coffee
@@ -1,4 +1,4 @@
-{View, EditorView} = require 'atom'
+{View} = require 'atom'

 module.exports = ->
   highlightSelectedPackage = atom.packages.getLoadedPackage('highlight-selected')
@@ -39,5 +39,5 @@
         @detach()

     getMinimap: ->
-      if @editorView instanceof EditorView
+      if @editorView.hasClass('editor')
         return minimap.minimapForEditorView(@editorView)


Added hash fragment to loggedout homepage.

--- workers/social/lib/social/render/graphmeta.coffee
+++ workers/social/lib/social/render/graphmeta.coffee
@@ -12,6 +12,7 @@
   <meta name="description" content="Koding is a developer community and cloud development environment where developers come together and code in the browser – with a real development server to run their code. Developers can work, collaborate, write and run apps without jumping through hoops and spending unnecessary money.">
   <meta name="keywords" content="Online IDE, Collaborative IDE, Free VM, Browser-based terminal,free virtual machine, online compiler, Javascript, nodejs, golang, Python, ">
   <meta name="author" content="Koding">
+  <meta name="fragment" content="!">
   <meta property="og:site_name" content="Koding"/>
   <meta property="og:description" content="#{encoder.XSSEncode options.body}"/>
   <meta property="og:title" content="Koding - #{encoder.XSSEncode options.title}"/>


finished layout with namespace viewer object

--- bokeh/server/static/coffee/usercontext/usercontext.coffee
+++ bokeh/server/static/coffee/usercontext/usercontext.coffee
@@ -115,6 +115,7 @@
       resp = utility.load_doc(docid)

     resp.done((data) =>
+      @set('docid', data.docid)
       @set('apikey', data['apikey'])
       @set('plot_context', data['plot_context_ref'])
       @trigger('loaded')


add dispatcherCount to config file

add dispatcherCount to config file

--- services/document-updater/config/settings.defaults.coffee
+++ services/document-updater/config/settings.defaults.coffee
@@ -86,5 +86,7 @@

 	max_doc_length: 2 * 1024 * 1024 # 2mb

+	dispatcherCount: process.env["DISPATCHER_COUNT"]
+
 	mongo:
 		url: "mongodb://#{process.env["MONGO_HOST"] or "localhost"}/sharelatex"


initialize the range slider with min and max values of current group page items

--- app/assets/javascripts/components/group-page.cjsx
+++ app/assets/javascripts/components/group-page.cjsx
@@ -12,6 +12,7 @@
   getInitialState: ->
     all_institutions: []
     all_playwrights: []
+    all_years: []

   componentDidMount: ->
     # make a request to http://localhost:3000/subject_set_first_pages?group_id={{requested group id}}
@@ -20,11 +21,15 @@
     API.type("subject_set_first_pages").get(group_id: @props.params.group_id).then (first_pages_json) =>
       all_institutions = []
       all_playwrights = []
+      min_year = 9999
+      max_year = 0
+      min_max_year_array = []

       # iterate through the first pages and update the available institutions and playwright options
       for first_page_json in first_pages_json
         institution = first_page_json.meta_data.location
         playwright = first_page_json.meta_data.written_by
+        year = first_page_json.meta_data.year

         if institution
           if institution not in all_institutions
@@ -33,12 +38,23 @@
         if playwright
           if playwright not in all_playwrights
             all_playwrights.push(playwright)
+
+        if year
+          year_int = parseInt(year)
+          if year_int < min_year
+            min_year = year_int
+          if year_int > max_year
+            max_year = year_int
+
+      min_max_year_array = [min_year, max_year]
+      console.log(min_max_year_array)

       @setState
         all_first_pages: first_pages_json
         all_institutions: all_institutions
         all_playwrights: all_playwrights
-        first_pages_initialized: 0
+        min_year: min_year
+        max_year: max_year

       @initializeFirstPageArray()

@@ -58,7 +74,6 @@
       first_pages_view.push <FirstPageThumbnail page_json={page_json} key={index} />
     @setState
       first_page_array: first_pages_view
-      first_pages_initialized: 1

   updateFirstPageArray: ->
@@ -132,8 +147,17 @@

?

+
+

+
{@state.min_year}

+
{@state.max_year}

+

+

-                  <ReactSlider defaultValue={[0, 100]} withBars />
+
+                  <ReactSlider min={@state.min_year}
+                      max={@state.max_year}
+                      defaultValue={[@state.min_year, @state.max_year]} withBars />


Disable Pjax timeout

Disable Pjax timeout

--- app/assets/javascripts/nembrot.document.js.coffee
+++ app/assets/javascripts/nembrot.document.js.coffee
@@ -1,6 +1,8 @@
 jQuery.fn.reverse = [].reverse

 page_initializers = () ->
+  # Implementing a spinner may be a better idea: https://github.com/defunkt/jquery-pjax/issues/129
+  $.pjax.defaults.timeout = false
   $(document).pjax('a:not([data-remote]):not([data-behavior]):not([data-skip-pjax])', '[data-pjax-container]')

 content_initializers = () ->


conversations: fix recipient search pagination

fixes CNVS-10209

test plan:
  * open old conversations
  * in the recipient search, select a course with more than ten people
  * scroll to the bottom
  * confirm that all of the people in the course are present

Regression appears to have been introduced in
https://gerrit.instructure.com/26489 .

Change-Id: Ie2bb7cf3d6c348ae753fc245d719dfb081948ea2
Reviewed-on: https://gerrit.instructure.com/28016
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Zach Pendleton <514dbb4d54d4f29e454990df7d075678f43f92aa@instructure.com>
Product-Review: Zach Pendleton <514dbb4d54d4f29e454990df7d075678f43f92aa@instructure.com>
QA-Review: Steven Shepherd <e794458448443812fb2685675aab3bbd1a3891bc@instructure.com>

--- app/coffeescripts/widget/TokenSelectorList.coffee
+++ app/coffeescripts/widget/TokenSelectorList.coffee
@@ -49,6 +49,7 @@
       91: 'Command'

     initialize: (options) ->
+      @paginationScrollContainer = $('<ul />', role: 'menu')
       super
       @selector = @options.selector
       @parent = @options.parent
@@ -56,7 +57,6 @@
       @query = @options.query

       @$heading                  = $('<ul />', class: 'heading').appendTo(@$el)
-      @paginationScrollContainer = $('<ul />', role: 'menu')
       @$body                     = @paginationScrollContainer.appendTo(@$el)

       @$el.find('ul')


make it possible to override existing command handlers

--- source/infrastructure/command_bus.coffee
+++ source/infrastructure/command_bus.coffee
@@ -24,10 +24,12 @@
     else
       @_handleCommand command

-  registerHandler: (typeName, handler) ->
-    if @_handlers[typeName]?
+  registerHandler: (typeName, handler, overrideExisting) ->
+    if @_handlers[typeName]? and !overrideExisting
       throw new Error "There is already an handler for #{typeName} commands."
     @_handlers[typeName] = handler
+
+  overrideHandler: (typeName, handler) -> @registerHandler typeName, handler, true

   _handleCommand: (command, data) =>
     handler = @_handlers[command.typeName()]


copy previous name before swap nodes when upload file

--- source/javascripts/dante/dante.js.coffee
+++ source/javascripts/dante/dante.js.coffee
@@ -1032,7 +1032,7 @@

   insertTemplate: ()->
     "

-

+

@@ -1071,7 +1071,7 @@
     $(@el).show()

   toggleOptions: ()=>
-    utils.log "OLI!!"
+    utils.log "Toggle Options!!"
     $(@el).toggleClass("is-active is-scaled")

   move: (coords)->
@@ -1132,7 +1132,9 @@

   displayCachedImage: (file)->
     @node = current_editor.getNode()
-    replaced_node = $(@node).replaceWith(@insertTemplate())
+    #copy previous name before swap nodes
+    new_node = $(@insertTemplate()).attr("name", $(this.node).attr("name") )
+    replaced_node = $(@node).replaceWith( new_node )

     current_editor.tooltip_view.hide()
     reader = new FileReader()


put shabbat vatikin schedule on screen version of weekly schedule

--- source/javascripts/index/schedule.coffee
+++ source/javascripts/index/schedule.coffee
@@ -12,12 +12,13 @@

 shaharit_is_fixed_at = (day, hour, minute, hebrewDate, gregorianDate) ->
   time = moment().hour(hour).minute(minute)
-  vatikin = new Vatikin(gregorianDate, hebrewDate).schedule
-  vatikin = vatikin.korbanot + vatikin.hodu + vatikin.yishtabach
-  $(".#{day} .korbanot").html("#{time.format("h:mm")} and
#{vatikin} minutes
before sunrise")
-  $(".#{day} .hodu").html(time.add(15, 'minutes').format("h:mm"))
+  vatikin = new Vatikin(gregorianDate, hebrewDate)
+  earlyMinyanHodu = moment(vatikin.sunrise).subtract(vatikin.schedule.hodu + vatikin.schedule.yishtabach, 'minutes').format("h:mm")
+  earlyMinyanKorbanot = moment(vatikin.sunrise).subtract(vatikin.schedule.korbanot + vatikin.schedule.hodu + vatikin.schedule.yishtabach, 'minutes').format("h:mm")
+  $(".#{day} .korbanot").html("#{earlyMinyanKorbanot} and #{time.format("h:mm")}")
+  $(".#{day} .hodu").html("#{earlyMinyanHodu} and #{time.add(15, 'minutes').format("h:mm")}")
   $(".#{day} .yishtabach").html('')
-  $(".#{day} .amidah").html('')
+  $(".#{day} .amidah").html("#{vatikin.sunrise.format("h:mm:ss")}")

 write_schedule = (day_iterator) ->
   $('.start-hidden').addClass('hidden')


remove an indentation level

remove an indentation level

--- src/kite-server/kite-server.coffee
+++ src/kite-server/kite-server.coffee
@@ -39,36 +39,36 @@
     @server.on 'connection', @bound 'onConnection'
     @emit 'info', "Listening: #{ @server.options.host }:#{ @server.options.port }"

-  register: ({ to: kontrolUri, host, kiteKey }) ->
+  register: ({ to: u, host: h, kiteKey: k }) ->
     throw new Error "Already registered!"  if @kontrol?
-    kontrolUriP = Promise.cast kontrolUri
-    hostP       = Promise.cast host
-    kiteKeyP    = @normalizeKiteKey kiteKey
-    Promise.all [kontrolUriP, hostP, kiteKeyP]
-      .spread (kontrolUri, host, key) =>
-        { name, username, environment, version, region, hostname, logLevel } = @options
+    Promise.all([
+      Promise.cast u
+      Promise.cast h
+      @normalizeKiteKey k
+    ]).spread (kontrolUri, host, key) =>
+      { name, username, environment, version, region, hostname, logLevel } = @options

-        throw new Error "No kite key!"  unless key?
+      throw new Error "No kite key!"  unless key?

-        @key = key
+      @key = key

-        @kontrol = new Kontrol
-          url         : kontrolUri
-          auth        : { type: 'kiteKey', key }
-          name        : name
-          username    : username
-          environment : environment
-          version     : version
-          region      : region
-          hostname    : hostname
-          logLevel    : logLevel
-        .on 'connected', =>
-          @emit 'info', "Connected to Kontrol"
+      @kontrol = new Kontrol
+        url         : kontrolUri
+        auth        : { type: 'kiteKey', key }
+        name        : name
+        username    : username
+        environment : environment
+        version     : version
+        region      : region
+        hostname    : hostname
+        logLevel    : logLevel
+      .on 'connected', =>
+        @emit 'info', "Connected to Kontrol"

-        kiteUri = "ws://#{ host }:#{ @port }/#{ @options.name }"
+      kiteUri = "ws://#{ host }:#{ @port }/#{ @options.name }"

-        @kontrol.register(url: kiteUri).then =>
-          @emit 'info', "Registered to Kontrol with URL: #{ kiteUri }"
+      @kontrol.register(url: kiteUri).then =>
+        @emit 'info', "Registered to Kontrol with URL: #{ kiteUri }"

   normalizeKiteKey: Promise.method (src, enc = "utf-8") -> switch
     when 'string' is typeof src


HistoryManager: Fixed page reloading on Firefox.

Returns a input element to give goog's History class. This prevents Firefox
    to reload the page. Also Firefox was throwing a security error on localhost
    when HistoryManager constructed. So this trick will also fix that issue too.

--- src/lib/core/HistoryManager.coffee
+++ src/lib/core/HistoryManager.coffee
@@ -2,6 +2,7 @@
 goog.provide 'spark.core.HistoryManager.TokenTransformer'

 goog.require 'spark.core.Object'
+goog.require 'spark.components.Input'
 goog.require 'goog.History'
 goog.require 'goog.history.Html5History'

@@ -41,7 +42,7 @@
       @history.setPathPrefix  options.pathPrefix
       @history.setUseFragment no
     else
-      @history = new goog.History()
+      @history = new goog.History null, null, @getHistoryInput_()

     goog.events.listen @history, goog.history.EventType.NAVIGATE, (e) =>
       @emit 'Navigated', e.token
@@ -58,6 +59,16 @@
   setToken: (token) ->
     @history.setToken token

+
+  ###*
+    Returns a input element to give goog's History class. This prevents Firefox
+    to reload the page. Also Firefox was throwing a security error on localhost
+    when HistoryManager constructed. So this trick will also fix that issue too.
+
+    @private
+  ###
+  getHistoryInput_: ->
+    return new spark.components.Input().getElement()

 ###*


simpler plugin structure

simpler plugin structure

--- src/dt-jquery.coffee
+++ src/dt-jquery.coffee
@@ -33,15 +33,14 @@
         @animation = new Animation(opts)
         @animation.start()
         # init jquery functions
-        [@fn, fns] = [{}, []]
-        if isArray opts.fn
-            fns = fns.concat(opts.fn)
-        else fns.push(opts.fn ? {})
-        fns.push(defaultfn)
-        for fn in fns
-            for n,f of fn
-                @fn[n] ?= f.bind(this) if typeof f is 'function'
+        @fn = {}
+        for n,f of defaultfn
+            @fn[n] ?= f.bind(this)
         @initialize()
+        # allow plugins as options
+        opts.use ?= []
+        opts.use = [opts.use] unless isArray opts.use
+        @use(plugin) for plugin in opts.use

     initialize: () ->
         do @listen
@@ -83,6 +82,10 @@
                 tag._jquery_ready = ->
                     next(tag)

+    use: (plugin) ->
+        plugin?.call(this, this)
+        return this
+
     listen: () ->
         EVENTS.forEach (event) =>
             @template.on(event, this["on#{event}"].bind(this))


Display stack machine list regardless of hid machine boxes

--- client/app/lib/activity/sidebar/sidebarmachinelist.coffee
+++ client/app/lib/activity/sidebar/sidebarmachinelist.coffee
@@ -18,14 +18,11 @@

     super options, data

-    @hide()
-
     @machineBoxes = []
     @machineBoxesByMachineUId = {}

     @createHeader()
     @addMachineBoxes()
-    @updateVisibility()

   createHeader: ->
@@ -54,8 +51,6 @@
     data = boxes or @getData()
     data.forEach @bound 'addMachineBox'

-    @updateVisibility()
-

   addMachineBox: (machineAndWorkspaceData) ->

@@ -65,7 +60,6 @@

     box = new SidebarMachineBox {}, machineAndWorkspaceData

-    box.on 'SetVisibility', @bound 'updateVisibility'
     box.once 'KDObjectWillBeDestroyed', @lazyBound 'handleMachineBoxDestroy', box

     @forwardEvent box, 'ListStateChanged'


Added user is logged in check before fetching intro snippets.

--- client/landing/app/CommonViews/introductiontooltip.coffee
+++ client/landing/app/CommonViews/introductiontooltip.coffee
@@ -38,6 +38,7 @@
       @init()

   init: ->
+    return unless KD.whoami() instanceof KD.remote.api.JAccount
     KD.remote.api.JIntroSnippet.fetchAll (err, snippets) =>
       return log err if err # TODO: error handling


Workspace: Added getActivePanelMethod to workspace.

--- client/landing/app/CommonViews/workspace/workspace.coffee
+++ client/landing/app/CommonViews/workspace/workspace.coffee
@@ -36,6 +36,9 @@

   prev: ->

+  getActivePanel: ->
+    return @panels[@lastCreatedPanelIndex]
+
   _windowDidResize: ->
     return unless @activePanel
     pane.emit "PaneResized" for pane in @activePanel.panes


Pricing: fixed learn more link href

Pricing: fixed learn more link href

--- client/landing/site.landing/coffee/pricing/AppView.coffee
+++ client/landing/site.landing/coffee/pricing/AppView.coffee
@@ -100,8 +100,8 @@

     footer.addSubView new CustomLinkView
       title    : 'Learn more about all our features'
-      cssClass : "learn-more"
-      href     : "/"
+      cssClass : 'learn-more'
+      href     : '/Features'

     footer.addSubView new KDCustomHTMLView
       cssClass : 'footer-msg'


Use "widget-type" syntax for class names.

--- vendor/javascripts/widget.coffee
+++ vendor/javascripts/widget.coffee
@@ -8,7 +8,7 @@
     @mixin(AllTheThings.lastEvents[@id]) # in case the events from the server came before the widget was rendered

     type = Batman.Filters.underscore(@view)
-    $(@node).addClass("widget #{type} #{@id}")
+    $(@node).addClass("widget widget-#{type} #{@id}")

   onData: (data) =>
     @mixin(data)


replace wrapping if by guard

replace wrapping if by guard

--- core/app/backbone/views/wheel/base_fact_wheel_view.coffee
+++ core/app/backbone/views/wheel/base_fact_wheel_view.coffee
@@ -169,16 +169,17 @@
   clickOpinionType: ->

   bindTooltips: ->
-    if @options.showsTooltips
-      @$("div.tooltip").remove()
-      @$(".authority").tooltip title: "This number represents the amount of thinking " + "spent by people on this Factlink"
+    return unless @options.showsTooltips

-      # Create tooltips for each opinionType (believe, disbelieve etc)
-      for key, opinionType of @model.get('opinion_types')
-        raphaelObject = @opinionTypeRaphaels[opinionType.type]
-        $(raphaelObject.node).tooltip
-          title: @options.opinionStyles[opinionType.type].groupname + ": " + opinionType.percentage + "%"
-          placement: "left"
+    @$("div.tooltip").remove()
+    @$(".authority").tooltip title: "This number represents the amount of thinking " + "spent by people on this Factlink"
+
+    # Create tooltips for each opinionType (believe, disbelieve etc)
+    for key, opinionType of @model.get('opinion_types')
+      raphaelObject = @opinionTypeRaphaels[opinionType.type]
+      $(raphaelObject.node).tooltip
+        title: @options.opinionStyles[opinionType.type].groupname + ": " + opinionType.percentage + "%"
+        placement: "left"

   updateTo: (authority, opinionTypes) ->
     @model.set "authority", authority


Bongo: invokeMethod: fix all the unhandled calls issues

This is very annoying that I just realised all the calls drops here if
there is an error in the invoker. For example, if you make an instance
call on a non-existent instance it never calls the callback. Or if you
try to call a non-existent method over any Bongo.model this never calls
the callback as well. It was valid for lots of other cases as well in
this commit.

With this commit we will call the provided callback with a proper error
instead. which I assume will fix the remaining memory issues on Bongo.

--- node_modules_koding/bongo/lib/bongo.coffee
+++ node_modules_koding/bongo/lib/bongo.coffee
@@ -471,9 +471,11 @@
     @description - apply the method, conditionally currying the "client" object
     ###
     apply = (bongo, ctx, method, args, sessionToken, userArea, client) ->
+
       unless ctx?
-        bongo.handleUserError "bad instance! #{method}"
+        bongo.handleUserError "Bad instance! #{method}", args
         return
+
       if 'function' is typeof method
         fn = method
       else if ctx? and 'string' is typeof method
@@ -482,9 +484,11 @@
         # a given model, and provides a wrapper for it; otherwise, search for
         # the method with the exact name.
         fn = ctx["#{method}$"] ? ctx[method]
+
       unless fn?
-        bongo.handleUserError "unknown method! #{method}"
+        bongo.handleUserError "Unknown method! #{method}", args
         return
+
       if fn.isSecurityEnabled
         if client
           args = [client].concat args
@@ -495,12 +499,13 @@
             fn.apply ctx, args
       else
         fn.apply ctx, args
+
     ###
     @implementation
     ###
     (method, args, userArea, sessionToken, secretName, client)->
       unless method?
-        @handleUserError 'No such method'
+        @handleUserError 'No such method', args
       else if method is 'ping' then @pong args[0]
       else if method is 'monitorPresence' then @monitorPresence args[0]
       else if method is 'authenticateUser' then @authenticateUser args... # TODO: this doesn't need to be specialcase. C.T.
@@ -508,12 +513,15 @@
       else if method?.method
         konstructor = Base.constructors[method.constructorName]
         unless konstructor?
-          console.warn "No such constructor! #{method.constructorName}"
+          @handleUserError "No such constructor! #{method.constructorName}", args
           return

-        validCall = konstructor.testSignature method.type, method.method, args
+        [validCall, signatures] = konstructor.testSignature \
+          method.type, method.method, args
+
         unless validCall
-          console.warn "unrecognized signature:", method, args
+          signatures = " Possible signatures are #{JSON.stringify signatures}"
+          @handleUserError "Unrecognized signature for #{konstructor.name}.#{method.method}#{signatures ? ''}", args
           return

         switch method.type
@@ -521,35 +529,53 @@
             if konstructor.hasSharedMethod method.method
               apply this, konstructor, method.method, args, sessionToken, userArea, client
             else
-              @handleUserError "No such method! #{JSON.stringify method} #{args} #{secretName}"
+              @handleUserError "No such method! #{JSON.stringify method}", args
+
           when 'instance'
             if konstructor::hasSharedMethod method.method
+
               if method.id
-                konstructor.one? _id: method.id, (err, instance)=>
+
+                unless konstructor.one?
+                  @handleUserError "Constructor #{konstructor.name} has no instance getter!", args
+                  return
+
+                konstructor.one? _id: method.id, (err, instance) =>
                   if err
-                    @handleUserError err
+                    @handleUserError err, args
                   else unless instance
-                    console.warn "#{konstructor.name} instance with id #{method.id} is not found"
-                    return
+                    @handleUserError "#{konstructor.name} instance with id #{method.id} is not found", args
                   else
                     apply this, instance, method.method, args, sessionToken, userArea, client
+
               else if method.data
                 instance = new konstructor method.data
                 apply this, instance, method.method, args, sessionToken, userArea, client
+
             else
-              @handleUserError "No such method! #{JSON.stringify method} #{args} #{secretName}"
+              @handleUserError "No such method! #{JSON.stringify method}", args
+
           else
-            @handleUserError 'Unknown method type!'
+            @handleUserError 'Unknown method type!', args
+
       else
-        kallback = @localStore.get method
-        if kallback?
+        if (kallback = @localStore.get method)?
           apply this, null, kallback, args, sessionToken, userArea, client
         else
-          @handleUserError 'Unknown method type!'
-
-  handleUserError:(message)->
-    console.warn message
+          @handleUserError 'Unknown method type!', args
+
+
+  handleUserError: (message, args) ->
+
+    console.warn '[Bongo:UserError]', message, args
+
+    if (Array.isArray args) and args.length > 0
+      callback = args[args.length - 1]
+      if 'function' is typeof callback
+        callback { message }
+
     @emit 'userError', message
+

   detectErrFirst:(cursor)->
     if cursor.path.length is 1 and


remove unnecessary render thing

remove unnecessary render thing

--- SingularityUI/app/views/taskOverviewSubview.coffee
+++ SingularityUI/app/views/taskOverviewSubview.coffee
@@ -41,7 +41,6 @@
     renderData: ->
         config:         config
         data:           @model.toJSON()
-        healthCheck:    @model.get('healthcheckResults')[0]
         synced:         @model.synced and @collection.synced


line renderer should also perform do_stroke check

--- subtree/bokehjs/static/coffee/renderers/glyph/line.coffee
+++ subtree/bokehjs/static/coffee/renderers/glyph/line.coffee
@@ -45,6 +45,8 @@
     [@sx, @sy] = @plot_view.map_to_screen(@x, @glyph_props.x.units, @y, @glyph_props.y.units)

   _render: () ->
+    if not @do_stroke
+      return
     @_map_data()
     ctx = @plot_view.ctx
     ctx.save()


reverting end on error

reverting end on error

--- lib/Pontifex.coffee
+++ lib/Pontifex.coffee
@@ -30,8 +30,6 @@
 			vhost: domain || '/'
 		self.connection.on 'error', (Message) ->
 			console.log "Connection error", Message
-			self.connection.end()
-			self.connect(domain,setup)
 		self.connection.on 'end', () ->
 			console.log "Connection closed"
 			self.connect(domain,setup)


sort axis tick numbers in numeric order

sort axis tick numbers in numeric order

Array.sort sorts in alphabetical order by default, and the visual
gets corrupted. This happens with values like
[0,1,2,3,4,5,6,7,8,9,10,11].sort()

--- src/viz/types/helpers/graph/includes/axes.coffee
+++ src/viz/types/helpers/graph/includes/axes.coffee
@@ -180,7 +180,7 @@
         , []
         counts
       else
-        uniques(values).sort()
+        uniques(values).sort((a,b) -> a-b)
     else
       values.sort (a, b) -> a - b
       if vars[axis].scale.value is "log"


Added a reset so we can continue chatting


Update compiler.coffee

Update compiler.coffee

--- lib/compiler.coffee
+++ lib/compiler.coffee
@@ -370,7 +370,7 @@
     file_options    = @file.file_options
     compile_options = @file.compile_options

-    _.extend(global_options, adapter_options, file_options, compile_options)
+    _.extend({}, global_options, adapter_options, file_options, compile_options)

   ###*
    * As small of a function as this is, it's the one that actually is doing


yeah yeah

yeah yeah

--- lib/eslogger.coffee
+++ lib/eslogger.coffee
@@ -258,7 +258,7 @@
     stop_date = stop.format('HH:mm')
     diffdays = moment().utc().diff(stop, 'days')
     content = @html_head(room)
-    nav = " - Day before"
+    nav = " - Day before"
     if diffdays isnt 0
       nav += " - Day after"
     content += """


Implement in requests table view

Implement in requests table view

--- SingularityUI/app/views/requests.coffee
+++ SingularityUI/app/views/requests.coffee
@@ -121,45 +121,21 @@
     removeRequest: (e) ->
         $row = $(e.target).parents('tr')
         requestModel = @collection.get($(e.target).data('request-id'))
-
-        if $(e.target).data('action-remove-type') is 'deletePaused'
-            vex.dialog.confirm
-                message: "
Are you sure you want to delete the paused request?

#{ requestModel.get('id') }
"
-                callback: (confirmed) =>
-                    return unless confirmed
-                    $row.remove()
-                    requestModel.deletePaused().done =>
-                        delete app.allRequests[requestModel.get('id')]
-                        @collection.remove(requestModel)
-
-        else
-            vex.dialog.confirm
-                message: @removeRequestTemplate(requestId: requestModel.get('id'))
-                buttons: [
-                    $.extend({}, vex.dialog.buttons.YES, (text: 'Remove', className: 'vex-dialog-button-primary vex-dialog-button-primary-remove'))
-                    vex.dialog.buttons.NO
-                ]
-                callback: (confirmed) =>
-                    return unless confirmed
-                    requestModel.destroy()
-                    delete app.allRequests[requestModel.get('id')] # TODO - move to model on destroy?
-                    @collection.remove(requestModel)
-                    $row.remove()
+        requestModel.promptRemove =>
+            $row.remove()

     unpauseRequest: (e) ->
         $row = $(e.target).parents('tr')
         requestModel = @collection.get($(e.target).data('request-id'))
+        requestModel.promptUnpause =>
+            @refresh()

-        vex.dialog.confirm
-            message: "
Are you sure you want to unpause the request?

#{ requestModel.get('id') }
"
-            callback: (confirmed) =>
-                return unless confirmed
-
-                if @requestsFilter is "paused"
-                    $row.remove()
-
-                requestModel.unpause().done =>
-                    @refresh()
+    runRequest: (e) ->
+        $row = $(e.target).parents 'tr'
+
+        requestModel = new Request id: $(e.target).data('request-id')
+        requestModel.promptRun =>
+            utils.flashRow $row

     toggleStar: (e) ->
         $target = $(e.target)
@@ -175,29 +151,6 @@
             $requests.each -> $(@).attr('data-starred', 'false')
         else
             $requests.each -> $(@).attr('data-starred', 'true')
-
-    runRequest: (e) ->
-        requestModel = new Request id: $(e.target).data('request-id')
-        $row = $(e.target).parents 'tr'
-
-        requestType = $(e.target).data 'request-type'
-
-        dialogOptions =
-            message: "
Are you sure you want to run a task for this #{ requestType } request immediately?

#{ requestModel.get('id') }
"
-            buttons: [
-                $.extend({}, vex.dialog.buttons.YES, text: 'Run now')
-                vex.dialog.buttons.NO
-            ]
-            callback: (confirmedOrPromptData) =>
-                return if confirmedOrPromptData is false
-
-                requestModel.run(confirmedOrPromptData)
-                utils.flashRow $row
-
-        dialogType = vex.dialog.prompt
-        dialogOptions.message += '
Additional command line input (optional):
'
-
-        dialogType dialogOptions

     changeFilters: (e) ->
         e.preventDefault()


Inserted missing spaces into ‘splitPane’ options in ‘git-plus.coffee’.

--- lib/git-plus.coffee
+++ lib/git-plus.coffee
@@ -46,10 +46,10 @@
       default: true
       description: 'Allow commands to open new panes'
     splitPane:
-      title: 'Split pane direction(up, right, down, or left)'
+      title: 'Split pane direction (up, right, down, or left)'
       type: 'string'
       default: 'right'
-      description: 'Where should new panes go?(Defaults to right)'
+      description: 'Where should new panes go? (Defaults to right)'
     wordDiff:
       type: 'boolean'
       default: true