Fix specs for use of setImmediate instead of nextTick in requestUpdate

--- spec/editor-component-spec.coffee
+++ spec/editor-component-spec.coffee
@@ -7,7 +7,7 @@

 describe "EditorComponent", ->
   [contentNode, editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = []
-  [lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame, nextTick, lineOverdrawMargin] = []
+  [lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame, runSetImmediateCallbacks, lineOverdrawMargin] = []

   beforeEach ->
     lineOverdrawMargin = 2
@@ -32,16 +32,16 @@
       atom.project.open('sample.js').then (o) -> editor = o

     runs ->
-      nextTickFns = []
-      nextTick = ->
-        if nextTickFns.length is 0
-          throw new Error("nextTick not requested")
+      setImmediateFns = []
+      runSetImmediateCallbacks = ->
+        if setImmediateFns.length is 0
+          throw new Error("runSetImmediateCallbacks not requested")
         else
-          fns = nextTickFns.slice()
-          nextTickFns.length = 0
+          fns = setImmediateFns.slice()
+          setImmediateFns.length = 0
           fn() for fn in fns

-      spyOn(process, 'nextTick').andCallFake (fn) -> nextTickFns.push(fn)
+      spyOn(window, 'setImmediate').andCallFake (fn) -> setImmediateFns.push(fn)

       contentNode = document.querySelector('#jasmine-content')
       contentNode.style.width = '1000px'
@@ -63,7 +63,7 @@
       node.style.height = editor.getLineCount() * lineHeightInPixels + 'px'
       node.style.width = '1000px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

   afterEach ->
     contentNode.style.width = ''
@@ -72,7 +72,7 @@
     it "renders the currently-visible lines plus the overdraw margin", ->
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       linesNode = node.querySelector('.lines')
       expect(linesNode.style['-webkit-transform']).toBe "translate3d(0px, 0px, 0px)"
@@ -84,6 +84,7 @@

       verticalScrollbarNode.scrollTop = 4.5 * lineHeightInPixels
       verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
+      runSetImmediateCallbacks()

       expect(linesNode.style['-webkit-transform']).toBe "translate3d(0px, #{-4.5 * lineHeightInPixels}px, 0px)"
       expect(node.querySelectorAll('.line').length).toBe 6 + 4 # margin above and below
@@ -94,7 +95,7 @@

     it "updates the top position of subsequent lines when lines are inserted or removed", ->
       editor.getBuffer().deleteRows(0, 1)
-      nextTick()
+      runSetImmediateCallbacks()

       lineNodes = node.querySelectorAll('.line')
       expect(component.lineNodeForScreenRow(0).offsetTop).toBe 0
@@ -102,7 +103,7 @@
       expect(component.lineNodeForScreenRow(2).offsetTop).toBe 2 * lineHeightInPixels

       editor.getBuffer().insert([0, 0], '\n\n')
-      nextTick()
+      runSetImmediateCallbacks()

       lineNodes = node.querySelectorAll('.line')
       expect(component.lineNodeForScreenRow(0).offsetTop).toBe 0 * lineHeightInPixels
@@ -114,7 +115,7 @@
     it "updates the top position of lines when the line height changes", ->
       initialLineHeightInPixels = editor.getLineHeightInPixels()
       component.setLineHeight(2)
-      nextTick()
+      runSetImmediateCallbacks()

       newLineHeightInPixels = editor.getLineHeightInPixels()
       expect(newLineHeightInPixels).not.toBe initialLineHeightInPixels
@@ -123,7 +124,7 @@
     it "updates the top position of lines when the font size changes", ->
       initialLineHeightInPixels = editor.getLineHeightInPixels()
       component.setFontSize(10)
-      nextTick()
+      runSetImmediateCallbacks()

       newLineHeightInPixels = editor.getLineHeightInPixels()
       expect(newLineHeightInPixels).not.toBe initialLineHeightInPixels
@@ -136,7 +137,7 @@

       initialLineHeightInPixels = editor.getLineHeightInPixels()
       component.setFontFamily('sans-serif')
-      nextTick()
+      runSetImmediateCallbacks()

       expect(linesComponent.measureLineHeightAndDefaultCharWidth).toHaveBeenCalled()
       newLineHeightInPixels = editor.getLineHeightInPixels()
@@ -147,7 +148,7 @@
       editor.setText('')
       node.style.height = '300px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       linesNode = node.querySelector('.lines')
       expect(linesNode.offsetHeight).toBe 300
@@ -167,7 +168,7 @@

       it "re-renders the lines when the showInvisibles config option changes", ->
         editor.setText " a line with tabs\tand spaces "
-        nextTick()
+        runSetImmediateCallbacks()
         expect(component.lineNodeForScreenRow(0).textContent).toBe "#{invisibles.space}a line with tabs#{invisibles.tab}and spaces#{invisibles.space}#{invisibles.eol}"

         atom.config.set("editor.showInvisibles", false)
@@ -178,27 +179,27 @@

       it "displays spaces, tabs, and newlines as visible characters", ->
         editor.setText " a line with tabs\tand spaces "
-        nextTick()
+        runSetImmediateCallbacks()
         expect(component.lineNodeForScreenRow(0).textContent).toBe "#{invisibles.space}a line with tabs#{invisibles.tab}and spaces#{invisibles.space}#{invisibles.eol}"

       it "displays newlines as their own token outside of the other tokens' scopes", ->
         editor.setText "var"
-        nextTick()
+        runSetImmediateCallbacks()
         expect(component.lineNodeForScreenRow(0).innerHTML).toBe "var#{invisibles.eol}"

       it "displays trailing carriage returns using a visible, non-empty value", ->
         editor.setText "a line that ends with a carriage return\r\n"
-        nextTick()
+        runSetImmediateCallbacks()
         expect(component.lineNodeForScreenRow(0).textContent).toBe "a line that ends with a carriage return#{invisibles.cr}#{invisibles.eol}"

       describe "when soft wrapping is enabled", ->
         beforeEach ->
           editor.setText "a line that wraps "
           editor.setSoftWrap(true)
-          nextTick()
+          runSetImmediateCallbacks()
           node.style.width = 16 * charWidth + 'px'
           component.measureScrollView()
-          nextTick()
+          runSetImmediateCallbacks()

         it "doesn't show end of line invisibles at the end of wrapped lines", ->
           expect(component.lineNodeForScreenRow(0).textContent).toBe "a line that "
@@ -207,7 +208,7 @@
     describe "when indent guides are enabled", ->
       beforeEach ->
         component.setShowIndentGuide(true)
-        nextTick()
+        runSetImmediateCallbacks()

       it "adds an 'indent-guide' class to spans comprising the leading whitespace", ->
         line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
@@ -224,7 +225,7 @@

       it "renders leading whitespace spans with the 'indent-guide' class for empty lines", ->
         editor.getBuffer().insert([1, Infinity], '\n')
-        nextTick()
+        runSetImmediateCallbacks()

         line2LeafNodes = getLeafNodes(component.lineNodeForScreenRow(2))

@@ -238,7 +239,7 @@

       it "renders indent guides correctly on lines containing only whitespace", ->
         editor.getBuffer().insert([1, Infinity], '\n      ')
-        nextTick()
+        runSetImmediateCallbacks()

         line2LeafNodes = getLeafNodes(component.lineNodeForScreenRow(2))
         expect(line2LeafNodes.length).toBe 3
@@ -251,7 +252,7 @@

       it "does not render indent guides in trailing whitespace for lines containing non whitespace characters", ->
         editor.getBuffer().setText "  hi  "
-        nextTick()
+        runSetImmediateCallbacks()

         line0LeafNodes = getLeafNodes(component.lineNodeForScreenRow(0))
         expect(line0LeafNodes[0].textContent).toBe '  '
@@ -268,7 +269,7 @@
     describe "when the buffer contains null bytes", ->
       it "excludes the null byte from character measurement", ->
         editor.setText("a\0b")
-        nextTick()
+        runSetImmediateCallbacks()
         expect(editor.pixelPositionForScreenPosition([0, Infinity]).left).toEqual 2 * charWidth

     describe "when there is a fold", ->
@@ -277,12 +278,12 @@
         expect(foldedLineNode.querySelector('.fold-marker')).toBeFalsy()

         editor.foldBufferRow(4)
-        nextTick()
+        runSetImmediateCallbacks()
         foldedLineNode = component.lineNodeForScreenRow(4)
         expect(foldedLineNode.querySelector('.fold-marker')).toBeTruthy()

         editor.unfoldBufferRow(4)
-        nextTick()
+        runSetImmediateCallbacks()
         foldedLineNode = component.lineNodeForScreenRow(4)
         expect(foldedLineNode.querySelector('.fold-marker')).toBeFalsy()

@@ -296,12 +297,12 @@
         marker = editor.displayBuffer.markBufferRange([[2, 13], [3, 15]], invalidate: 'inside')
         decoration = {type: 'line', class: 'someclass'}
         editor.addDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()

       it "does not render off-screen lines with line number classes until they are with in the rendered row range", ->
         node.style.height = 4.5 * lineHeightInPixels + 'px'
         component.measureScrollView()
-        nextTick()
+        runSetImmediateCallbacks()

         expect(component.lineNodeForScreenRow(9)).not.toBeDefined()

@@ -311,7 +312,7 @@

         verticalScrollbarNode.scrollTop = 2.5 * lineHeightInPixels
         verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineHasClass(9, 'fancy-class')).toBe true
         expect(lineHasClass(9, 'nope-class')).toBe false
@@ -324,7 +325,7 @@

       it "removes line classes when a decoration's marker is invalidated", ->
         editor.getBuffer().insert([3, 2], 'n')
-        nextTick()
+        runSetImmediateCallbacks()

         expect(marker.isValid()).toBe false
@@ -334,7 +335,7 @@
         expect(lineHasClass(4, 'someclass')).toBe false

         editor.getBuffer().undo()
-        nextTick()
+        runSetImmediateCallbacks()

         expect(marker.isValid()).toBe true
         expect(lineHasClass(1, 'someclass')).toBe false
@@ -344,7 +345,7 @@

       it "removes the classes and unsubscribes from the marker when decoration is removed", ->
         editor.removeDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineHasClass(1, 'someclass')).toBe false
         expect(lineHasClass(2, 'someclass')).toBe false
@@ -352,14 +353,14 @@
         expect(lineHasClass(4, 'someclass')).toBe false

         editor.getBuffer().insert([0, 0], '\n')
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineHasClass(2, 'someclass')).toBe false
         expect(lineHasClass(3, 'someclass')).toBe false

       it "removes the line number classes when the decoration's marker is destroyed", ->
         marker.destroy()
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineHasClass(1, 'someclass')).toBe false
         expect(lineHasClass(2, 'someclass')).toBe false
@@ -382,7 +383,7 @@
     it "renders the currently-visible line numbers", ->
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(node.querySelectorAll('.line-number').length).toBe 6 + 2 + 1 # line overdraw margin below + dummy line number
       expect(component.lineNumberNodeForScreenRow(0).textContent).toBe "#{nbsp}1"
@@ -390,6 +391,7 @@

       verticalScrollbarNode.scrollTop = 2.5 * lineHeightInPixels
       verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
+      runSetImmediateCallbacks()

       expect(node.querySelectorAll('.line-number').length).toBe 6 + 4 + 1 # line overdraw margin above/below + dummy line number

@@ -400,7 +402,7 @@

     it "updates the translation of subsequent line numbers when lines are inserted or removed", ->
       editor.getBuffer().insert([0, 0], '\n\n')
-      nextTick()
+      runSetImmediateCallbacks()

       lineNumberNodes = node.querySelectorAll('.line-number')
       expect(component.lineNumberNodeForScreenRow(0).offsetTop).toBe 0
@@ -410,7 +412,7 @@
       expect(component.lineNumberNodeForScreenRow(4).offsetTop).toBe 4 * lineHeightInPixels

       editor.getBuffer().insert([0, 0], '\n\n')
-      nextTick()
+      runSetImmediateCallbacks()

       expect(component.lineNumberNodeForScreenRow(0).offsetTop).toBe 0
       expect(component.lineNumberNodeForScreenRow(1).offsetTop).toBe 1 * lineHeightInPixels
@@ -425,7 +427,7 @@
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       node.style.width = 30 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(node.querySelectorAll('.line-number').length).toBe 6 + lineOverdrawMargin + 1 # 1 dummy line node
       expect(component.lineNumberNodeForScreenRow(0).textContent).toBe "#{nbsp}1"
@@ -437,7 +439,7 @@

     it "pads line numbers to be right-justified based on the maximum number of line number digits", ->
       editor.getBuffer().setText([1..10].join('\n'))
-      nextTick()
+      runSetImmediateCallbacks()
       for screenRow in [0..8]
         expect(component.lineNumberNodeForScreenRow(screenRow).textContent).toBe "#{nbsp}#{screenRow + 1}"
       expect(component.lineNumberNodeForScreenRow(9).textContent).toBe "10"
@@ -447,14 +449,14 @@

       # Removes padding when the max number of digits goes down
       editor.getBuffer().delete([[1, 0], [2, 0]])
-      nextTick()
+      runSetImmediateCallbacks()
       for screenRow in [0..8]
         expect(component.lineNumberNodeForScreenRow(screenRow).textContent).toBe "#{screenRow + 1}"
       expect(gutterNode.offsetWidth).toBeLessThan initialGutterWidth

       # Increases padding when the max number of digits goes up
       editor.getBuffer().insert([0, 0], '\n\n')
-      nextTick()
+      runSetImmediateCallbacks()
       for screenRow in [0..8]
         expect(component.lineNumberNodeForScreenRow(screenRow).textContent).toBe "#{nbsp}#{screenRow + 1}"
       expect(component.lineNumberNodeForScreenRow(9).textContent).toBe "10"
@@ -463,7 +465,7 @@
     it "renders the .line-numbers div at the full height of the editor even if it's taller than its content", ->
       node.style.height = node.offsetHeight + 100 + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.querySelector('.line-numbers').offsetHeight).toBe node.offsetHeight

     describe "when the editor.showLineNumbers config is false", ->
@@ -486,7 +488,7 @@

         it "updates the foldable class on the correct line numbers when the foldable positions change", ->
           editor.getBuffer().insert([0, 0], '\n')
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(0, 'foldable')).toBe false
           expect(lineNumberHasClass(1, 'foldable')).toBe true
           expect(lineNumberHasClass(2, 'foldable')).toBe true
@@ -499,25 +501,25 @@
           expect(lineNumberHasClass(11, 'foldable')).toBe false

           editor.getBuffer().insert([11, 44], '\n    fold me')
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(11, 'foldable')).toBe true

           editor.undo()
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(11, 'foldable')).toBe false

         it "adds, updates and removes the folded class on the correct line number nodes", ->
           editor.foldBufferRow(4)
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(4, 'folded')).toBe true

           editor.getBuffer().insert([0, 0], '\n')
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(4, 'folded')).toBe false
           expect(lineNumberHasClass(5, 'folded')).toBe true

           editor.unfoldBufferRow(5)
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(5, 'folded')).toBe false

       describe "mouse interactions with fold indicators", ->
@@ -535,19 +537,19 @@
           lineNumber = component.lineNumberNodeForScreenRow(1)
           target = lineNumber.querySelector('.icon-right')
           target.dispatchEvent(buildClickEvent(target))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(1, 'folded')).toBe true

           lineNumber = component.lineNumberNodeForScreenRow(1)
           target = lineNumber.querySelector('.icon-right')
           target.dispatchEvent(buildClickEvent(target))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(1, 'folded')).toBe false

         it "does not fold when the line number node is clicked", ->
           lineNumber = component.lineNumberNodeForScreenRow(1)
           lineNumber.dispatchEvent(buildClickEvent(lineNumber))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(1, 'folded')).toBe false

     describe "cursor-line decorations", ->
@@ -557,11 +559,11 @@

       it "modifies the cursor-line decoration when the cursor moves", ->
         cursor.setScreenPosition([0, 0])
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(0, 'cursor-line')).toBe true

         cursor.setScreenPosition([1, 0])
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(0, 'cursor-line')).toBe false
         expect(lineNumberHasClass(1, 'cursor-line')).toBe true

@@ -569,20 +571,20 @@
         cursor.setScreenPosition([2, 0])
         cursor2 = editor.addCursorAtScreenPosition([8, 0])
         cursor3 = editor.addCursorAtScreenPosition([10, 0])
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineNumberHasClass(2, 'cursor-line')).toBe true
         expect(lineNumberHasClass(8, 'cursor-line')).toBe true
         expect(lineNumberHasClass(10, 'cursor-line')).toBe true

         cursor2.destroy()
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(2, 'cursor-line')).toBe true
         expect(lineNumberHasClass(8, 'cursor-line')).toBe false
         expect(lineNumberHasClass(10, 'cursor-line')).toBe true

         cursor3.destroy()
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(2, 'cursor-line')).toBe true
         expect(lineNumberHasClass(8, 'cursor-line')).toBe false
         expect(lineNumberHasClass(10, 'cursor-line')).toBe false
@@ -590,7 +592,7 @@
       it "adds cursor-line decorations to multiple lines when a selection is performed", ->
         cursor.setScreenPosition([1, 5])
         editor.selectDown(2)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(0, 'cursor-line')).toBe false
         expect(lineNumberHasClass(1, 'cursor-line')).toBe true
         expect(lineNumberHasClass(2, 'cursor-line')).toBe true
@@ -600,7 +602,7 @@
       it "does not render a cursor-line decoration for the last line of a multi-line selection of the selection ends at column 0", ->
         cursor.setScreenPosition([1, 0])
         editor.selectDown(2)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(0, 'cursor-line')).toBe false
         expect(lineNumberHasClass(1, 'cursor-line')).toBe true
         expect(lineNumberHasClass(2, 'cursor-line')).toBe true
@@ -612,12 +614,12 @@
         marker = editor.displayBuffer.markBufferRange([[2, 13], [3, 15]], invalidate: 'inside')
         decoration = {type: 'gutter', class: 'someclass'}
         editor.addDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()

       it "does not render off-screen lines with line number classes until they are with in the rendered row range", ->
         node.style.height = 4.5 * lineHeightInPixels + 'px'
         component.measureScrollView()
-        nextTick()
+        runSetImmediateCallbacks()
         expect(component.lineNumberNodeForScreenRow(9)).not.toBeDefined()

         marker = editor.displayBuffer.markBufferRange([[9, 0], [9, 0]], invalidate: 'inside')
@@ -626,7 +628,7 @@

         verticalScrollbarNode.scrollTop = 2.5 * lineHeightInPixels
         verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
-        nextTick()
+        runSetImmediateCallbacks()

         expect(lineNumberHasClass(9, 'fancy-class')).toBe true
         expect(lineNumberHasClass(9, 'nope-class')).toBe false
@@ -634,13 +636,13 @@
       it "renders classes on correct screen lines when the user folds a block of code", ->
         marker = editor.displayBuffer.markBufferRange([[9, 0], [9, 0]], invalidate: 'inside')
         editor.addDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberForBufferRowHasClass(9, 'someclass')).toBe true

         editor.foldBufferRow(5)
-        nextTick() # TODO: Removing this nextTick causes the spec to fail because of flaws in decoration updating
+        runSetImmediateCallbacks() # TODO: Removing this runSetImmediateCallbacks causes the spec to fail because of flaws in decoration updating
         editor.removeDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberForBufferRowHasClass(9, 'someclass')).toBe false

       it "updates line number classes when the marker moves", ->
@@ -650,14 +652,14 @@
         expect(lineNumberHasClass(4, 'someclass')).toBe false

         editor.getBuffer().insert([0, 0], '\n')
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(2, 'someclass')).toBe false
         expect(lineNumberHasClass(3, 'someclass')).toBe true
         expect(lineNumberHasClass(4, 'someclass')).toBe true
         expect(lineNumberHasClass(5, 'someclass')).toBe false

         editor.getBuffer().deleteRows(0, 1)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(0, 'someclass')).toBe false
         expect(lineNumberHasClass(1, 'someclass')).toBe true
         expect(lineNumberHasClass(2, 'someclass')).toBe true
@@ -665,7 +667,7 @@

       it "removes line number classes when a decoration's marker is invalidated", ->
         editor.getBuffer().insert([3, 2], 'n')
-        nextTick()
+        runSetImmediateCallbacks()
         expect(marker.isValid()).toBe false
         expect(lineNumberHasClass(1, 'someclass')).toBe false
         expect(lineNumberHasClass(2, 'someclass')).toBe false
@@ -673,7 +675,7 @@
         expect(lineNumberHasClass(4, 'someclass')).toBe false

         editor.getBuffer().undo()
-        nextTick()
+        runSetImmediateCallbacks()
         expect(marker.isValid()).toBe true
         expect(lineNumberHasClass(1, 'someclass')).toBe false
         expect(lineNumberHasClass(2, 'someclass')).toBe true
@@ -682,20 +684,20 @@

       it "removes the classes and unsubscribes from the marker when decoration is removed", ->
         editor.removeDecorationForMarker(marker, decoration)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(1, 'someclass')).toBe false
         expect(lineNumberHasClass(2, 'someclass')).toBe false
         expect(lineNumberHasClass(3, 'someclass')).toBe false
         expect(lineNumberHasClass(4, 'someclass')).toBe false

         editor.getBuffer().insert([0, 0], '\n')
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(2, 'someclass')).toBe false
         expect(lineNumberHasClass(3, 'someclass')).toBe false

       it "removes the line number classes when the decoration's marker is destroyed", ->
         marker.destroy()
-        nextTick()
+        runSetImmediateCallbacks()
         expect(lineNumberHasClass(1, 'someclass')).toBe false
         expect(lineNumberHasClass(2, 'someclass')).toBe false
         expect(lineNumberHasClass(3, 'someclass')).toBe false
@@ -707,19 +709,19 @@
           editor.setSoftWrap(true)
           node.style.width = 16 * charWidth + 'px'
           component.measureScrollView()
-          nextTick()
+          runSetImmediateCallbacks()

         it "applies decoration only to the first row when marker range does not wrap", ->
           marker = editor.displayBuffer.markBufferRange([[0, 0], [0, 0]])
           editor.addDecorationForMarker(marker, type: 'gutter', class: 'someclass')
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(0, 'someclass')).toBe true
           expect(lineNumberHasClass(1, 'someclass')).toBe false

         it "applies decoration to both rows when marker wraps", ->
           marker = editor.displayBuffer.markBufferRange([[0, 0], [0, Infinity]])
           editor.addDecorationForMarker(marker, type: 'gutter', class: 'someclass')
-          nextTick()
+          runSetImmediateCallbacks()
           expect(lineNumberHasClass(0, 'someclass')).toBe true
           expect(lineNumberHasClass(1, 'someclass')).toBe true

@@ -731,7 +733,7 @@
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       node.style.width = 20 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       cursorNodes = node.querySelectorAll('.cursor')
       expect(cursorNodes.length).toBe 1
@@ -741,7 +743,7 @@

       cursor2 = editor.addCursorAtScreenPosition([8, 11])
       cursor3 = editor.addCursorAtScreenPosition([4, 10])
-      nextTick()
+      runSetImmediateCallbacks()

       cursorNodes = node.querySelectorAll('.cursor')
       expect(cursorNodes.length).toBe 2
@@ -753,6 +755,7 @@
       verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
       horizontalScrollbarNode.scrollLeft = 3.5 * charWidth
       horizontalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
+      runSetImmediateCallbacks()

       cursorNodes = node.querySelectorAll('.cursor')
       expect(cursorNodes.length).toBe 2
@@ -760,7 +763,7 @@
       expect(cursorNodes[1].style['-webkit-transform']).toBe "translate3d(#{(10 - 3.5) * charWidth}px, #{(4 - 4.5) * lineHeightInPixels}px, 0px)"

       cursor3.destroy()
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNodes = node.querySelectorAll('.cursor')
       expect(cursorNodes.length).toBe 1
       expect(cursorNodes[0].style['-webkit-transform']).toBe "translate3d(#{(11 - 3.5) * charWidth}px, #{(6 - 2.5) * lineHeightInPixels}px, 0px)"
@@ -768,7 +771,7 @@
     it "accounts for character widths when positioning cursors", ->
       atom.config.set('editor.fontFamily', 'sans-serif')
       editor.setCursorScreenPosition([0, 16])
-      nextTick()
+      runSetImmediateCallbacks()

       cursor = node.querySelector('.cursor')
       cursorRect = cursor.getBoundingClientRect()
@@ -784,13 +787,13 @@

     it "sets the cursor to the default character width at the end of a line", ->
       editor.setCursorScreenPosition([0, Infinity])
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNode = node.querySelector('.cursor')
       expect(cursorNode.offsetWidth).toBe charWidth

     it "gives the cursor a non-zero width even if it's inside atomic tokens", ->
       editor.setCursorScreenPosition([1, 0])
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNode = node.querySelector('.cursor')
       expect(cursorNode.offsetWidth).toBe charWidth

@@ -816,7 +819,7 @@
     it "does not render cursors that are associated with non-empty selections", ->
       editor.setSelectedScreenRange([[0, 4], [4, 6]])
       editor.addCursorAtScreenPosition([6, 8])
-      nextTick()
+      runSetImmediateCallbacks()

       cursorNodes = node.querySelectorAll('.cursor')
       expect(cursorNodes.length).toBe 1
@@ -825,21 +828,21 @@
     it "updates cursor positions when the line height changes", ->
       editor.setCursorBufferPosition([1, 10])
       component.setLineHeight(2)
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNode = node.querySelector('.cursor')
       expect(cursorNode.style['-webkit-transform']).toBe "translate3d(#{10 * editor.getDefaultCharWidth()}px, #{editor.getLineHeightInPixels()}px, 0px)"

     it "updates cursor positions when the font size changes", ->
       editor.setCursorBufferPosition([1, 10])
       component.setFontSize(10)
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNode = node.querySelector('.cursor')
       expect(cursorNode.style['-webkit-transform']).toBe "translate3d(#{10 * editor.getDefaultCharWidth()}px, #{editor.getLineHeightInPixels()}px, 0px)"

     it "updates cursor positions when the font family changes", ->
       editor.setCursorBufferPosition([1, 10])
       component.setFontFamily('sans-serif')
-      nextTick()
+      runSetImmediateCallbacks()
       cursorNode = node.querySelector('.cursor')

       {left} = editor.pixelPositionForScreenPosition([1, 10])
@@ -855,7 +858,7 @@
     it "renders 1 region for 1-line selections", ->
       # 1-line selection
       editor.setSelectedScreenRange([[1, 6], [1, 10]])
-      nextTick()
+      runSetImmediateCallbacks()
       regions = node.querySelectorAll('.selection .region')

       expect(regions.length).toBe 1
@@ -867,7 +870,7 @@

     it "renders 2 regions for 2-line selections", ->
       editor.setSelectedScreenRange([[1, 6], [2, 10]])
-      nextTick()
+      runSetImmediateCallbacks()
       regions = node.querySelectorAll('.selection .region')
       expect(regions.length).toBe 2

@@ -885,7 +888,7 @@

     it "renders 3 regions for selections with more than 2 lines", ->
       editor.setSelectedScreenRange([[1, 6], [5, 10]])
-      nextTick()
+      runSetImmediateCallbacks()
       regions = node.querySelectorAll('.selection .region')
       expect(regions.length).toBe 3

@@ -909,7 +912,7 @@

     it "does not render empty selections", ->
       editor.addSelectionForBufferRange([[2, 2], [2, 2]])
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.getSelection(0).isEmpty()).toBe true
       expect(editor.getSelection(1).isEmpty()).toBe true

@@ -918,14 +921,14 @@
     it "updates selections when the line height changes", ->
       editor.setSelectedBufferRange([[1, 6], [1, 10]])
       component.setLineHeight(2)
-      nextTick()
+      runSetImmediateCallbacks()
       selectionNode = node.querySelector('.region')
       expect(selectionNode.offsetTop).toBe editor.getLineHeightInPixels()

     it "updates selections when the font size changes", ->
       editor.setSelectedBufferRange([[1, 6], [1, 10]])
       component.setFontSize(10)
-      nextTick()
+      runSetImmediateCallbacks()
       selectionNode = node.querySelector('.region')
       expect(selectionNode.offsetTop).toBe editor.getLineHeightInPixels()
       expect(selectionNode.offsetLeft).toBe 6 * editor.getDefaultCharWidth()
@@ -933,7 +936,7 @@
     it "updates selections when the font family changes", ->
       editor.setSelectedBufferRange([[1, 6], [1, 10]])
       component.setFontFamily('sans-serif')
-      nextTick()
+      runSetImmediateCallbacks()
       selectionNode = node.querySelector('.region')
       expect(selectionNode.offsetTop).toBe editor.getLineHeightInPixels()
       expect(selectionNode.offsetLeft).toBe editor.pixelPositionForScreenPosition([1, 6]).left
@@ -945,16 +948,16 @@
       marker = editor.displayBuffer.markBufferRange([[2, 13], [3, 15]], invalidate: 'inside')
       decoration = {type: 'highlight', class: 'test-highlight'}
       editor.addDecorationForMarker(marker, decoration)
-      nextTick()
+      runSetImmediateCallbacks()

     it "does not render highlights for off-screen lines until they come on-screen", ->
       node.style.height = 2.5 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       marker = editor.displayBuffer.markBufferRange([[9, 2], [9, 4]], invalidate: 'inside')
       editor.addDecorationForMarker(marker, type: 'highlight', class: 'some-highlight')
-      nextTick()
+      runSetImmediateCallbacks()

       # Should not be rendering range containing the marker
       expect(component.getRenderedRowRange()[1]).toBeLessThan 9
@@ -966,6 +969,7 @@

       verticalScrollbarNode.scrollTop = 3.5 * lineHeightInPixels
       verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
+      runSetImmediateCallbacks()

       regions = node.querySelectorAll('.some-highlight .region')

@@ -982,31 +986,31 @@

     it "removes highlights when a decoration is removed", ->
       editor.removeDecorationForMarker(marker, decoration)
-      nextTick()
+      runSetImmediateCallbacks()
       regions = node.querySelectorAll('.test-highlight .region')
       expect(regions.length).toBe 0

     it "does not render a highlight that is within a fold", ->
       editor.foldBufferRow(1)
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.querySelectorAll('.test-highlight').length).toBe 0

     it "removes highlights when a decoration's marker is destroyed", ->
       marker.destroy()
-      nextTick()
+      runSetImmediateCallbacks()
       regions = node.querySelectorAll('.test-highlight .region')
       expect(regions.length).toBe 0

     it "only renders highlights when a decoration's marker is valid", ->
       editor.getBuffer().insert([3, 2], 'n')
-      nextTick()
+      runSetImmediateCallbacks()

       expect(marker.isValid()).toBe false
       regions = node.querySelectorAll('.test-highlight .region')
       expect(regions.length).toBe 0

       editor.getBuffer().undo()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(marker.isValid()).toBe true
       regions = node.querySelectorAll('.test-highlight .region')
@@ -1018,7 +1022,7 @@
         originalTop = parseInt(regionStyle.top)

         editor.getBuffer().insert([0, 0], '\n')
-        nextTick()
+        runSetImmediateCallbacks()

         regionStyle = node.querySelector('.test-highlight .region').style
         newTop = parseInt(regionStyle.top)
@@ -1030,7 +1034,7 @@
         expect(parseInt(regionStyle.top)).toBe 2 * lineHeightInPixels

         marker.setBufferRange([[5, 8], [5, 13]])
-        nextTick()
+        runSetImmediateCallbacks()

         regionStyle = node.querySelector('.test-highlight .region').style
         expect(parseInt(regionStyle.top)).toBe 5 * lineHeightInPixels
@@ -1044,19 +1048,19 @@
       node.style.height = 5 * lineHeightInPixels + 'px'
       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(editor.getCursorScreenPosition()).toEqual [0, 0]
       editor.setScrollTop(3 * lineHeightInPixels)
       editor.setScrollLeft(3 * charWidth)
-      nextTick()
+      runSetImmediateCallbacks()

       expect(inputNode.offsetTop).toBe 0
       expect(inputNode.offsetLeft).toBe 0

       # In bounds, not focused
       editor.setCursorBufferPosition([5, 4])
-      nextTick()
+      runSetImmediateCallbacks()
       expect(inputNode.offsetTop).toBe 0
       expect(inputNode.offsetLeft).toBe 0

@@ -1072,7 +1076,7 @@

       # Out of bounds, not focused
       editor.setCursorBufferPosition([1, 2])
-      nextTick()
+      runSetImmediateCallbacks()
       expect(inputNode.offsetTop).toBe 0
       expect(inputNode.offsetLeft).toBe 0

@@ -1096,24 +1100,24 @@
           component.measureScrollView()
           editor.setScrollTop(3.5 * lineHeightInPixels)
           editor.setScrollLeft(2 * charWidth)
-          nextTick()
+          runSetImmediateCallbacks()

           linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([4, 8])))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(editor.getCursorScreenPosition()).toEqual [4, 8]

       describe "when the shift key is held down", ->
         it "selects to the nearest screen position", ->
           editor.setCursorScreenPosition([3, 4])
           linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([5, 6]), shiftKey: true))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(editor.getSelectedScreenRange()).toEqual [[3, 4], [5, 6]]

       describe "when the command key is held down", ->
         it "adds a cursor at the nearest screen position", ->
           editor.setCursorScreenPosition([3, 4])
           linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([5, 6]), metaKey: true))
-          nextTick()
+          runSetImmediateCallbacks()
           expect(editor.getSelectedScreenRanges()).toEqual [[[3, 4], [3, 4]], [[5, 6], [5, 6]]]

     describe "when a non-folded line is double-clicked", ->
@@ -1179,7 +1183,7 @@
     describe "when a line is folded", ->
       beforeEach ->
         editor.foldBufferRow 4
-        nextTick()
+        runSetImmediateCallbacks()

       describe "when the folded line's fold-marker is clicked", ->
         it "unfolds the buffer row", ->
@@ -1308,49 +1312,49 @@
     beforeEach ->
       cursor = editor.getCursor()
       cursor.setScreenPosition([0, 0])
-      nextTick()
+      runSetImmediateCallbacks()

     it "adds the 'has-selection' class to the editor when there is a selection", ->
       expect(node.classList.contains('has-selection')).toBe false

       editor.selectDown()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.classList.contains('has-selection')).toBe true

       cursor.moveDown()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.classList.contains('has-selection')).toBe false

   describe "scrolling", ->
     it "updates the vertical scrollbar when the scrollTop is changed in the model", ->
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(verticalScrollbarNode.scrollTop).toBe 0

       editor.setScrollTop(10)
-      nextTick()
+      runSetImmediateCallbacks()
       expect(verticalScrollbarNode.scrollTop).toBe 10

     it "updates the horizontal scrollbar and the x transform of the lines based on the scrollLeft of the model", ->
       node.style.width = 30 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       linesNode = node.querySelector('.lines')
       expect(linesNode.style['-webkit-transform']).toBe "translate3d(0px, 0px, 0px)"
       expect(horizontalScrollbarNode.scrollLeft).toBe 0

       editor.setScrollLeft(100)
-      nextTick()
+      runSetImmediateCallbacks()
       expect(linesNode.style['-webkit-transform']).toBe "translate3d(-100px, 0px, 0px)"
       expect(horizontalScrollbarNode.scrollLeft).toBe 100

     it "updates the scrollLeft of the model when the scrollLeft of the horizontal scrollbar changes", ->
       node.style.width = 30 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(editor.getScrollLeft()).toBe 0
       horizontalScrollbarNode.scrollLeft = 100
@@ -1363,7 +1367,7 @@
       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
       editor.setScrollBottom(editor.getScrollHeight())
-      nextTick()
+      runSetImmediateCallbacks()
       lastLineNode = component.lineNodeForScreenRow(editor.getLastScreenRow())
       bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
       topOfHorizontalScrollbar = horizontalScrollbarNode.getBoundingClientRect().top
@@ -1372,7 +1376,7 @@
       # Scroll so there's no space below the last line when the horizontal scrollbar disappears
       node.style.width = 100 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()
       bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
       bottomOfEditor = node.getBoundingClientRect().bottom
       expect(bottomOfLastLine).toBe bottomOfEditor
@@ -1382,7 +1386,7 @@
       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
       editor.setScrollLeft(Infinity)
-      nextTick()
+      runSetImmediateCallbacks()

       rightOfLongestLine = component.lineNodeForScreenRow(6).querySelector('.line > span:last-child').getBoundingClientRect().right
       leftOfVerticalScrollbar = verticalScrollbarNode.getBoundingClientRect().left
@@ -1395,21 +1399,21 @@
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       node.style.width = '1000px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(verticalScrollbarNode.style.display).toBe ''
       expect(horizontalScrollbarNode.style.display).toBe 'none'

       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(verticalScrollbarNode.style.display).toBe ''
       expect(horizontalScrollbarNode.style.display).toBe ''

       node.style.height = 20 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(verticalScrollbarNode.style.display).toBe 'none'
       expect(horizontalScrollbarNode.style.display).toBe ''
@@ -1418,7 +1422,7 @@
       node.style.height = 4 * lineHeightInPixels + 'px'
       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       atom.themes.applyStylesheet "test", """
         ::-webkit-scrollbar {
@@ -1442,21 +1446,21 @@
       node.style.height = 4.5 * lineHeightInPixels + 'px'
       node.style.width = '1000px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(verticalScrollbarNode.style.bottom).toBe ''
       expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
       expect(scrollbarCornerNode.style.display).toBe 'none'

       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
       expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
       expect(scrollbarCornerNode.style.display).toBe ''

       node.style.height = 20 * lineHeightInPixels + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()
       expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
       expect(horizontalScrollbarNode.style.right).toBe ''
       expect(scrollbarCornerNode.style.display).toBe 'none'
@@ -1465,7 +1469,7 @@
       gutterNode = node.querySelector('.gutter')
       node.style.width = 10 * charWidth + 'px'
       component.measureScrollView()
-      nextTick()
+      runSetImmediateCallbacks()

       expect(horizontalScrollbarNode.scrollWidth).toBe gutterNode.offsetWidth + editor.getScrollWidth()

@@ -1478,37 +1482,43 @@
         node.style.height = 4.5 * lineHeightInPixels + 'px'
         node.style.width = 20 * charWidth + 'px'
         component.measureScrollView()
-        nextTick()
+        runSetImmediateCallbacks()

       it "updates the scrollLeft or scrollTop on mousewheel events depending on which delta is greater (x or y)", ->
         expect(verticalScrollbarNode.scrollTop).toBe 0
         expect(horizontalScrollbarNode.scrollLeft).toBe 0

         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -5, wheelDeltaY: -10))
+        runSetImmediateCallbacks()
         expect(verticalScrollbarNode.scrollTop).toBe 10
         expect(horizontalScrollbarNode.scrollLeft).toBe 0

         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -15, wheelDeltaY: -5))
+        runSetImmediateCallbacks()
         expect(verticalScrollbarNode.scrollTop).toBe 10
         expect(horizontalScrollbarNode.scrollLeft).toBe 15

       it "updates the scrollLeft or scrollTop according to the scroll sensitivity", ->
         atom.config.set('editor.scrollSensitivity', 50)
         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -5, wheelDeltaY: -10))
+        runSetImmediateCallbacks()
         expect(horizontalScrollbarNode.scrollLeft).toBe 0

         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -15, wheelDeltaY: -5))
+        runSetImmediateCallbacks()
         expect(verticalScrollbarNode.scrollTop).toBe 5
         expect(horizontalScrollbarNode.scrollLeft).toBe 7

       it "uses the previous scrollSensitivity when the value is not an int", ->
         atom.config.set('editor.scrollSensitivity', 'nope')
         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -10))
+        runSetImmediateCallbacks()
         expect(verticalScrollbarNode.scrollTop).toBe 10

       it "parses negative scrollSensitivity values as positive", ->
         atom.config.set('editor.scrollSensitivity', -50)
         node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -10))
+        runSetImmediateCallbacks()
         expect(verticalScrollbarNode.scrollTop).toBe 5

     describe "when the mousewheel event's target is a line", ->
@@ -1594,28 +1604,28 @@

     it "inserts the newest character in the input's value into the buffer", ->
       node.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.lineForBufferRow(0)).toBe 'xvar quicksort = function () {'

       node.dispatchEvent(buildTextInputEvent(data: 'y', target: inputNode))
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.lineForBufferRow(0)).toBe 'xyvar quicksort = function () {'

     it "replaces the last character if the length of the input's value doesn't increase, as occurs with the accented character menu", ->
       node.dispatchEvent(buildTextInputEvent(data: 'u', target: inputNode))
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.lineForBufferRow(0)).toBe 'uvar quicksort = function () {'

       # simulate the accented character suggestion's selection of the previous character
       inputNode.setSelectionRange(0, 1)
       node.dispatchEvent(buildTextInputEvent(data: 'ü', target: inputNode))
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.lineForBufferRow(0)).toBe 'üvar quicksort = function () {'

     it "does not handle input events when input is disabled", ->
       component.setInputEnabled(false)
       node.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
-      nextTick()
+      runSetImmediateCallbacks()
       expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'

     describe "when IME composition is used to insert international characters", ->
@@ -1721,7 +1731,7 @@
         initialLineHeightInPixels = editor.getLineHeightInPixels()

         component.setLineHeight(2)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(editor.getLineHeightInPixels()).toBe initialLineHeightInPixels

         wrapperView.show()
@@ -1734,7 +1744,7 @@
         initialCharWidth = editor.getDefaultCharWidth()

         component.setFontSize(22)
-        nextTick()
+        runSetImmediateCallbacks()
         expect(editor.getLineHeightInPixels()).toBe initialLineHeightInPixels
         expect(editor.getDefaultCharWidth()).toBe initialCharWidth

@@ -1746,11 +1756,11 @@
         wrapperView.hide()

         component.setFontSize(22)
-        nextTick()
+        runSetImmediateCallbacks()

         wrapperView.show()
         editor.setCursorBufferPosition([0, Infinity])
-        nextTick()
+        runSetImmediateCallbacks()

         cursorLeft = node.querySelector('.cursor').getBoundingClientRect().left
         line0Right = node.querySelector('.line > span:last-child').getBoundingClientRect().right
@@ -1763,7 +1773,7 @@
         initialCharWidth = editor.getDefaultCharWidth()

         component.setFontFamily('sans-serif')
-        nextTick()
+        runSetImmediateCallbacks()
         expect(editor.getDefaultCharWidth()).toBe initialCharWidth

         wrapperView.show()
@@ -1773,11 +1783,11 @@
         wrapperView.hide()

         component.setFontFamily('sans-serif')
-        nextTick()
+        runSetImmediateCallbacks()

         wrapperView.show()
         editor.setCursorBufferPosition([0, Infinity])
-        nextTick()
+        runSetImmediateCallbacks()

         cursorLeft = node.querySelector('.cursor').getBoundingClientRect().left
         line0Right = node.querySelector('.line > span:last-child').getBoundingClientRect().right
@@ -1789,7 +1799,7 @@
         wrapperView.hide()
         editor.setText('var z = 1')
         editor.setCursorBufferPosition([0, Infinity])
-        nextTick()
+        runSetImmediateCallbacks()
         wrapperView.show()
         expect(node.querySelector('.cursor').style['-webkit-transform']).toBe "translate3d(#{9 * charWidth}px, 0px, 0px)"

@@ -1801,13 +1811,13 @@
       node.style.height = newHeight

       advanceClock(component.scrollViewMeasurementInterval)
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.querySelectorAll('.line')).toHaveLength(4 + lineOverdrawMargin + 1)

       gutterWidth = node.querySelector('.gutter').offsetWidth
       node.style.width = gutterWidth + 14 * charWidth + 'px'
       advanceClock(component.scrollViewMeasurementInterval)
-      nextTick()
+      runSetImmediateCallbacks()
       expect(node.querySelector('.line').textContent).toBe "var quicksort "

   describe "legacy editor compatibility", ->
@@ -1818,7 +1828,7 @@
       editor.on 'screen-lines-changed', -> callingOrder.push 'screen-lines-changed'
       wrapperView.on 'editor:display-updated', -> callingOrder.push 'editor:display-updated'
       editor.insertText("HELLO! HELLO!\n HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! HELLO! ")
-      nextTick()
+      runSetImmediateCallbacks()

       expect(callingOrder).toEqual ['screen-lines-changed', 'editor:display-updated']


pcbnew exporter (.pretty format)

pcbnew exporter (.pretty format)

error: pathspec 'src/output/pcbnew.coffee' did not match any file(s) known to git

--- src/output/pcbnew.coffee
+++ src/output/pcbnew.coffee
@@ -0,0 +1,91 @@
+# pad {
+#   num
+#   location: [x, y]
+#   size: d or [x, y]
+#   drill: d or [x, y]
+#   square: true
+#   nopaste: true
+#   hole: true
+#   back: true
+# }
+
+module.exports = (data, lib) -> data.map(each, lib)
+
+each = (data) ->
+  ret = """
+        (module #{ data.name } (layer F.Cu)
+          (at 0 0)
+          (fp_text reference #{ data.name } (at 0 0) (layer F.SilkS)
+            (effects (font (size #{ data.font || 0.8} #{ data.font || 0.8}) (thickness #{ data.silkWidth || 0.12})))
+          )
+        """
+
+  if data.pads
+    ret += data.pads.map (a) ->
+      num: a.num
+      type: if a.hole
+        'np_thru_hole'
+      else if a.drill
+        'thru_hole'
+      else if a.nopaste
+        'connect'
+      else
+        'smd'
+      padShape: if a.square
+        'rect'
+      else if a.size[0] && a.size[1] && a.size[0] != a.size[1]
+        'oval'
+      else
+        'circle'
+      location: a.location
+      size: if a.size[1] then a.size else [a.size, a.size]
+      drill: a.drill
+      lCu: if drill then '*.Cu' else if a.back then 'B.Cu' else 'F.Cu'
+      lMask: if drill then '*.Mask' else if a.back then 'B.Mask' else 'F.Mask'
+      lPaste: if a.nopaste then '' else if a.back then 'B.Paste' else 'F.Paste'
+      lSilk: if a.drill then 'F.Silk' else ''
+    .map (a) ->
+      """
+        (pad #{ a.num } #{ a.type } #{ a.padShape  } (at #{ a.location.join(' ') }) (size #{ a.size.join(' ') }) (drill #{ if a.drill[1] then 'oval ' + a.drill.join(' ') else a.drill })
+          (layers #{ a.lCu } #{ a.lMask } #{ a.lPaste } #{ a.lSilk })
+        )
+      """
+    .join('\n') + '\n'
+
+  if data.silk
+    ret += data.silk.map (a) ->
+      layer = switch a.layer
+        when 'backSilk' then 'B.SilkS'
+        when 'edge' then 'Edge.Cuts'
+        when 'frontCopper' then 'F.Cu'
+        when 'backCopper' then 'B.Cu'
+        when 'frontMask' then 'F.Mask'
+        when 'backMask' then 'B.Mask'
+        else 'F.SilkS'
+      width = a.width || data.silkWidth || 0.12
+      """
+        (fp_line (start #{ a.start.join(' ') }) (end #{ a.end.join(' ') }) (layer #{ layer }) (width #{ width }))
+      """
+    .join('\n') + '\n'
+
+  if data.arc
+    ret += data.arc.map (a) ->
+      layer = switch a.layer
+        when 'backSilk' then 'B.SilkS'
+        when 'edge' then 'Edge.Cuts'
+        when 'frontCopper' then 'F.Cu'
+        when 'backCopper' then 'B.Cu'
+        when 'frontMask' then 'F.Mask'
+        when 'backMask' then 'B.Mask'
+        else 'F.SilkS'
+      width = a.width || data.silkWidth || 0.12
+      """
+        (fp_arc (start #{ a.location.join(' ') }) (end #{ a.start.join(' ') }) (angle #{ a.angle }) (layer #{ layer }) (width #{ width }))
+      """
+    .join('\n') + '\n'
+
+  ret += ")"
+  {
+    filename: data.name + '.kicad_mod'
+    contents: ret
+  }


Stub new function to be called to initialise slider on age stats page

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Margatroid/Anilytics.git/'


make url regex match case insensitive

make url regex match case insensitive

Links created by mobile apps are often capitalized

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/VoiSmart/Rocket.Chat.git/'


add ie

add ie

error: pathspec 'data/points/ie.coffee' did not match any file(s) known to git

--- data/points/ie.coffee
+++ data/points/ie.coffee
@@ -0,0 +1,4 @@
+id: "ie"
+title: "Internet Explorer"
+function: [ "browser" ]
+homepage: "http://windows.microsoft.com/zh-cn/internet-explorer/download-ie"


Minor defensive bug handling for the LevelSessionCodeView for when teamSpells has invalid, old data.

--- app/views/common/LevelSessionCodeView.coffee
+++ app/views/common/LevelSessionCodeView.coffee
@@ -39,7 +39,7 @@
     teamSpells = @session.get('teamSpells')[team] or []
     filteredSpells = []
     for spell in teamSpells
-      code = @session.getSourceFor(spell)
+      code = @session.getSourceFor(spell) ? ''
       lines = code.split('\n').length
       height = lines * 16 + 20
       filteredSpells.push {


Add confirmDialog to Api

Add confirmDialog to Api

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/picoCTF/picoCTF-web.git/'


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

error: pathspec 'test/approachable.coffee' did not match any file(s) known to git

--- test/approachable.coffee
+++ test/approachable.coffee
@@ -0,0 +1,22 @@
+module "Approachable"
+
+test "objects count down each of their cooldowns", ->
+  obj = GameObject
+    cooldowns:
+      bullet:
+        target: 0
+        approachBy: 1
+
+  obj.include(Approachable)
+
+  5.times ->
+    obj.update()
+
+  equals obj.I.active, true, "object is active until duration is exceeded"
+
+  6.times ->
+    obj.update()
+
+  equals obj.I.active, false, "object is inactive after duration"
+
+module()


Style fixes

Style fixes

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/clochix/cozy-ical.git/'


clean

clean

--- apps/articles/test/client.coffee
+++ apps/articles/test/client.coffee
@@ -38,7 +38,7 @@
               ids: ['5321b73dc9dc2458c4000196', '5321b71c275b24bcaa0001a5'],
               layout: 'overflow_fillwidth'
             }
-        ],
+        ]
         author: new Backbone.Model fabricate 'user'
         sd: {}
         asset: (->)


Ensure window.jquery reference

Ensure window.jquery reference

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lonelyplanet/rizzo.git/'


add docType controller

add docType controller

error: pathspec 'app/controllers/doctype_controller.coffee' did not match any file(s) known to git

--- app/controllers/doctype_controller.coffee
+++ app/controllers/doctype_controller.coffee
@@ -0,0 +1,69 @@
+load 'application'
+
+git = require('git-rev')
+Client = require("request-json").JsonClient
+
+client = new Client "http://localhost:9102/"
+db = require('./helpers/db_connect_helper').db_connect()
+
+
+before 'get doc', ->
+    db.get params.id, (err, doc) =>
+        if err and err.error is "not_found"
+            app.locker.removeLock @lock
+            send error: "not found", 404
+        else if err
+            console.log "[Get doc] err: " + JSON.stringify err
+            app.locker.removeLock @lock
+            send error: err, 500
+        else if doc?
+            @doc = doc
+            next()
+        else
+            app.locker.removeLock @lock
+            send error: "not found", 404
+, only: ['delete']
+
+
+# POST /doctype
+action 'create', ->
+    delete body._attachments
+    if (body.docType? and body.docType isnt "docType") or !body.name
+        send error: "docType should be equal to 'docType' and field name are "+
+                "required", 409
+    else
+        body.docType = "docType"
+        if params.id
+            db.get params.id, (err, doc) -> # this GET needed because of cache
+                if doc
+                    send error: "The document exists", 409
+                else
+                    db.save params.id, body, (err, res) ->
+                        if err
+                            send error: err.message, 409
+                        else
+                            send "_id": res.id, 201
+        else
+            db.save body, (err, res) ->
+                if err
+                    railway.logger.write "[Create] err: " + JSON.stringify err
+                    send error: err.message, 500
+                else
+                    send "_id": res.id, 201
+
+# DELETE /data/:id
+action 'delete', ->
+    # this version don't take care of conflict (erase DB with the sent value)
+    db.remove params.id, @doc.rev, (err, res) =>
+        if err
+            # oops unexpected error !
+            console.log "[Delete] err: " + JSON.stringify err
+            send error: err.message, 500
+        else
+            # Event is emited
+            doctype = @doc.docType?.toLowerCase()
+            doctype ?= 'null'
+            app.feed.publish "#{doctype}.delete", @doc.id
+            # Doc is removed from indexation
+            client.del "index/#{params.id}/", (err, res, resbody) ->
+                send success: true, 204


fix media search by tags

fix media search by tags

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bekite/knignish.git/'


Use `backwardsScanInRange` instead of passing `true`

--- src/packages/bracket-matcher/lib/bracket-matcher.coffee
+++ src/packages/bracket-matcher/lib/bracket-matcher.coffee
@@ -116,14 +116,13 @@
     regex = new RegExp("[#{_.escapeRegExp(startPair + endPair)}]", 'g')
     startPairPosition = null
     unpairedCount = 0
-    scanner = (match, range, {stop}) =>
+    buffer.backwardsScanInRange regex, scanRange, (match, range, {stop}) =>
       if match[0] is endPair
         unpairedCount++
       else if match[0] is startPair
         unpairedCount--
         startPairPosition = range.start
         stop() if unpairedCount < 0
-    buffer.scanInRange(regex, scanRange, scanner, true)
     startPairPosition

   updateMatch: (editor) ->


Adds the coffeescript

Adds the coffeescript

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/dennis-best/clickableParent.git/'


schemas

schemas

error: pathspec 'both/collections/_schemas.coffee' did not match any file(s) known to git

--- both/collections/_schemas.coffee
+++ both/collections/_schemas.coffee
@@ -0,0 +1 @@
+@Schemas = {}


add BoltResources.create method

add BoltResources.create method

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/xaun/impac-angular.git/'


Add whitespace

Add whitespace

--- src/sensu.coffee
+++ src/sensu.coffee
@@ -172,7 +172,7 @@

     reason = msg.match[5]
     if reason
-      data['content']['reason'] = msg.message.user.name + 'silenced: ' + reason
+      data['content']['reason'] = msg.message.user.name + ' silenced: ' + reason
     else
       data['content']['reason'] = msg.message.user.name + ' silenced'


Bug fix

Bug fix

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bubblegroup/bubblebot.git/'


Add routing test

Add routing test

--- apps/sitemaps/test/routes.coffee
+++ apps/sitemaps/test/routes.coffee
@@ -5,6 +5,17 @@
 routes = rewire '../routes'

 describe 'Sitemaps', ->
+
+  beforeEach ->
+    sinon.stub Backbone, 'sync'
+    @req = {}
+    @res =
+      render: sinon.stub()
+      set: sinon.stub()
+
+  afterEach ->
+    Backbone.sync.restore()
+
   describe '#robots', ->
     beforeEach ->
       @res = set: sinon.stub(), send: sinon.stub()
@@ -23,16 +34,6 @@
       routes.robots null, @res
       @res.send.args[0][0]
         .should.equal  'Sitemap: https://www.artsy.net/sitemap.xml'
-
-  beforeEach ->
-    sinon.stub Backbone, 'sync'
-    @req = {}
-    @res =
-      render: sinon.stub()
-      set: sinon.stub()
-
-  afterEach ->
-    Backbone.sync.restore()

   describe '#news_sitemap', ->

@@ -57,12 +58,12 @@
   describe '#artworks', ->

     it 'displays the correct artwork URLs in the sitemap', ->
+      routes.__set__ 'request', get: -> query: -> end: (cb) ->
+        cb(null, { body: results: [fabricate 'artwork', { id: 'foo'}] })
+      @req =
+        params:
+          date: '2012-01-01'
+          page: 3
       routes.artworksPage('artworks')(@req, @res)
-      Backbone.sync.args[0][2].success {
-        results: [
-          fabricate('artwork', { id: 'foo' })
-        ]
-      }
-
       @res.render.args[0][0].should.equal('artworks')
-      @res.render.args[0][1].artworks[0].id.should.equal('foo')+      @res.render.args[0][1].models[0].id.should.equal('foo')


fix typo

fix typo

--- spec/BaconSpec.coffee
+++ spec/BaconSpec.coffee
@@ -1275,7 +1275,7 @@
       -> Bacon.never().toProperty(1).scan(0, add)
       [1])

-describe "EventStream.withStateMachin", ->
+describe "EventStream.withStateMachine", ->
   describe "runs state machine on the stream", ->
     expectStreamEvents(
       -> Bacon.fromArray([1,2,3]).withStateMachine(0, (sum, event) ->
@@ -1287,7 +1287,7 @@
           [sum, [event]])
       [6])

-describe "Property.withStateMachin", ->
+describe "Property.withStateMachine", ->
   describe "runs state machine on the stream", ->
     expectPropertyEvents(
       -> Bacon.fromArray([1,2,3]).toProperty().withStateMachine(0, (sum, event) ->


fix contenteditable directive

fix contenteditable directive

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/CivicCommons/CivicCommons.git/'


Create better rules of ferengi

Create better rules of ferengi

error: pathspec 'scripts/ferengi_rules_of_acquisition.coffee' did not match any file(s) known to git

--- scripts/ferengi_rules_of_acquisition.coffee
+++ scripts/ferengi_rules_of_acquisition.coffee
@@ -0,0 +1,277 @@
+# Description:
+#   Display a ferengi rule of acquisition upon certain keywords.
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   ferengi rule - Display a random ferengi rule of acquisition.
+#
+# Author:
+#   jan0sch
+
+counter = 0
+
+rules = [
+  "Ferengi Rule of Acquisition #1:\n
+  Once you have their money, you never give it back.\n
+    -- ST: DS9, \"The Nagus\", \"Heart of Stone\"",
+  "Ferengi Rule of Acquisition #3:\n
+  Never pay more for an acquisition than you have to.\n
+    -- ST: DS9, \"The Maquis, Part II\"",
+  "Ferengi Rule of Acquisition #6:\n
+  Never allow family to stand in the way of opportunity.\n
+    -- ST: DS9, \"The Nagus\"",
+  "Ferengi Rule of Acquisition #7:\n
+  Keep your ears open.\n
+    -- ST: DS9, \"In the Hands of the Prophets\"",
+  "Ferengi Rule of Acquisition #8:\n
+    Small print leads to large risk.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #9:\n
+  Opportunity plus instinct equals profit.\n
+    -- ST: DS9, The Storyteller",
+  "Ferengi Rule of Acquisition #10:\n
+  Greed is eternal.\n
+    -- ST: DS9, Prophet Motive",
+  "Ferengi Rule of Acquisition #13:\n
+    Anything worth doing is worth doing for money.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #16:\n
+  A deal is a deal... until a better one comes along.\n
+    -- ST: DS9, \"Melora\"",
+  "Ferengi Rule of Acquisition #17:\n
+  A contract is a contract is a contract... but only between Ferengi.\n
+    -- ST: DS9, \"Body Parts\"",
+  "Ferengi Rule of Acquisition #18:\n
+  A Ferengi without profit is no Ferengi at all.\n
+    -- ST: DS9, \"Heart of Stone\"",
+  "Ferengi Rule of Acquisition #19:\n
+    Satisfaction is not guaranteed.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #21:\n
+  Never place friendship above profit.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #22:\n
+  A wise man can hear profit in the wind.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #27:\n
+    There is nothing more dangerous than an honest businessman\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #28:\n
+  Whisper your way to success.\n
+    -- ST: DS9, \"Treachery, Faith, and the Great River\"",
+  "Ferengi Rule of Acquisition #31:\n
+  Never make fun of a Ferengi's mother.\n
+    -- ST: DS9, \"The Siege\"",
+  "Ferengi Rule of Acquisition #33:\n
+  It never hurts to suck up to the boss.\n
+    -- ST: DS9, \"Rule of Acquisition\", \"The Dogs of War\"",
+  "Ferengi Rule of Acquisition #34:\n
+  War is good for business.\n
+    -- ST: DS9, \"Destiny\"",
+  "Ferengi Rule of Acquisition #35:\n
+  Peace is good for business.\n
+    -- ST: DS9, \"The Perfect Mate\"; ST:TNG, \"Destiny\"",
+  "Ferengi Rule of Acquisition #40:\n
+    She can touch your lobes, but never your latinum.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #41:\n
+    Profit is its own reward.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #44:\n
+    Never confuse wisdom with luck.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #47:\n
+  Never trust a man wearing a better suit than your own.\n
+    -- ST: DS9, \"Rivals\"",
+  "Ferengi Rule of Acquisition #48:\n
+  The bigger the smile, the sharper the knife.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #52:\n
+    Never ask when you can take.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #57:\n
+  Good customers are as rare as latinum. Treasure them.\n
+    -- ST: DS9, \"Armageddon Game\"",
+  "Ferengi Rule of Acquisition #58:\n
+    There is no substitute for success.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #59:\n
+  Free advice is seldom cheap.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #60:\n
+    Keep your lies consistent.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #62:\n
+  The riskier the road, the greater the profit.\n
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #65:\n
+    Win or lose, there's always Hupyrian beetle snuff.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #75:\n
+  Home is where the heart is, but the stars are made of latinum.\n
+    -- ST: DS9, \"Civil Defense\"",
+  "Ferengi Rule of Acquisition #76:\n
+  Every once in a while, declare peace. It confuses the hell out of your enemies.\n
+    -- ST: DS9, \"The Homecoming\"",
+  "Ferengi Rule of Acquisition #79:\n
+    Beware of the Vulcan greed for knowledge.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #82:\n
+    The flimsier the product, the higher the price.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #85:\n
+    Never let the competition know what you're thinking.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #89:\n
+    Ask not what your profits can do for you, but what you can do for your profits.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #94:\n
+  Females and finances don't mix.\n
+    -- ST: DS9, \"Ferengi Love Songs\"",
+  "Ferengi Rule of Acquisition #97:\n
+    Enough ... is never enough.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #98:\n
+  Every man has his price.\n
+    -- ST: DS9, \"In the Pale Moonlight\"",
+  "Ferengi Rule of Acquisition #99:\n
+    Trust is the biggest liability of all.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #102:\n
+  Nature decays, but latinum lasts forever.\n
+    -- ST: DS9, \"The Jem'Hadar\"",
+  "Ferengi Rule of Acquisition #103:\n
+  Sleep can interfere with your lust for latinum.5
+    -- ST: DS9, \"Rule of Acquisition\"",
+  "Ferengi Rule of Acquisition #104:\n
+    Faith moves mountains ... of inventory.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #106:\n
+    There is no honor in poverty.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #109:\n
+  Dignity and an empty sack is worth the sack.\n
+    -- ST: DS9, \"Rivals\"",
+  "Ferengi Rule of Acquisition #111:\n
+  Treat people in your debt like family... exploit them.\n
+    -- ST: DS9, \"Past Tense, Part I\", \"The Darkness and the Light\"",
+  "Ferengi Rule of Acquisition #112:\n
+  Never have sex with the boss's sister.\n
+    -- ST: DS9, \"Playing God\"",
+  "Ferengi Rule of Acquisition #113:\n
+    Always have sex with the boss.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #121:\n
+    Everything is for sale, even friendship.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #123:\n
+    Even a blind man can recognize the glow of latinum.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #125:\n
+  You can't make a deal if you're dead.\n
+    -- ST: DS9, \"The Siege of AR-558\"",
+  "Ferengi Rule of Acquisition #139:\n
+  Wives serve, brothers inherit.\n
+    -- ST: DS9, \"Necessary Evil\"",
+  "Ferengi Rule of Acquisition #141:\n
+    Only fools pay retail.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #144:\n
+    There's nothing wrong with charity... as long as it winds up in your pocket.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #162:\n
+    Even in the worst of times, someone turns a profit.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #168:\n
+  Whisper your way to success.\n
+    -- ST: DS9, \"Treachery, Faith, and the Great River\"",
+  "Ferengi Rule of Acquisition #177:\n
+    Know your enemies... but do business with them always.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #181:\n
+    Not even dishonesty can tarnish the shine of profit.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #189:\n
+    Let others keep their reputation. You keep their latinum.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #190:\n
+  Hear all, trust nothing.\n
+    -- ST: DS9, \"Call to Arms\"",
+  "Ferengi Rule of Acquisition #192:\n
+    Never cheat a Klingon ... unless you can get away with it.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #194:\n
+  It's always good to know about new customers before they walk in your door.\n
+    -- ST: DS9, \"Whispers\"",
+  "Ferengi Rule of Acquisition #202:\n
+    The justification for profit is profit.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #203:\n
+  New customers are like razor-toothed gree worms. They can be succulent, but sometimes they bite back.\n
+    -- ST: DS9, \"Little Green Men\"",
+  "Ferengi Rule of Acquisition #208:\n
+  Sometimes the only thing more dangerous than the question is an answer.\n
+    -- ST: DS9, \"Ferengi Love Songs\"",
+  "Ferengi Rule of Acquisition #211:\n
+  Employees are the rungs on the ladder of success. Don't hesitate to step on them.\n
+    -- ST: DS9, \"Bar Association\"",
+  "Ferengi Rule of Acquisition #214:\n
+  Never begin a negotiation on an empty stomach.\n
+    -- ST: DS9, \"The Maquis, Part I\"",
+  "Ferengi Rule of Acquisition #217:\n
+  You can't free a fish from water.\n
+    -- ST: DS9, \"Past Tense, Part I\"",
+  "Ferengi Rule of Acquisition #218:\n
+    Always know what you're buying.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #223:\n
+    Beware the man who doesn't make time for oo-mox.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #229:\n
+  Latinum lasts longer than lust.\n
+    -- ST: DS9, \"Ferengi Love Songs\"",
+  "Ferengi Rule of Acquisition #236:\n
+    You can't buy fate.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #239:\n
+  Never be afraid to mislabel a product.\n
+    -- ST: DS9, \"Body Parts\"",
+  "Ferengi Rule of Acquisition #242:\n
+    More is good. All is better.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #255:\n
+    A wife is a luxury ... a smart accountant a necessity.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #261:\n
+    A wealthy man can afford anything except a conscience.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #266:\n
+    When in doubt, lie.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #263:\n
+  Never let doubt interfere with your lust for latinum.\n
+    -- ST: DS9, \"Bar Association\"",
+  "Ferengi Rule of Acquisition #284:\n
+    Deep down, everyone's a Ferengi.\n
+    -- ST: Legends of the Ferengi",
+  "Ferengi Rule of Acquisition #285:\n
+  No good deed ever goes unpunished.\n
+    -- ST: DS9, \"The Collaborator\""
+]
+
+module.exports = (robot) ->
+
+  words = ["ferengi rule", "money", "profit", "sale", "discount", "opportunity"]
+  regex = new RegExp('(?:^|\\s)(' + words.join('|') + ')(?:\\s|\\.|\\?|!|$)', 'i');
+
+  robot.hear regex, (msg) ->
+    if counter is 5
+      msg.send msg.random rules
+      counter = 0
+    else
+      counter += 1


Brought over some of the source specs

Brought over some of the source specs

error: pathspec 'test/from_port_source.spec.coffee' did not match any file(s) known to git

--- test/from_port_source.spec.coffee
+++ test/from_port_source.spec.coffee
@@ -0,0 +1,21 @@
+describe 'The specs from the ruby source project', ->
+  beforeEach ->
+    @cut = require '../src/htmldiff'
+
+  xit 'should diff text', ->
+    diff = @cut 'a word is here', 'a nother word is there'
+    (expect diff).equal 'a nother word " +
+      "is herethere'
+
+  xit "should insert a letter and a space", ->
+    diff = @cut 'a c', 'a b c'
+    (expect diff).equal "a b c"
+
+  xit "should remove a letter and a space", ->
+    diff = @cut 'a b c', 'a c'
+    diff.should == "a b c"
+
+  xit "should change a letter", ->
+    diff = @cut 'a b c', 'a d c'
+    (expect diff).equal "a b" +
+      "d c"


added a basic redirect code

added a basic redirect code

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Digipalvelutehdas/APIKA.git/'


fix typo for spawning test commands on unix

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rafalprzywarski/test-status.git/'


fix: text format cleanup

fix: text format cleanup

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/PatrickLerner/escrit.git/'


Enabled RTMP option for IE

Enabled RTMP option for IE

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/evercam/evercam-dashboard.git/'


initial commit for "coffeelint.coffee"

initial commit for "coffeelint.coffee"

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/iTonyYo/node-find-folder.git/'


Restore story functionality

Restore story functionality

--- app/assets/javascripts/backbone/models/chunk.js.coffee
+++ app/assets/javascripts/backbone/models/chunk.js.coffee
@@ -28,7 +28,7 @@
     chapterRules.get(@grammar)

   css_class: ->
-    extra = if $.trim(@word) == '' || $.trim(@word) == '
' then ' non-editable' else ''
+    extra = if $.trim(@correct()) == '' || $.trim(@correct()) == '
' then ' non-editable' else ''
     "edit-word#{extra}"

   toJSON: ->


online_notification: optimize height calculation

--- app/assets/javascripts/app/controllers/widget/online_notification.coffee
+++ app/assets/javascripts/app/controllers/widget/online_notification.coffee
@@ -136,14 +136,17 @@
     heightPopoverSpacer     = 22
     heightPopoverHeader     = @header.outerHeight(true)
     heightPopoverContent    = 0
-    @item.each -> heightPopoverContent += @clientHeight
-
-    if (heightPopoverHeader + heightPopoverContent + heightPopoverSpacer) > heightApp
-      heightPopoverContent = heightApp - heightPopoverHeader - heightPopoverSpacer
-      @container.addClass('is-overflowing')
-    else
-      @container.removeClass('is-overflowing')
-
+    isOverflowing           = false
+    @item.each ->
+      # accumulate height of items
+      heightPopoverContent += @clientHeight
+
+      if (heightPopoverHeader + heightPopoverContent + heightPopoverSpacer) > heightApp
+        heightPopoverContent = heightApp - heightPopoverHeader - heightPopoverSpacer
+        isOverflowing = true
+        return false # exit .each loop
+
+    @container.toggleClass('is-overflowing', isOverflowing)
     @content.css('height', heightPopoverContent)

   fetch: =>


Revert "Revert "Also copy JS files individually""

This reverts commit 3a99cc55f438aee2bf65e884297ac670f5ea2dc3.
Nah, it didnt.

--- config.coffee
+++ config.coffee
@@ -277,7 +277,7 @@
     if stat.isDirectory()
       dirStack.push(fullPath)
     else
-      if _.str.endsWith(file, '.coffee')
+      if _.str.endsWith(file, '.coffee') or _.str.endsWith(file, '.js')
         coffeeFiles.push(fullPath)
       else if _.str.endsWith(file, '.jade')
         jadeFiles.push(fullPath)


Initial commit

Initial commit

Helper of Proteome Query Language.
pQL®: An efficient Proteome Query Language.
BioQL®: An efficient Query Language for interpreting genome and proteome.
Author: Prabhat Kumar, http://prabhatkumar.org/.
Copyright: Sequømics Corporation, http://sequomics.com/.

error: pathspec 'src/pql/helper.coffee' did not match any file(s) known to git


Updated a test file

Updated a test file

error: pathspec 'dev/var/test-public/modules/config.coffee' did not match any file(s) known to git

--- dev/var/test-public/modules/config.coffee
+++ dev/var/test-public/modules/config.coffee
@@ -0,0 +1,11 @@
+'use strict'
+
+describe 'anConfig', ->
+    beforeEach: ->
+        module 'anConfig'
+        return
+
+    it 'Should be function', ->
+        expect(1).toEqual 1
+        return
+    return


Removed extra datetime conversion code

Removed extra datetime conversion code


Add indentation patterns

Add indentation patterns

--- settings/language-jison.cson
+++ settings/language-jison.cson
@@ -1,6 +1,15 @@
 ".source.jison, .source.jisonlex":
   editor:
     commentStart: "// "
+
+".rules.jison":
+  editor:
+    decreaseIndentPattern: "^"
+
+".rule.jison":
+  editor:
+    increaseIndentPattern: "\\b[[:alpha:]_](?:[\\w-]*\\w)?\\b"
+    decreaseIndentPattern: "(?!)"

 ".rule-components.jison":
   autocomplete:
@@ -16,3 +25,6 @@
           "EOF"
           "error"
         ]
+  editor:
+    increaseIndentPattern: ":|\\|"
+    decreaseIndentPattern: "\\||;"


renaming unsaved files handled by using askforsave flag

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


Hackathon: login improvements

Hackathon: login improvements

--- client/landing/site.hackathon/coffee/login/AppView.coffee
+++ client/landing/site.hackathon/coffee/login/AppView.coffee
@@ -307,6 +307,11 @@
       itemClass : KDCustomHTMLView
       partial   : email

+    handleKeyup = (event) ->
+
+      return  unless event.which is ENTER
+      modal.modalTabs.forms.extraInformation.submit event
+

     fields.username =
       name               : 'username'
@@ -320,12 +325,7 @@
         attributes       :
           testpath       : 'register-form-username'
         focus            : -> @unsetTooltip()
-        keyup            : (event) =>
-
-          return unless event.which is ENTER
-
-          modal.modalTabs.forms.extraInformation.submit event
-
+        keyup            : handleKeyup
         validate         :
           container      : this
           rules          :
@@ -355,11 +355,13 @@
       fields.firstName =
         defaultValue : givenName
         label        : 'First Name'
+        keyup        : handleKeyup

     if familyName
       fields.lastName =
         defaultValue : familyName
         label        : 'Last Name'
+        keyup        : handleKeyup

     modal = new KDModalViewWithForms


add fips data to response from lookup file (loaded and stored before request starts); simplify per-lookup work to add data beyond MaxMind's default response; misc cleanup after conversations

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/newsdev/geoip.git/'


_createCheckBox was implemented

_createCheckBox was implemented

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NightingaleStudio/exam.js.git/'


length validator

length validator

error: pathspec 'src/validators.coffee' did not match any file(s) known to git

--- src/validators.coffee
+++ src/validators.coffee
@@ -0,0 +1,31 @@
+
+
+class Validator
+  constructor: () ->
+    @msg = null
+
+  error_message: () ->
+    @msg
+
+class LengthValidator extends Validator
+  validate: (value, attributes) ->
+    max = attributes['max'] || Number.POSITIVE_INFINITY
+    min = attributes['min'] || Number.NEGATIVE_INFINITY
+    length  = attributes['length']
+    actual_length = value.length
+
+    if length
+      if actual_length == length
+        true
+      else
+        @msg = "Required length: #{length}, given: #{actual_length}"
+        false
+    else
+      if ((actual_length >= min) && (actual_length <= max))
+        true
+      else
+        @msg = "Required length in range [#{min}..#{max}], given: #{actual_length}"
+        false
+
+
+


improving some things

improving some things

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/guaka/wikifarmchanges.git/'


Add tests for SendGraphChanges

Add tests for SendGraphChanges

error: pathspec 'spec/SendGraphChanges.coffee' did not match any file(s) known to git

--- spec/SendGraphChanges.coffee
+++ spec/SendGraphChanges.coffee
@@ -0,0 +1,79 @@
+noflo = require 'noflo'
+chai = require 'chai' unless chai
+BaseRuntime = require '../node_modules/fbp-protocol-client/lib/base'
+path = require 'path'
+baseDir = path.resolve __dirname, '../'
+
+describe 'SendGraphChanges component', ->
+  component = null
+  graph = null
+  runtime = null
+  runtimeSocket = null
+  graphSocket = null
+  queuedSocket = null
+  sentSocket = null
+  errorSocket = null
+  loader = null
+
+  before ->
+    @timeout 4000
+    loader = new noflo.ComponentLoader baseDir
+  beforeEach (done) ->
+    loader.load 'runtime/SendGraphChanges', (err, instance) ->
+      return done err if err
+      component = instance
+      runtime = new BaseRuntime
+        capabilities: [
+          'protocol:graph'
+        ]
+
+      runtimeSocket = noflo.internalSocket.createSocket()
+      component.inPorts.runtime.attach runtimeSocket
+
+      graphSocket = noflo.internalSocket.createSocket()
+      component.inPorts.graph.attach graphSocket
+
+      queuedSocket = noflo.internalSocket.createSocket()
+      component.outPorts.queued.attach queuedSocket
+
+      sentSocket = noflo.internalSocket.createSocket()
+      component.outPorts.sent.attach sentSocket
+
+      errorSocket = noflo.internalSocket.createSocket()
+      component.outPorts.error.attach errorSocket
+
+      graph = new noflo.Graph 'hello'
+
+      done()
+
+  describe 'with a runtime and a graph', ->
+    beforeEach ->
+      runtimeSocket.send runtime
+      graphSocket.send graph
+
+    it 'should queue an addNode event', (done) ->
+      errorSocket.on 'data', (data) ->
+        done data
+      queuedSocket.on 'data', (data) ->
+        chai.expect(data).to.equal 1
+        done()
+      graph.addNode 'test', 'core/Split'
+    it 'should send queued events on endTransaction', (done) ->
+      queued = [
+        1
+        2
+        3
+        0
+      ]
+      errorSocket.on 'data', (data) ->
+        done data
+      queuedSocket.on 'data', (data) ->
+        chai.expect(data).to.equal queued.shift()
+      sentSocket.on 'data', ->
+        chai.expect(queued.length).to.equal 0
+        done()
+      graph.startTransaction 'foo'
+      graph.addNode 'sender', 'core/Split'
+      graph.addNode 'receiver', 'core/Split'
+      graph.addEdge 'sender', 'out', 'receiver', 'in'
+      graph.endTransaction 'foo'


Build: prepared loggedout entry coffee

Build: prepared loggedout entry coffee


Environment: Add collaboration session support to already joined a permanent vm machine.


newkite: fix reconnecting logic to kontrol

--- client/landing/app/MainApp/kite/newkite.coffee
+++ client/landing/app/MainApp/kite/newkite.coffee
@@ -45,17 +45,18 @@
     xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
     xhr.send JSON.stringify requestData
     xhr.onload = =>
-       if xhr.status is 200
-          data = JSON.parse xhr.responseText
-          @token = data[0].token
-          @addr = data[0].addr
+      if xhr.status is 200
+        data = JSON.parse xhr.responseText
+        @token = data[0].token
+        @addr = data[0].addr

-          # this should be optional
-          @connectDirectly() if connect
-        else
-          log "kontrol request error", xhr.responseText
-          # Make a request again if we could not get the addres, use backoff for that
-          KD.utils.defer => @setBackoffTimeout @bound "getKiteAddr"
+        # this should be optional
+        @connectDirectly() if connect
+      else
+        log "kontrol request error", xhr.responseText
+        # Make a request again if we could not get the addres, use backoff for that
+        KD.utils.defer => @setBackoffTimeout =>
+          @getKiteAddr true

   disconnect:(reconnect=true)->
     @autoReconnect = !!reconnect  if reconnect?


minor tweeks

minor tweeks

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtsagias/.dotfiles.git/'


it wasn't me

it wasn't me

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/talvdav/dotfiles.git/'


Removed brainstorming

Removed brainstorming

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/city41/bookends.git/'


bitbucket: "repo" means slug

bitbucket: "repo" means slug

My bad.

--- plugins/bitbucket-issues/index.coffee
+++ plugins/bitbucket-issues/index.coffee
@@ -6,7 +6,7 @@
   BASE_URL = "https://bitbucket.org"

   @issuesUrl: (config) ->
-    "#{BASE_URL}/api/1.0/repositories/#{config.username}/#{config.repo}/issues"
+    "#{BASE_URL}/api/1.0/repositories/#{config.repo}/issues"

   @issueUrl: (config, issueId) ->
     @issuesUrl(config) + "/" + issueId
@@ -41,6 +41,7 @@
       "kind": config.kind
       "priority": config.priority

+    console.log @issuesUrl(config)
     # Send the request
     @bitbucketRequest(@request.post(@issuesUrl(config)), config)
       .send(qs.stringify(query_object))
@@ -51,7 +52,7 @@

         callback null,
           id: res.body.local_id
-          url: url.resolve(BASE_URL, "#{config.username}/#{config.repo}/issue/#{res.body.local_id}")
+          url: url.resolve(BASE_URL, "#{config.repo}/issue/#{res.body.local_id}")

   @receiveEvent: (config, event, callback) ->
     if event?.trigger?.type == "reopened"


Convert TS.Friend class from prototypal inheritance to CoffeeScript class structure

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fbergin/timeline-stats.git/'


Clean up task-helpers.coffee

Clean up task-helpers.coffee

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/dkfiresky/electron-starter.git/'


clean console.logs in table.coffee

clean console.logs in table.coffee

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/pisaq/para.git/'


Add a comment explaining the .editor-colors class on .lines

--- src/lines-component.coffee
+++ src/lines-component.coffee
@@ -21,6 +21,8 @@
         width: scrollWidth
         WebkitTransform: "translate3d(#{-scrollLeft}px, #{-scrollTop}px, 0px)"

+    # The lines div must have the 'editor-colors' class so it has an opaque
+    # background to avoid sub-pixel anti-aliasing problems on the GPU
     div {className: 'lines editor-colors', style},
       HighlightsComponent({editor, highlightDecorations, lineHeightInPixels, defaultCharWidth}) if @isMounted()


missing RSS.coffee class

missing RSS.coffee class

error: pathspec 'src/models/data/RSS.coffee' did not match any file(s) known to git

--- src/models/data/RSS.coffee
+++ src/models/data/RSS.coffee
@@ -0,0 +1,8 @@
+class RSS
+  constructor: (@options={}) ->
+    @url = if options.constructor.name == "String"
+      options
+    else
+      options.url
+
+    throw "URL required" unless @url