Remove unnecessary 'return' statements

Remove unnecessary 'return' statements

--- client.coffee
+++ client.coffee
@@ -86,11 +86,8 @@
     else
       # opts.bootstrap is undefined or true
       @_bootstrap BOOTSTRAP_NODES
-    return
   @on 'ready', ->
     @_debug 'emit ready'
-    return
-  return

 ###*
 # Parse saved string
@@ -102,7 +99,6 @@
   nodes.forEach (node) ->
     if node.id
       node.id = idToBuffer(node.id)
-    return
   nodes

 ###*
@@ -150,7 +146,6 @@
   catch err
     debug 'error parsing peer info ' + list
     return []
-  return

 ###*
 # Ensure a transacation id is a 16-bit buffer, so it can be sent on the wire as
@@ -275,12 +270,10 @@
     address = undefined
   if onlistening
     @once 'listening', onlistening
-  if @_destroyed or @_binding or @listening
-    return
+  return if @_destroyed or @_binding or @listening
   @_binding = true
   @_debug 'listen %s', port
   @socket.bind port, address
-  return

 ###*
 # Called when DHT is listening for UDP messages.
@@ -292,7 +285,6 @@
   @_port = @socket.address().port
   @_debug 'emit listening %s', @_port
   @emit 'listening'
-  return

 DHT::address = ->
   @socket.address()
@@ -312,10 +304,8 @@
       return cb(err)
     closest.forEach (contact) =>
       @_sendAnnouncePeer contact.addr, infoHash, port, contact.token
-      return
     @_debug 'announce end %s %s', infoHash, port
     cb null
-    return

   if !cb

@@ -331,7 +321,6 @@
     onClosest null, table.closest({ id: infoHash }, K)
   else
     @lookup infoHash, onClosest
-  return

 ###*
 # Destroy and cleanup the DHT.
@@ -364,7 +353,6 @@
   catch err
     # ignore error, socket was either already closed / not yet bound
     cb null
-  return

 ###*
 # Add a DHT node to the routing table.
@@ -374,12 +362,10 @@
 ###

 DHT::addNode = (addr, nodeId, from) ->
-  if @_destroyed
-    return
+  return if @_destroyed
   nodeId = idToBuffer(nodeId)
-  if @_addrIsSelf(addr)
+  return if @_addrIsSelf(addr)
     # @_debug('skipping adding %s since that is us!', addr)
-    return
   contact =
     id: nodeId
     addr: addr
@@ -387,7 +373,6 @@
   # TODO: only emit this event for new nodes
   @emit 'node', addr, nodeId, from
   @_debug 'addNode %s %s discovered from %s', idToHexString(nodeId), addr, from
-  return

 ###*
 # Remove a DHT node from the routing table.
@@ -395,13 +380,11 @@
 ###

 DHT::removeNode = (nodeId) ->
-  if @_destroyed
-    return
+  return if @_destroyed
   contact = @nodes.get(idToBuffer(nodeId))
   if contact
     @_debug 'removeNode %s %s', contact.nodeId, contact.addr
     @nodes.remove contact
-  return

 ###*
 # Store a peer in the DHT. Called when a peer sends a `announce_peer` message.
@@ -410,8 +393,7 @@
 ###

 DHT::_addPeer = (addr, infoHash) ->
-  if @_destroyed
-    return
+  return if @_destroyed
   infoHash = idToHexString(infoHash)
   peers = @peers[infoHash]
   if !peers
@@ -423,7 +405,6 @@
     peers.list.push string2compact(addr)
     @_debug 'addPeer %s %s', addr, infoHash
     @emit 'announce', addr, infoHash
-  return

 ###*
 # Remove a peer from the DHT.
@@ -432,8 +413,7 @@
 ###

 DHT::removePeer = (addr, infoHash) ->
-  if @_destroyed
-    return
+  return if @_destroyed
   infoHash = idToHexString(infoHash)
   peers = @peers[infoHash]
   if peers and peers.index[addr]
@@ -445,8 +425,6 @@
         @_debug 'removePeer %s %s', addr, infoHash
         return true
         # abort early
-      return
-  return

 ###*
 # Join the DHT network. To join initially, connect to known nodes (either public
@@ -477,8 +455,6 @@
         if !@ready
           @ready = true
           @emit 'ready'
-        return
-      return

     if err
       return @emit('error', err)
@@ -487,7 +463,6 @@
       ! !contact.id
     ).forEach (contact) =>
       @addNode contact.addr, contact.id, contact.from
-      return
     # get addresses of bootstrap nodes
     addrs = contacts.filter((contact) ->
       !contact.id
@@ -497,17 +472,13 @@
     lookup()
     # TODO: keep retrying after one failure
     @_bootstrapTimeout = setTimeout((=>
-      if @_destroyed
-        return
+      return if @_destroyed
       # If 0 nodes are in the table after a timeout, retry with bootstrap nodes
       if @nodes.count() == 0
         @_debug 'No DHT bootstrap nodes replied, retry'
         lookup()
-      return
     ), BOOTSTRAP_TIMEOUT)
     @_bootstrapTimeout.unref and @_bootstrapTimeout.unref()
-    return
-  return

 ###*
 # Resolve the DNS for nodes whose hostname is a domain name (often the case for
@@ -528,8 +499,6 @@
             return cb(null, null)
           contact.addr = host + ':' + addrData[1]
           cb null, contact
-          return
-      return
   )
   parallel tasks, (err, contacts) ->
     if err
@@ -539,8 +508,6 @@
       ! !contact
     )
     done null, contacts
-    return
-  return

 ###*
 # Perform a recurive node lookup for the given nodeId. If isFindNode is true, then
@@ -555,12 +522,10 @@
 DHT::lookup = (id, opts, cb) ->

   add = (contact) =>
-    if @_addrIsSelf(contact.addr)
-      return
+    return if @_addrIsSelf(contact.addr)
     if contact.token
       tokenful.add contact
     table.add contact
-    return

   query = (addr) =>
     pending += 1
@@ -569,13 +534,10 @@
       @_sendFindNode addr, id, onResponse.bind(null, addr)
     else
       @_sendGetPeers addr, id, onResponse.bind(null, addr)
-    return

   queryClosest = =>
     @nodes.closest({ id: id }, K).forEach (contact) ->
       query contact.addr
-      return
-    return

   # Note: `_sendFindNode` and `_sendGetPeers` will insert newly discovered nodes into
   # the routing table, so that's not done here.
@@ -601,7 +563,6 @@
       if res and res.nodes
         res.nodes.forEach (contact) ->
           add contact
-          return
     # find closest unqueried nodes
     candidates = table.closest({ id: id }, K).filter((contact) ->
       !queried[contact.addr]
@@ -616,9 +577,7 @@
       @_debug 'K closest nodes are:'
       closest.forEach (contact) =>
         @_debug '  ' + contact.addr + ' ' + idToHexString(contact.id)
-        return
       cb null, closest
-    return

   id = idToBuffer(id)
   if typeof opts == 'function'
@@ -644,7 +603,6 @@
     peers.forEach (peerAddr) =>
       @_debug 'emit peer %s %s from %s', peerAddr, idHex, 'local'
       @emit 'peer', peerAddr, idHex, 'local'
-      return
   table = new KBucket(
     localNodeId: id
     numberOfNodesPerKBucket: K
@@ -665,7 +623,6 @@
   else
     # kick off lookup with nodes in the main table
     queryClosest()
-  return

 ###*
 # Called when another node sends a UDP message
@@ -685,13 +642,11 @@
     errMessage = err.message + ' from ' + addr + ' (' + data + ')'
     @_debug errMessage
     @emit 'warning', new Error(errMessage)
-    return
   type = message.y and message.y.toString()
   if type != MESSAGE_TYPE.QUERY and type != MESSAGE_TYPE.RESPONSE and type != MESSAGE_TYPE.ERROR
     errMessage = 'unknown message type ' + type + ' from ' + addr
     @_debug errMessage
     @emit 'warning', new Error(errMessage)
-    return
   # @_debug('got data %s from %s', JSON.stringify(message), addr)
   # Attempt to add every (valid) node that we see to the routing table.
   # TODO: If they node is already in the table, just update the "last heard from" time
@@ -704,7 +659,6 @@
     @_onQuery addr, message
   else if type == MESSAGE_TYPE.RESPONSE or type == MESSAGE_TYPE.ERROR
     @_onResponseOrError addr, type, message
-  return

 ###*
 # Called when another node sends a query.
@@ -720,7 +674,6 @@
     errMessage = 'unexpected query type'
     @_debug errMessage
     @_sendError addr, message.t, ERROR_TYPE.METHOD_UNKNOWN, errMessage
-  return

 ###*
 # Called when another node sends a response or error.
@@ -746,7 +699,6 @@
       @emit 'warning', new Error(errMessage)
     return
   transaction.cb err, message.r
-  return

 ###*
 # Send a UDP message to the given addr.
@@ -765,12 +717,10 @@
   addrData = addrToIPPort(addr)
   host = addrData[0]
   port = addrData[1]
-  if !(port > 0 and port < 65535)
-    return
+  return if !(port > 0 and port < 65535)
   # @_debug('send %s to %s', JSON.stringify(message), addr)
   message = bencode.encode(message)
   @socket.send message, 0, message.length, port, host, cb
-  return

 DHT::_query = (data, addr, cb) ->
   if !data.a
@@ -788,7 +738,6 @@
   else if data.q == 'get_peers'
     @_debug 'sent get_peers %s to %s', data.a.info_hash.toString('hex'), addr
   @_send addr, message
-  return

 ###*
 # Send "ping" query to given addr.
@@ -798,7 +747,6 @@

 DHT::_sendPing = (addr, cb) ->
   @_query { q: 'ping' }, addr, cb
-  return

 ###*
 # Called when another node sends a "ping" query.
@@ -813,7 +761,6 @@
     r: id: @nodeId
   @_debug 'got ping from %s', addr
   @_send addr, res
-  return

 ###*
 # Send "find_node" query to given addr.
@@ -836,12 +783,9 @@
       res.nodes = parseNodeInfo(res.nodes)
       res.nodes.forEach (node) =>
         @addNode node.addr, node.id, addr
-        return
     cb null, res
-    return

   @_query data, addr, onResponse
-  return

 ###*
 # Called when another node sends a "find_node" query.
@@ -855,7 +799,6 @@
     errMessage = '`find_node` missing required `a.target` field'
     @_debug errMessage
     @_sendError addr, message.t, ERROR_TYPE.PROTOCOL, errMessage
-    return
   @_debug 'got find_node %s from %s', idToHexString(nodeId), addr
   # Convert nodes to "compact node info" representation
   nodes = convertToNodeInfo(@nodes.closest({ id: nodeId }, K))
@@ -866,7 +809,6 @@
       id: @nodeId
       nodes: nodes
   @_send addr, res
-  return

 ###*
 # Send "get_peers" query to given addr.
@@ -884,15 +826,12 @@
       res.nodes = parseNodeInfo(res.nodes)
       res.nodes.forEach (node) =>
         @addNode node.addr, node.id, addr
-        return
     if res.values
       res.values = parsePeerInfo(res.values)
       res.values.forEach (peerAddr) =>
         @_debug 'emit peer %s %s from %s', peerAddr, infoHashHex, addr
         @emit 'peer', peerAddr, infoHashHex, addr
-        return
     cb null, res
-    return

   infoHash = idToBuffer(infoHash)
   infoHashHex = idToHexString(infoHash)
@@ -902,7 +841,6 @@
       id: @nodeId
       info_hash: infoHash
   @_query data, addr, onResponse
-  return

 ###*
 # Called when another node sends a "get_peers" query.
@@ -917,7 +855,6 @@
     errMessage = '`get_peers` missing required `a.info_hash` field'
     @_debug errMessage
     @_sendError addr, message.t, ERROR_TYPE.PROTOCOL, errMessage
-    return
   infoHashHex = idToHexString(infoHash)
   @_debug 'got get_peers %s from %s', infoHashHex, addr
   res =
@@ -936,7 +873,6 @@
     # info" representation
     res.r.nodes = convertToNodeInfo(@nodes.closest({ id: infoHash }, K))
   @_send addr, res
-  return

 ###*
 # Send "announce_peer" query to given host and port.
@@ -962,7 +898,6 @@
       token: token
       implied_port: 0
   @_query data, addr, cb
-  return

 ###*
 # Called when another node sends a "announce_peer" query.
@@ -978,12 +913,10 @@
     errMessage = '`announce_peer` missing required `a.info_hash` field'
     @_debug errMessage
     @_sendError addr, message.t, ERROR_TYPE.PROTOCOL, errMessage
-    return
   token = message.a and message.a.token
   if !@_isValidToken(token, addrData[0])
     errMessage = 'cannot `announce_peer` with bad token'
     @_sendError addr, message.t, ERROR_TYPE.PROTOCOL, errMessage
-    return
   port = if message.a.implied_port != 0 then addrData[1] else message.a.port
   # use port in `announce_peer` message
   @_debug 'got announce_peer %s %s from %s with token %s', idToHexString(infoHash), port, addr, idToHexString(token)
@@ -994,7 +927,6 @@
     y: MESSAGE_TYPE.RESPONSE
     r: id: @nodeId
   @_send addr, res
-  return

 ###*
 # Send an error to given host and port.
@@ -1017,7 +949,6 @@
     message.t = transactionId
   @_debug 'sent error %s to %s', JSON.stringify(message), addr
   @_send addr, message
-  return

 ###*
 # Get a transaction id, and (optionally) set a function to be called
@@ -1030,13 +961,11 @@
   onTimeout = ->
     reqs[transactionId] = null
     fn new Error('query timed out')
-    return

   onResponse = (err, res) ->
     clearTimeout reqs[transactionId].timeout
     reqs[transactionId] = null
     fn err, res
-    return

   fn = once(fn)
   reqs = @transactions[addr]
@@ -1101,7 +1030,6 @@
     return
   @secrets[1] = @secrets[0]
   @secrets[0] = createSecret()
-  return

 ###*
 # Get a string that can be used to initialize and bootstrap the DHT in the
@@ -1128,4 +1056,3 @@
   args = [].slice.call(arguments)
   args[0] = '[' + idToHexString(@nodeId).substring(0, 7) + '] ' + args[0]
   debug.apply null, args
-  return


Clear test datbase before and after tests are run.

--- test/globalConfig.coffee
+++ test/globalConfig.coffee
@@ -1 +1,21 @@
 require('source-map-support').install handleUncaughtExceptions: false
+mongoose = require 'mongoose'
+config = require "../config/test.json"
+
+dropTestDb = (done) ->
+  # ensure that we can only drop the test database
+  if config.mongo.url.indexOf('openhim-test') > -1
+    process.stdout.write 'Dropping test database...'
+    # drop test database when starting tests
+    mongoose.connect config.mongo.url, ->
+      mongoose.connection.db.dropDatabase (err, result) ->
+        throw err if err?
+        if result
+          console.log 'Success'
+        else
+          console.log 'Failed'
+        done()
+
+before (done) -> dropTestDb done
+
+after (done) -> dropTestDb done


"parâng" region

"parâng" region


reduce code duplication

reduce code duplication

--- src/game.coffee
+++ src/game.coffee
@@ -32,11 +32,12 @@
       casePosition = game.positionFromCoord @x, @y
       game.board.cases[casePosition].g.remove()
       if game.board.cases[casePosition].constructor is Flag
-        game.board.flagsLbl.attr text: "Flags: #{--game.flags}/#{game.nbMines}"
+        game.flags--
         game.board.cases[casePosition] = new Tile @ctx, @x, @y
       else
-        game.board.flagsLbl.attr text: "Flags: #{++game.flags}/#{game.nbMines}"
+        game.flags++
         game.board.cases[casePosition] = new Flag @ctx, @x, @y
+      game.board.flagsLbl.attr text: "Flags: #{game.flags}/#{game.nbMines}"
     else
       @showTile()


:video_camera::soon: Updated in browser at strd6.github.io/editor

--- pixie.cson
+++ pixie.cson
@@ -3,7 +3,7 @@
 remoteDependencies: [
   "//code.jquery.com/jquery-1.10.1.min.js"
   "//cdnjs.cloudflare.com/ajax/libs/coffee-script/1.6.3/coffee-script.min.js"
-  "http://strd6.github.io/tempest/javascripts/envweb-v0.4.5.js"
+  "http://strd6.github.io/tempest/javascripts/envweb-v0.4.6.js"
   "http://strd6.github.io/require/v0.2.2.js?"
 ]
 dependencies:


close popup when hash.success is false

close popup when hash.success is false

--- src/hull.coffee
+++ src/hull.coffee
@@ -68,7 +68,7 @@
     orgUrl = config.orgUrl.replace(/^http:/,'https:')
     orgOk = snippetOrgUrl == orgUrl

-    check  = snippet.check
+    check  = snippet.check

     window.location.hash=""
     if(orgOk && platformOk)
@@ -96,12 +96,14 @@

 parseHash = ()->
   return if window.location.href.match('//.+\.hullapp\.io/.+/remote.html') # prevent this when in remote.html
+
   hash = decodeHash()
-  if hash?.success && hash?.token
-    if window?.opener?.Hull? and window?.opener?.__hull_login_status__ and !!hash
+  if hash? && hash.hasOwnProperty('success')
+    window.location.hash = ''
+
+    if window?.opener?.Hull? and window?.opener?.__hull_login_status__
       window.opener.__hull_login_status__(hash)
       window.close()
-  window.location.hash = '' if hash && hash.hasOwnProperty('success')

 parseHash()


changing barcode default hint to default label

--- jsapp/xlform_model_view/model.configs.coffee
+++ jsapp/xlform_model_view/model.configs.coffee
@@ -117,7 +117,7 @@
       label:
         value: "Enter a number"
     barcode:
-      hint:
+      label:
         value: "Use the camera to scan a barcode"
     decimal:
       label:


Clean up flex-direction hack

Clean up flex-direction hack

--- lib/autoprefixer/hacks/flex-direction.coffee
+++ lib/autoprefixer/hacks/flex-direction.coffee
@@ -29,14 +29,11 @@
   prefixProp: (prefix) ->
     [spec, prefix] = @flexSpec(prefix)
     if spec == '2009'
-      @insertBefore(prefix + 'box-orient', if @value.indexOf('row') != -1
-        'horizontal'
-      else
-        'vertical')
-      @insertBefore(prefix + 'box-direction', if @value.indexOf('reverse') != -1
-        'reverse'
-      else
-        'normal')
+      orient = if @value.indexOf('row') != -1 then 'horizontal' else 'vertical'
+      @insertBefore(prefix + 'box-orient', orient)
+
+      dir = if @value.indexOf('reverse') != -1 then 'reverse' else 'normal'
+      @insertBefore(prefix + 'box-direction', dir)
     else
       super


capture view

capture view

--- client/landing/includes.coffee
+++ client/landing/includes.coffee
@@ -35,6 +35,7 @@

   # image
   "Framework/components/image/KDImage.coffee",
+  "Framework/components/image/KDPhotoCapture.coffee",

   # split
   "Framework/components/split/splitview.coffee",


Includes: Added new finder classes for workspace. Included workspace classes at the bottom because it requires other resources.

--- client/landing/includes.coffee
+++ client/landing/includes.coffee
@@ -231,29 +231,6 @@
   # INTRODUCTION TOOLTIP
   "app/CommonViews/introductiontooltip/introductiontooltip.coffee",
   "app/CommonViews/introductiontooltip/introductiontooltipcontroller.coffee",
-
-  # WORKSPACE
-  "app/CommonViews/workspace/panes/pane.coffee",
-  "app/CommonViews/workspace/panes/editorpane.coffee",
-  "app/CommonViews/workspace/panes/previewpane.coffee",
-  "app/CommonViews/workspace/panes/terminalpane.coffee",
-  "app/CommonViews/workspace/panes/videopane.coffee",
-  "app/CommonViews/workspace/panel/panel.coffee",
-  "app/CommonViews/workspace/workspace.coffee",
-
-  # COLLABORATIVE WORKSPACE
-  "libs/firebase/firebase.all.js",
-  "libs/codemirror/lib/codemirror.js",
-  "libs/codemirror/mode/javascript/javascript.js",
-  "libs/firebase/firepad.js",
-  "libs/firepad/firepad.css",
-  "libs/codemirror/lib/codemirror.css",
-  "app/CommonViews/workspace/panes/collaborativeterminalpane.coffee",
-  "app/CommonViews/workspace/panes/collaborativeclientterminalpane.coffee",
-  "app/CommonViews/workspace/panes/collaborativeeditorpane.coffee",
-  "app/CommonViews/workspace/panel/collaborativepanel.coffee",
-  "app/CommonViews/workspace/collaborativeworkspace.coffee",
-

   "app/CommonViews/ModalViewWithTerminal.coffee",

@@ -718,6 +695,33 @@

   # Virtualization CONTROLLER
   "app/MainApp/VirtualizationController.coffee",
+
+
+  # WORKSPACE
+  "app/CommonViews/workspace/panes/pane.coffee",
+  "app/CommonViews/workspace/panes/editorpane.coffee",
+  "app/CommonViews/workspace/panes/previewpane.coffee",
+  "app/CommonViews/workspace/panes/terminalpane.coffee",
+  "app/CommonViews/workspace/panes/videopane.coffee",
+  "app/CommonViews/workspace/panel/panel.coffee",
+  "app/CommonViews/workspace/workspace.coffee",
+
+  # COLLABORATIVE WORKSPACE
+  # i know it's a CommonView and should include at the top but it have to
+  # wait for NFinderTreeController etc., so included at the bottom
+  "libs/firebase/firebase.all.js",
+  "libs/codemirror/lib/codemirror.js",
+  "libs/codemirror/mode/javascript/javascript.js",
+  "libs/firebase/firepad.js",
+  "libs/firepad/firepad.css",
+  "libs/codemirror/lib/codemirror.css",
+  "app/CommonViews/workspace/panes/collaborativeterminalpane.coffee",
+  "app/CommonViews/workspace/panes/collaborativeclientterminalpane.coffee",
+  "app/CommonViews/workspace/panes/collaborativefinderpane.coffee",
+  "app/CommonViews/workspace/panes/collaborativeclientfinderpane.coffee",
+  "app/CommonViews/workspace/panes/collaborativeeditorpane.coffee",
+  "app/CommonViews/workspace/panel/collaborativepanel.coffee",
+  "app/CommonViews/workspace/collaborativeworkspace.coffee",

   # OLD PAGES
   # "app/MainApp/oldPages/pageHome.coffee",


New snippet php array

New snippet php array

--- snippets/php.cson
+++ snippets/php.cson
@@ -8,3 +8,9 @@
           $this->${2:request} = $${2:request};
       }
     """
+
+  'PHP snippets - array':
+    'prefix': 'php:array'
+    'body': """
+      ['${1:name}'=>'${2:value}']
+    """


Hopefully a fool-proof fix for the votes import.

--- jobs/import-votes.coffee
+++ jobs/import-votes.coffee
@@ -80,14 +80,13 @@

           client.VoteService.BasicHttpBinding_VoteFinder.GetVotes getVotesArgs, (err, result, raw) -> ifSuccessful err, callback, ->
             result.GetVotesResult.VoteListing?.forEach? (assemblyVoteSummary) ->
-              if typeof assemblyVoteSummary.Caption != 'string' || assemblyVoteSummary.Caption.toLowerCase() != "attendance"
-                getVoteArgs =
-                  VoteId: assemblyVoteSummary.VoteId
+              getVoteArgs =
+                VoteId: assemblyVoteSummary.VoteId

-                client.VoteService.BasicHttpBinding_VoteFinder.GetVote getVoteArgs, (err, result, raw) ->
-                  ifSuccessful err, callback, ->
-                    persistVote(session, result.GetVoteResult, db, callback)
-              else
-                persistVote(session, assemblyVoteSummary, db, callback)
+              client.VoteService.BasicHttpBinding_VoteFinder.GetVote getVoteArgs, (err, result, raw) ->
+                if err
+                  persistVote(session, assemblyVoteSummary, db, callback)
+                else
+                  persistVote(session, result.GetVoteResult, db, callback)

             callback()


Fix dates that are strings because... I don't even know.

--- jobs/import-votes.coffee
+++ jobs/import-votes.coffee
@@ -45,11 +45,15 @@
     voteName = memberVote.MemberVoted.toLowerCase()
     votesCast[voteName].push(memberVote.Member.Id)

+  # Sometimes the date in the data that comes downwire is a string and other times
+  # it is a proper date. Let's get things into a uniform format in our DB.
+  fixedDate = if typeof vote.Date == 'string' then new Date(vote.Date) else vote.Date
+
   mapVoteMemberIds session, votesCast, db, (votes) ->
     voteDetails =
       sessionId: session._id,
       voteNumber: Number(vote.Number),
-      dateTime: vote.Date,
+      dateTime: fixedDate,
       caption: vote.Caption,
       description: vote.Description,
       chamber: vote.Branch.toLowerCase(),


Fix https://github.com/poooi/poi/issues/236

--- views/env.coffee
+++ views/env.coffee
@@ -361,10 +361,12 @@
       when '/kcsapi/api_req_nyukyo/speedchange'
         shipId = _ndocks[postBody.api_ndock_id - 1]
         _ships[shipId].api_nowhp = _ships[shipId].api_maxhp
+        _ships[shipId].api_cond = Math.max(40, _ships[shipId].api_cond)
       when '/kcsapi/api_req_nyukyo/start'
         if postBody.api_highspeed == '1'
           shipId = parseInt postBody.api_ship_id
           _ships[shipId].api_nowhp = _ships[shipId].api_maxhp
+          _ships[shipId].api_cond = Math.max(40, _ships[shipId].api_cond)
       when '/kcsapi/api_req_practice/battle_result'
         window._teitokuLv = body.api_member_lv
       when '/kcsapi/api_req_sortie/battleresult'


Fix indentation in main.coffee

Fix indentation in main.coffee

--- src/main.coffee
+++ src/main.coffee
@@ -151,53 +151,53 @@
         setTimeout startup, 5000

     if !config.advertiseComponents?
-      config.advertiseComponents = []
+        config.advertiseComponents = []
     for index of config.advertiseComponents
-      componentConfig = {}
-      for key, value of config.xmpp
-        componentConfig[key] = value
-      componentConfig.jid = config.advertiseComponents[index]
-      componentConfig.reconnect = true
-      connection = new xmpp.Component(componentConfig)
-      connection.on "error", (e) ->
-          logger.error e
-      connection.on "stanza", (stanza) =>
-          # Just debug output:
-          logger.trace "<< Extra connection request: #{stanza.toString()}"
-          from = stanza.attrs.from
-
-          if stanza.name is 'iq' and stanza.attrs.type is 'get'
-              # IQ requests
-              if !stanza.children?
-                stanza.children = []
-              for i, child of stanza.children
-                if child.name is 'query'
-                  query = child
-              if !query?
-                  return
-              switch query.attrs.xmlns
-                when NS.DISCO_ITEMS
-                    reply = new xmpp.Element("iq",
-                        from: stanza.attrs.to
-                        to: stanza.attrs.from
-                        id: stanza.attrs.id or ""
-                        type: "result"
-                        xmlns: Connection.NS_STREAM).
-                        c('query', xmlns: NS.DISCO_ITEMS).
-                        c('item', jid: config.xmpp.jid, name: 'buddycloud-server')
-                when NS.DISCO_INFO
-                    reply = new xmpp.Element("iq",
-                        from: stanza.attrs.to
-                        to: stanza.attrs.from
-                        id: stanza.attrs.id or ""
-                        type: "result"
-                        xmlns: Connection.NS_STREAM).
-                        c('query', xmlns: NS.DISCO_INFO).
-                        c('feature', var: NS.DISCO_INFO).up().
-                        c('feature', var: NS.DISCO_ITEMS).up().
-                        c('feature', var: NS.REGISTER).up().
-                        c('identity', category:'pubsub', type:'service', name:'Buddycloud proxy domain')
-                else
+        componentConfig = {}
+        for key, value of config.xmpp
+            componentConfig[key] = value
+        componentConfig.jid = config.advertiseComponents[index]
+        componentConfig.reconnect = true
+        connection = new xmpp.Component(componentConfig)
+        connection.on "error", (e) ->
+            logger.error e
+        connection.on "stanza", (stanza) =>
+            # Just debug output:
+            logger.trace "<< Extra connection request: #{stanza.toString()}"
+            from = stanza.attrs.from
+
+            if stanza.name is 'iq' and stanza.attrs.type is 'get'
+                # IQ requests
+                if !stanza.children?
+                    stanza.children = []
+                for i, child of stanza.children
+                    if child.name is 'query'
+                        query = child
+                if !query?
                     return
-              logger.trace "<< Extra connection response: #{reply.root().toString()}"
-              connection.send reply
+                switch query.attrs.xmlns
+                    when NS.DISCO_ITEMS
+                        reply = new xmpp.Element("iq",
+                            from: stanza.attrs.to
+                            to: stanza.attrs.from
+                            id: stanza.attrs.id or ""
+                            type: "result"
+                            xmlns: Connection.NS_STREAM).
+                            c('query', xmlns: NS.DISCO_ITEMS).
+                            c('item', jid: config.xmpp.jid, name: 'buddycloud-server')
+                    when NS.DISCO_INFO
+                        reply = new xmpp.Element("iq",
+                            from: stanza.attrs.to
+                            to: stanza.attrs.from
+                            id: stanza.attrs.id or ""
+                            type: "result"
+                            xmlns: Connection.NS_STREAM).
+                            c('query', xmlns: NS.DISCO_INFO).
+                            c('feature', var: NS.DISCO_INFO).up().
+                            c('feature', var: NS.DISCO_ITEMS).up().
+                            c('feature', var: NS.REGISTER).up().
+                            c('identity', category:'pubsub', type:'service', name:'Buddycloud proxy domain')
+                    else
+                        return
+                logger.trace "<< Extra connection response: #{reply.root().toString()}"
+                connection.send reply


Run Cucumber via Cucumber.Cli, rather than /bin/.

--- src/dill.coffee
+++ src/dill.coffee
@@ -1,16 +1,17 @@
 moment = require 'moment'
 module.exports = (lib, eformatter) ->
   timeStart = new Date().getTime()
-  process.argv.push("--error_formatter=#{eformatter}") unless process.argv.filter(checkForErrorFormatter).length
-  process.argv.push "--require"
-  process.argv.push "#{lib}/support"
+  execOptions = process.argv or []
+  execOptions.push("--error_formatter=#{eformatter}") unless process.argv.filter(checkForErrorFormatter).length
+  execOptions.push "--require"
+  execOptions.push "#{lib}/support"

   require('./environment')()
-  require(require.resolve('cucumber').replace /lib\/cucumber\.js$/, 'bin/cucumber.js')

-  process.on 'exit', ->
+  cucumber = require 'cucumber'
+  cucumber.Cli(execOptions).run ->
     testTime = moment.duration(new Date().getTime() - timeStart)._data
     console.log "Duration " + "(" + testTime.minutes + "m:" + testTime.seconds + "s:" + testTime.milliseconds + "ms)"

 checkForErrorFormatter = (element) ->
-  return !element.indexOf('--error_formatter')
+  return !element.indexOf('--error_formatter')


prevent error in handling of link when it is a mailto

Former-commit-id: b53917a71065963544708486287ad746c8e157de [formerly 21bf1ef7be22e0ba43699098d872c66c0ab2754e] [formerly d0c1a8dc22f9c0262f707e8fd5ab6bef192a3768 [formerly 27590094c7a97c39c91347e0befbb17d133281b4]] [formerly 8ac3db66f2846025c0086361fb579e6e865f61d9 [formerly 04b538fc477658f6239c30f379445716c35d1e93] [formerly 9bef63e13f01033c6f5d036529eb66bc5ac1c51b [formerly 9bef63e13f01033c6f5d036529eb66bc5ac1c51b [formerly 78887d5722cf6bf83d3afb3d9f35b0bbb9989b47]]]]
Former-commit-id: 547e10a1eff13e78706850caf829e9b97c55f5e4 [formerly 51d3a15a88daf740bd6a1fe503fffcd150adbb2f] [formerly 50908162ab1e341099a96aad24ead0352e62ebca [formerly 8fd46c3f67dd51941be36d139e8928fc43a9fcea]]
Former-commit-id: af20c724c6320b07385c10105fdc66462328d6e2 [formerly c3f592083cbb652ee16ad2ab664ef259b4ebcef9]
Former-commit-id: 5b6f8135442cfc47ee4384207ca1fc6220204d50
Former-commit-id: 869c4baea95f8844f90ff2485b32032492025507

--- @client/browser_location.coffee
+++ @client/browser_location.coffee
@@ -57,13 +57,15 @@
                   # can easily check relative vs absolute url

         is_external_link = href.indexOf('//') > -1
+        is_mailto = href.toLowerCase().indexOf('mailto') > -1
+
         opened_in_new_tab = event.altKey ||
                              event.ctrlKey ||
                              event.metaKey ||
                              event.shiftKey

         # Allow shift+click for new tabs, etc.
-        if !is_external_link && !opened_in_new_tab
+        if !is_external_link && !opened_in_new_tab && !is_mailto
           event.preventDefault()
           loadPage href
           _onclick event


Only try to leave full screen on exit on macOS

Fixes #277

--- src/main.coffee
+++ src/main.coffee
@@ -364,15 +364,13 @@
     # Emitted when the window is about to close.
     # For OSX only hides the window if we're not force closing.
     mainWindow.on 'close', (ev) ->
-        if mainWindow.isFullScreen()
-            mainWindow.setFullScreen false
-
-        darwinHideOnly = process.platform == 'darwin' and not global.forceClose
-
-        if darwinHideOnly
-            ev.preventDefault()
-            mainWindow.hide()
-            return
+        if process.platform == 'darwin'
+            if mainWindow.isFullScreen()
+                mainWindow.setFullScreen false
+            if not global.forceClose
+                ev.preventDefault()
+                mainWindow.hide()
+                return

         mainWindow = null
         quit()


Run tests in default task.

Run tests in default task.

Unfortunately, run the tests last due to a grunt-jasmine-node bug.
See https://github.com/jasmine-contrib/grunt-jasmine-node/issues/19


Revert to using CoffeeScript plugin options: bare: true


compile to js and check if problem occurs while parsing coffe files

--- find-unused-vars.coffee
+++ find-unused-vars.coffee
@@ -2,6 +2,7 @@
 NodeType   = require './node-type'
 parseRegex = require './parse-regex'
 parse      = require('decaffeinate-parser').parse
+coffee     = require 'coffee-script'

 traverse = (node, func) ->
@@ -23,7 +24,16 @@
 analyzeCode = (code, path) ->

   ast = try parse code
-  catch e then console.log "Error occured parsing the file #{path}"
+  catch e
+    console.log "Error occured parsing the file #{path}"
+    code = try coffee.compile code
+    catch e
+      console.log 'Error occured while compiling to js...'
+      console.log 'Please run the same command with -r to see unused requires'
+    options =
+      loc : yes
+    ast = esprima.parse code, options
+
   variablesStats = {}

   assignDeclaration = (node) ->


Fixed the error handling in the broker.

Fixed the error handling in the broker.

--- src/broker.coffee
+++ src/broker.coffee
@@ -35,7 +35,7 @@

     @queue.push task, (error) =>
       if error?
-        @_routerTx envelopes, id: task.id, response: "failed", data: error.toString()
+        @_routerTx envelopes, id: task.id, response: "failed", data: error
       else
         @_dealerTx envelopes, payload
         @_routerTx envelopes, id: task.id, response: "submitted"
@@ -57,9 +57,9 @@

   _submitTasks: ->
     @store.keys (error, ids) =>
-      throw new Error(error) if error?
+      throw error if error?
       async.forEachSeries ids, @_submitTask, (error) ->
-        throw new Error(error) if error?
+        throw error if error?
         console.log "Pending tasks flushed"

   _submitTask: (id, callback) =>


Fix previous

Fix previous

--- src/bundle.coffee
+++ src/bundle.coffee
@@ -201,6 +201,7 @@
     for own filename, {code: src, canonicalName} of processed
       map.setSourceContent canonicalName, src

+  if build.sourceMap
     sourceMappingUrl =
       if build.output
         path.relative (path.dirname build.output), build.sourceMap


Allow partial animations on gradients, e.g. only the start color.

--- framer/Animation.coffee
+++ framer/Animation.coffee
@@ -278,7 +278,7 @@
 		for k, v of @_stateB
 			if Color.isColorObject(v) or Color.isColorObject(@_stateA[k])
 				@_valueUpdaters[k] = @_updateColorValue
-			else if LinearGradient.isLinearGradient(v)
+			else if LinearGradient.isLinearGradient(v) or LinearGradient.isLinearGradient(@_stateA[k])
 				@_valueUpdaters[k] = @_updateGradientValue
 			else
 				@_valueUpdaters[k] = @_updateNumberValue
@@ -294,7 +294,14 @@
 		@_target[key] = Color.mix(@_stateA[key], @_stateB[key], value, false, @options.colorModel)

 	_updateGradientValue: (key, value) =>
-		@_target[key] = LinearGradient.mix(@_stateA[key], @_stateB[key], value, @options.colorModel)
+		gradientA = LinearGradient._asPlainObject(@_stateA[key])
+		gradientB = LinearGradient._asPlainObject(@_stateB[key])
+		@_target[key] = LinearGradient.mix(
+			_.defaults(gradientA, gradientB)
+			_.defaults(gradientB, gradientA)
+			value
+			@options.colorModel
+		)

 	_currentState: ->
 		return _.pick(@layer, _.keys(@properties))
@@ -323,6 +330,8 @@
 				animatableProperties[k] = v
 			else if Color.isValidColorProperty(k, v)
 				animatableProperties[k] = new Color(v)
+			else if k is "gradient" and not _.isEmpty(LinearGradient._asPlainObject(v))
+				animatableProperties[k] = v

 		return animatableProperties


Nicer looking print

Nicer looking print


Added $destroy handler to cancel timer

Added $destroy handler to cancel timer

--- src/chosen.coffee
+++ src/chosen.coffee
@@ -94,15 +94,16 @@
       valuesExpr = match[7]

       scope.$watchCollection valuesExpr, (newVal, oldVal) ->
-      # Defer execution until DOM is loaded
-      $timeout(() ->
-        # There's no way to tell if the collection is a promise since $parse hides this from us, so just
-        # assume it is a promise if undefined, and show the loader
-        if angular.isUndefined(newVal)
-          startLoading()
-        else
-          removeEmptyMessage() if empty
-          stopLoading()
-          disableWithMessage() if isEmpty(newVal)
-      )
+        # Defer execution until DOM is loaded
+        timer = $timeout(->
+          if angular.isUndefined(newVal)
+            startLoading()
+          else
+            removeEmptyMessage() if empty
+            stopLoading()
+            disableWithMessage() if isEmpty(newVal)
+        )
+
+      scope.$on '$destroy', (event) ->
+        $timeout.cancel timer if timer?
 ]


Handle user_change

Handle user_change

--- src/client.coffee
+++ src/client.coffee
@@ -232,7 +232,7 @@
         else
           console.warn "Could not find channel/user "+message.channel+"/"+message.user+" for user_typing"

-      when "team_join"
+      when "team_join", "user_change"
         u = message.user
         @users[u.id] = new User @, u


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/color2.coffee
+++ src/color2.coffee
@@ -138,9 +138,9 @@
     grayscale: ->
       hsl = @toHsl()

-      g = hsl[2] * 255
-
-      return Color2(g.round(), g.round(), g.round())
+      g = (hsl[2] * 255).round()
+
+      return Color2(g, g, g)

     hue: (degrees) ->
       hsl = @toHsl()


Set ivars in constructor

Set ivars in constructor

--- src/config.coffee
+++ src/config.coffee
@@ -26,14 +26,11 @@
 class Config
   Emitter.includeInto(this)

-  defaultSettings: null
-  settings: null
-  configFileHasErrors: null
-
-  # Created during initialization, available as `global.config`
+  # Created during initialization, available as `atom.config`
   constructor: ({@configDirPath, @resourcePath}={}) ->
     @defaultSettings = {}
     @settings = {}
+    @configFileHasErrors = false
     @configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
     @configFilePath ?= path.join(@configDirPath, 'config.cson')


removing reference to jQuery

removing reference to jQuery

--- src/engine.coffee
+++ src/engine.coffee
@@ -261,4 +261,4 @@
     return self

   (exports ? this)["Engine"] = Engine
-)(jQuery)
+)()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/follow.coffee
+++ src/follow.coffee
@@ -1,4 +1,37 @@
+###*
+The Cooldown module provides a declarative way to manage cooldowns on
+GameObject's properties.

+

+# Health regeneration
+player = GameObject
+  health: 50
+
+player.cooldown "health",
+  target: 100
+
+player.update()
+

+
+

+# Shoot Timeout
+player = GameObject()
+
+player.cooldown "shootTimer"
+
+player.I.shootTimer = 10 # => Pew! Pew!
+
+player.I.update()
+
+player.I.shootTimer # => 9
+

+
+@name Cooldown
+@module
+@constructor
+@param {Object} I Instance variables
+@param {Core} self Reference to including object
+###
 Follow = (I={}, self) ->
   Object.reverseMerge I,
     followSpeed: 1


follow docs

follow docs

--- src/follow.coffee
+++ src/follow.coffee
@@ -3,7 +3,7 @@
 velocity so that it will approach another object.

-# follow relies on an object having a
+# follow relies on an object having a bounds m
 player = GameObject
   x: 50
   y: 50


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/follow.coffee
+++ src/follow.coffee
@@ -1,6 +1,6 @@
 ###*
 The Follow module provides a simple method to set an object's velocity
-so that it will ap
+so that it will approach

 # Health regeneration


Add Keymap::getKeyBindings

Add Keymap::getKeyBindings

--- src/keymap.coffee
+++ src/keymap.coffee
@@ -34,6 +34,12 @@
   destroy: ->
     for filePath, subscription of @watchSubscriptions
       subscription.off()
+
+  # Public: Get all current key bindings.
+  #
+  # Returns an {Array} of {KeyBinding}s.
+  getKeyBindings: ->
+    @keyBindings.slice()

   # Public: Add sets of key bindings grouped by CSS selector.
   #


Add deprecated ::keyBindingsForKeystrokesMatchingElement

--- src/keymap.coffee
+++ src/keymap.coffee
@@ -367,15 +367,20 @@
   keyBindingsForCommand: (command) ->
     @findKeyBindings({command})

+  # Deprecated: Use {::findKeyBindings} with the 'keystrokes' param.
+  keyBindingsForKeystroke: (keystroke) ->
+    @findKeyBindings({keystrokes: keystroke})
+
+  # Deprecated: Use {::findKeyBindings} with the 'target' param.
+  keyBindingsMatchingElement: (target) ->
+    @findKeyBindings({target: target[0] ? target})
+
   # Deprecated: Use {::findKeyBindings} with the 'command' and 'target'
   # params
   keyBindingsForCommandMatchingElement: (command, target) ->
     @findKeyBindings({command, target: target[0] ? target})

-  # Deprecated: Use {::findKeyBindings} with the 'target' param.
-  keyBindingsMatchingElement: (target) ->
-    @findKeyBindings({target: target[0] ? target})
-
-  # Deprecated: Use {::findKeyBindings} with the 'keystrokes' param.
-  keyBindingsForKeystroke: (keystroke) ->
-    @findKeyBindings({keystrokes: keystroke})
+  # Deprecated: Use {::findKeyBindings} with the 'keystrokes' and 'target'
+  # params
+  keyBindingsForKeystrokeMatchingElement: (keystrokes, target) ->
+    @findKeyBindings({keystrokes, target: target[0] ? target})


Add numbers support !NO TESTS!

Add numbers support !NO TESTS!

--- src/kidomi.coffee
+++ src/kidomi.coffee
@@ -55,6 +55,8 @@
         return document.createTextNode(obj)
     if obj instanceof Node
         return obj
+    if typeof obj == 'number'
+        return '' + obj
     null


regex should be case-insensitive

regex should be case-insensitive

--- example/interactions/index.coffee
+++ example/interactions/index.coffee
@@ -4,11 +4,11 @@
 unsure = require './unsure.coffee'

 module.exports = ->
-  if /cookie/.test @message
+  if /cookie/i.test @message
     cookie.apply @, arguments
-  else if (/sentient|skynet|robot/.test @message) or (/self/.test @message) and /aware/.test @message
+  else if /sentient|skynet|robot|self\s*aware/i.test @message
     sentient.apply @, arguments
-  else if /trixie/.test @message
+  else if /trixie/i.test @message
     trixie.apply @, arguments
   else
     unsure.apply @, arguments


Change ||/&& to or/and

Change ||/&& to or/and

--- backbone.tableview.coffee
+++ backbone.tableview.coffee
@@ -223,18 +223,18 @@
     refreshPagination: =>
         from = (@data.page - 1) * @data.size + 1
         to   = from + @collection.size() - 1
-        max  = @collection.count || -1
+        max  = @collection.count or -1
         if max < 0
             maxPage  = 1
             pageFrom = @data.page
             pageTo   = @data.page
             max = ""
         else
-            maxPage  = Math.ceil(max / @data.size) || 1
+            maxPage  = Math.ceil(max / @data.size) or 1
             pageFrom = _.max 1, @data.page - 2
             pageTo   = _.min maxPage, @data.page + 2
             max = " of " + max + " entries"
-        pages = ({number: i, active: (i == @data.page && "active") || ""} for i in _.range pageFrom, pageTo + 1)
+        pages = ({number: i, active: (i == @data.page and "active") or ""} for i in _.range pageFrom, pageTo + 1)
         $("#pagination-main", @$el).html @paginationTemplate
             from: from
             to: to
@@ -364,7 +364,7 @@
     initialize: ->
         super
         @options.options = _.map @options.options,
-            (option) => {name: @prettyName(option.name || option), value: option.value or option}
+            (option) => {name: @prettyName(option.name or option), value: option.value or option}

     update: (e) =>
         @setData @id, e.currentTarget.value


Only push the first argument to _gaq

Only push the first argument to _gaq

--- src/scripts/helpers/handlers/analytics.coffee
+++ src/scripts/helpers/handlers/analytics.coffee
@@ -27,7 +27,7 @@

     # Wrapper functions to add analytics events
     # ga: () -> window.ga?.apply(@, arguments) # analytics.js
-    gaq: () -> window._gaq?.push(arguments) # ga.js
+    gaq: () -> window._gaq?.push(arguments[0]) # ga.js

     # Send the current page to every analytics service
     send: () ->


:bug: Fix broken legacy line API

:bug: Fix broken legacy line API

--- lib/minimap-editor-view.coffee
+++ lib/minimap-editor-view.coffee
@@ -38,6 +38,11 @@
     actualRow = Math.floor(row)

     {top: row * @getLineHeight(), left: column}
+
+  # This prevent plugins that relies on these methods to break
+  addLineClass: ->
+  removeLineClass: ->
+  removeAllLineClasses: ->

   destroy: ->
     @unsubscribe()


add implementation of https://forums.zotero.org/discussion/3673/2/original-date-of-publication/ for #237

--- resource/translators/translator.coffee
+++ resource/translators/translator.coffee
@@ -208,7 +208,7 @@

       extra = []
       for line in @item.extra.split("\n")
-        m = /^\s*(LCCN|MR|Zbl|PMCID|PMID|arXiv|JSTOR|HDL|GoogleBooksID)\s*:\s*([\S]+)\s*$/i.exec(line)
+        m = /^\s*(:original-date|LCCN|MR|Zbl|PMCID|PMID|arXiv|JSTOR|HDL|GoogleBooksID)\s*:\s*([\S]+)\s*$/i.exec(line)
         name = m?[1].toLowerCase()
         Translator.log("fixed field #{name} = #{m[2]}") if name
         switch name
@@ -230,6 +230,8 @@
               fields.push({ name: 'eprint', value: m[2] })
             else
               fields.push({ name: 'googlebooks', value: m[2] })
+          when ':original-date'
+            fields.push({ name: 'origdate', value: data[2] })

           else extra.push(line)
       @item.extra = extra.join("\n")


refactor(macTooltip): Clear and not show tooltip with empty string. Make sure events propagate up the bubble

--- src/directives/tooltip.coffee
+++ src/directives/tooltip.coffee
@@ -32,7 +32,7 @@
       opts = util.extendAttributes "macTooltip", defaults, attrs

       showTip = (event) ->
-        return if disabled
+        return true if disabled or not text

         tip =
           if opts.inside then element else angular.element(document.body)
@@ -76,18 +76,21 @@
           tooltip.css key, value

         tooltip.addClass "visible"
+        return true

       removeTip = (event) ->
-        tooltip.removeClass "visible"
-        $timeout ->
-          tooltip.remove()
-        , 100, false
+        if tooltip?
+          tooltip.removeClass "visible"
+          $timeout ->
+            tooltip.remove()
+          , 100, false
+        return true

       toggle = (event) ->
         if tooltip? then removeTip(event) else showTip(event)

       attrs.$observe "macTooltip", (value) ->
-        if value? and value
+        if value?
           text = value

           unless enabled


Use nextOffset for next fetchNext if we have one

--- SingularityUI/app/collections/LogLines.coffee
+++ SingularityUI/app/collections/LogLines.coffee
@@ -15,6 +15,7 @@
     @timestampIndex = 0

     @grep = ''
+    @nextOffset = null

     # How much we request at a time (before growing it)
     baseRequestLength: 30000
@@ -91,7 +92,8 @@
     fetchNext: =>
         # console.log 'next'
         @fetch data:
-            offset: @getMaxOffset()
+            offset: @nextOffset or @getMaxOffset()
+        @nextOffset = null

     fetchFromStart: =>
         # console.log 'start'
@@ -125,6 +127,7 @@
         super

     parse: (result, options) =>
+        @nextOffset = result.nextOffset
         offset = result.offset
         whiteSpace = /^\s*$/


Reorg

Reorg

--- components/DetectTarget.coffee
+++ components/DetectTarget.coffee
@@ -28,16 +28,16 @@
           unless @detectTarget element
             passed = false
         if passed
-          @outPorts.pass.send data
           if @outPorts.target.isAttached()
             @outPorts.target.send data[Object.keys(data)[0].target]
+          @outPorts.pass.send data
         else
           @outPorts.fail.send data
         return
       if @detectTarget data[Object.keys(data)[0]]
-        @outPorts.pass.send data
         if @outPorts.target.isAttached()
           @outPorts.target.send data[Object.keys(data)[0].targe]
+        @outPorts.pass.send data
       else
         @outPorts.fail.send data
     @inPorts.in.on 'disconnect', =>


fixed user undefined bug

fixed user undefined bug

--- src/poll.coffee
+++ src/poll.coffee
@@ -93,10 +93,15 @@
 			optionString = ""
 			for index, option of options
 				text = option.text
-				numVotes = if option.users == undefined then 0 else option.users.length
-				users = option.users
-				@robot.logger.info "option: #{option} :: text: #{text} :: count: #{numVotes} :: users: #{users.join(", ")}"
-				optionString += "\t#{index}: #{text} Total: #{numVotes} Users:(#{users.join(", ")})\n"
+				userString = ""
+				numVotes = 0
+				if option.users != undefined
+					option.users.length
+					numVotes = option.users.length
+					users = option.users
+					userString = "Users:(#{users.join(", ")})"
+				@robot.logger.info "option: #{option} :: text: #{text} :: count: #{numVotes} :: users: userString"
+				optionString += "\t#{index}: #{text} Total: #{numVotes} #{userString}\n"
 			msg.send """
 			#{topic}
 			Current Poll Results:


Add all tools in toolbar for froala editor

--- app/assets/javascripts/admin/froala_editor.coffee
+++ app/assets/javascripts/admin/froala_editor.coffee
@@ -1,26 +1,32 @@
 #= require froala_editor.min.js
+#= require plugins/block_styles.min.js
+#= require plugins/colors.min.js
+#= require plugins/media_manager.min.js
+#= require plugins/tables.min.js
+#= require plugins/video.min.js
+#= require plugins/font_family.min.js
+#= require plugins/font_size.min.js
+#= require plugins/file_upload.min.js
 #= require plugins/lists.min.js
 #= require plugins/char_counter.min.js
+#= require plugins/fullscreen.min.js
+#= require plugins/urls.min.js
+#= require plugins/inline_styles.min.js
 #= require langs/fr.js

 $ ->
   if $('.froala').length
     froala_init()

-  $('.button.has_many_add').on 'click', (e) ->
-    setTimeout (->
-      froala_init()
-      return
-    ), 150
-
 froala_init = ->
   $('.froala').editable
     inlineMode: false
     placeholder: 'Contenu de l\'article ici :)'
-    theme: 'royal',
+    theme: 'gray',
     plainPaste: true
     toolbarFixed: false
     tabSpaces: true
-    buttons: ['undo', 'redo' , 'sep', 'bold', 'italic', 'underline', 'createLink', 'blockStyle', 'indent', 'outdent', 'align', 'insertOrderedList', 'insertUnorderedList', 'html']
+    # buttons: ['undo', 'redo' , 'sep', 'bold', 'italic', 'underline', 'createLink', 'blockStyle', 'indent', 'outdent', 'align', 'insertOrderedList', 'insertUnorderedList', 'html']
     language: 'fr'
-    minHeight: 300+    minHeight: 300
+    colorsStep: 6


spree_backend as dependency for js

spree_backend as dependency for js

--- app/assets/javascripts/admin/spree_blog.js.coffee
+++ app/assets/javascripts/admin/spree_blog.js.coffee
@@ -1,5 +1,5 @@
+#= require admin/spree_backend
 $ ->
-  'use strict'
   if $('#post_related_post_ids').length > 0
     $('#post_related_post_ids').select2
       placeholder: 'Related Posts'


Ignore URL-messages in the markov model

Ignore URL-messages in the markov model

--- src/markov.coffee
+++ src/markov.coffee
@@ -75,6 +75,9 @@

     # Return on empty messages
     return if !msg.message.text
+    # Return if message has url
+    return if msg.message.text.match /http:\/\//
+    return if msg.message.text.match /https:\/\//

     model.learn msg.message.text
     remodel.learn rephrase msg.message.text if remodel
@@ -89,6 +92,19 @@
   robot.respond /markov(\s+(.+))?$/i, (msg) ->
     model.generate msg.match[2] or '', max, (text) =>
       msg.send text
+
+  # Remove http and https links from model database
+  robot.respond /markov-removehttpkeys/, (msg) ->
+    client.keys "markov:*", (err, keys) ->
+      for key in keys
+
+        if String(key).match(/http:\/\//)
+          client.del(key)
+          console.log(key)
+        if String(key).match(/https:\/\//)
+          client.del(key)
+          console.log(key)
+    msg.send "HTTP removed from markov"

   if restorage
     # Generate reverse markov chains on demand, optionally seeded by some end state


Hotfix .filter-form__switch visibility

Hotfix .filter-form__switch visibility

--- app/assets/javascripts/modules/filter_form.coffee
+++ app/assets/javascripts/modules/filter_form.coffee
@@ -109,7 +109,7 @@

     label = I18n.t 'js.mobile_filter'

-    unless $('.filter-form__switch').length
+    if !$('.filter-form__switch').length  &&  ($(window).width() <= 440)
       $('.template--offers-index').find('.content-main').prepend(
         $('<button class="filter-form__switch" aria-expanded="false">' +
           label + '</button>')


fix buildSettings()

fix buildSettings()

--- app/assets/javascripts/uploadcare/utils.js.coffee
+++ app/assets/javascripts/uploadcare/utils.js.coffee
@@ -68,6 +68,9 @@
       upscale: false
       preferedSize: null
     }
+
+    if settings.multiple
+      settings.crop = 'disabled'

     # disabled 300x200 → disabled
     # 300x200 3:2 → 3:2


Composition doesn't need the config

Composition doesn't need the config

--- src/trix/controllers/editor_controller.coffee
+++ src/trix/controllers/editor_controller.coffee
@@ -18,7 +18,7 @@
     @textController = new Trix.TextController @textElement, @text, @config
     @textController.delegate = this

-    @composition = new Trix.Composition @text, @config
+    @composition = new Trix.Composition @text
     @composition.delegate = this
     @composition.selectionDelegate = @textController


RPC refactoring

RPC refactoring

--- app/coffee/modules/packages/comm/rpc/index.coffee
+++ app/coffee/modules/packages/comm/rpc/index.coffee
@@ -1,9 +1,21 @@
+
+exports.$appRun = [
+	'$window', 'comm/rpc'
+	($window, rpc) ->
+
+		# Hang up the socket unless it's the local (Node.js) client.
+		# TODO do this through config, from server-side
+		unless $window.navigator.userAgent.match /^Node\.js .*$/
+			rpc.call 'hangup'
+]

 exports.$service = [
-	'$q', '$window', 'require', 'comm/socket'
-	($q, $window, require, socket) ->
+	'$q', 'require', 'comm/socket'
+	($q, require, socket) ->

-		@call = (route, data) ->
+		service = {}
+
+		service.call = (route, data) ->

 			deferred = $q.defer()

@@ -16,10 +28,6 @@

 			deferred.promise

-		# Hang up the socket unless it's the local (Node.js) client.
-		# TODO do this through config, from server-side
-		@call 'hangup' unless $window.navigator.userAgent.match /^Node\.js .*$/
-
-		return
+		service

 ]


2:1 ratio for DECaLS:Illustris

2:1 ratio for DECaLS:Illustris

--- app/models/subject.coffee
+++ app/models/subject.coffee
@@ -59,7 +59,7 @@

   @randomSurveyId: ->
     n = Math.random()
-    if n <= 0.5
+    if n <= (2/3)
       @::surveys.decals.id
     else
       @::surveys.illustris.id


Extend unit tests for RankingUtils. 1. Add additional tests for `RankingUtils.matches()`. 2. Add tests for `RankingUtils.wordRelevancy()`.

--- tests/unit_tests/completion_test.coffee
+++ tests/unit_tests/completion_test.coffee
@@ -153,8 +153,19 @@

 context "RankingUtils",
   should "do a case insensitive match", ->
-    assert.isTrue RankingUtils.matches(["maRiO"], "MARIO", "MARIo")
+    assert.isTrue RankingUtils.matches(["aRi"], "MARIO", "MARio")

+  should "do a case insensitive match on full term", ->
+    assert.isTrue RankingUtils.matches(["MaRiO"], "MARIO", "MARio")
+
+  should "do a case insensitive match on more than just two terms", ->
+    assert.isTrue RankingUtils.matches(["aRi"], "DOES_NOT_MATCH", "DOES_NOT_MATCH_EITHER", "MARio")
+
+  should "do case insensitive word relevancy (matching)", ->
+    assert.isTrue RankingUtils.wordRelevancy(["aRi"], "MARIO", "MARio") > 0.0
+
+  should "do case insensitive word relevancy (not matching)", ->
+    assert.isTrue RankingUtils.wordRelevancy(["DOES_NOT_MATCH"], "MARIO", "MARio") == 0.0

 # A convenience wrapper around completer.filter() so it can be called synchronously in tests.
 filterCompleter = (completer, queryTerms) ->


line graphs

line graphs

--- app/views/js/views.coffee
+++ app/views/js/views.coffee
@@ -1,20 +1,35 @@
 Kearny.DataView = Backbone.View.extend
   defaultScale: 'day'
+  defaultFormat: 'area'
   height: 400
   width: 600
   xPadding: 40
   yPadding: 20
+  yAxisVisible: false

   initialize: ->
-    @listenTo(@model, 'change', @render)
+    @listenTo(@model, 'change:data', @render)
+    @listenTo(@model, 'change:format', @renderGraph)
     @listenTo(@model, 'destroy', @remove)

   className: 'dataView'

   events:
-    'dblclick' : 'open'
+    'dblclick' : 'fetchData'
+    'click'    : 'cycleFormat'

-  open: -> @$el.addClass 'active'
+  fetchData: -> @model.fetchData()
+
+  getFormat: -> @model.get('format') || @defaultFormat
+  cycleFormat: ->
+    formats = _.keys(@generators)
+    nextFormat = @getFormat()
+
+    while (nextFormat == @getFormat())
+      nextFormat = formats[Math.floor(Math.random() * formats.length)]
+
+    @model.set('format', nextFormat)
+

   template: _.template($('#dataview-template').html())

@@ -39,9 +54,12 @@
     @yScale = d3.scale.linear().domain @model.yDomain()

     @svg ?= d3.select(@$el[0]).append('svg')
-    @yAxisMarker = @svg.append('g')
-        .attr('class', 'y axis')
-        .attr('transform', "translate(#{@xPadding}, 0)")
+    if @yAxisVisible
+      @yAxisMarker = @svg.append('g')
+          .attr('class', 'y axis')
+          .attr('transform', "translate(#{@xPadding}, 0)")
+    else
+      @xPadding = 0

     @xAxisMarker = @svg.append('g')
         .attr('class', 'x axis')
@@ -60,50 +78,71 @@
     @xScale.range([@xPadding, @width - @xPadding])
     @yScale.range([@height - @yPadding, @yPadding])

-    yAxis = d3.svg.axis().scale(@yScale)
-                  .orient('left')
-                  .ticks(4)
-
     xAxis = d3.svg.axis().scale(@xScale)
                   .ticks(3)

     @xAxisMarker
         .attr('transform', "translate(0, #{@height - @yPadding})")
         .call(xAxis)
-    @yAxisMarker.call(yAxis)
+
+    if @yAxisVisible
+      yAxis = d3.svg.axis().scale(@yScale)
+                    .orient('left')
+                    .ticks(4)
+      @yAxisMarker.call(yAxis)

     verticalPadding  = @$el.innerHeight() - @$el.height()
     horizontalPadding = @$el.innerWidth()  - @$el.width()

+  stylers:
+    area: (el) ->
+       z = d3.scale.category20c()
+       el.attr('fill', (_, i) -> z(Kearny.colorCounter))
+         .attr('stroke', 'none')
+    line: (el) ->
+      z = d3.scale.category20c()
+      el.attr('fill', 'none')
+        .attr('stroke', (_, i) -> z(Kearny.colorCounter))
+        .attr('stroke-width', 2)
+
+  generators:
+    area: ->
+      d3.svg.area()
+            .interpolate('basis')
+            .x((d) => @xScale(d[1] * 1000))
+            .y1((d) => @yScale(d[0]))
+            .y0(@height - @yPadding)
+
+    line: ->
+      d3.svg.line()
+            .interpolate('basis')
+            .x((d) => @xScale(d[1] * 1000))
+            .y((d) => @yScale(d[0]))
+
   renderGraph: ->
     @setupGraph() unless @svg
     @resize()
+    lineFunction = _.bind(@generators[@getFormat()], this)()

-    z = d3.scale.category20c()
     Kearny.colorCounter ?= 0
     Kearny.colorCounter += 1
+    data = @model.get('data')

-    area = d3.svg.area()
-             .interpolate('basis')
-             .x((d) => @xScale(d[1] * 1000))
-             .y1((d) => @yScale(d[0]))
-             .y0(@height - @yPadding)
+    el = @svg.selectAll('path')
+             .data(data, (d) -> d.target)
+             .attr('d', (d) -> lineFunction(d.datapoints))
+    el.enter()
+      .append('path').transition()
+      .attr('d', (d) -> lineFunction(d.datapoints))

-    @svg.selectAll('path')
-         .data(@model.get('data'), (d) -> d.target)
-         .attr('d', (d) -> area(d.datapoints))
-         .enter()
-           .append('path').transition()
-           .attr('d', (d) -> area(d.datapoints))
-           .attr('fill', (_, i) -> z(i + Kearny.colorCounter))
+    @stylers[@getFormat()](el)

     @$el.addClass('has-content')

 Kearny.AppView = Backbone.View.extend
   el: '#kearny-main'
-  gutters: 40
-  minWidth: 300
-  maxWidth: 500
+  gutters: 20
+  maxWidth: 400

   initialize: ->
     @dashboard = new Kearny.Dashboard(name: 'default')
@@ -137,7 +176,7 @@

   resizeAll: (render) ->
     viewportWidth = @$el.width()
-    horizontalCount = Math.floor(viewportWidth / @minWidth)
+    horizontalCount = Math.floor(viewportWidth / @maxWidth)
     newWidth = Math.floor((viewportWidth / horizontalCount) -
                           (@gutters * horizontalCount))


removed final dependencies on jQuery and async

--- src/math3d.coffee
+++ src/math3d.coffee
@@ -49,7 +49,7 @@
             "(opts=#{trunc JSON.stringify opts}, base=#{trunc JSON.stringify base})"
         catch
             ""
-    if typeof(opts) isnt 'object'
+    if typeof opts isnt 'object'
         # We put explicit traces before the errors in this function,
         # since otherwise they can be very hard to debug.
         console.trace()
@@ -357,7 +357,7 @@
         if @_center?
             @controls.target = @_center
         if @opts.spin
-            if typeof(@opts.spin) is "boolean"
+            if typeof @opts.spin is "boolean"
                 @controls.autoRotateSpeed = 2.0
             else
                 @controls.autoRotateSpeed = @opts.spin
@@ -881,46 +881,49 @@
     opts = defaults opts,
         scene    : required    # {opts:?, obj:?} or url from which to download (via ajax) a JSON string that parses to {opts:?,obj:?}
         element  : required    # DOM element to attach to
+        timeout  : 30000       # milleseconds for timing out fetchs
         callback : undefined   # callback(error, scene object)
     # Render a 3-d scene
     #console.log("render_3d_scene: url='#{opts.url}'")

-    scene_obj = undefined
-    async.series([
-        (callback) ->
-            switch typeof(opts.scene)
-                when 'string'
-                    $.ajax(
-                        url     : opts.scene
-                        timeout : 30000
-                        success : (data) ->
-                            try
-                                opts.scene = JSON.parse data
-                                callback()
-                            catch error
-                                callback error
-                    ).fail ->
-                        callback "error downloading #{opts.scene}"
-                when 'object'
-                    callback()
-                else
-                    callback "bad scene value: #{opts.scene}"
-        (callback) ->
-            # do this initialization *after* we create the 3d renderer
-            init = (error, scene) ->
-                if error
-                    callback error
-                else
-                    scene_obj = scene
+    create_scene = ->
+        if opts.scene.opts?.callback? and opts.callback?
+            orig = opts.scene.opts.callback
+            opts.scene.opts.callback = (error, scene) ->
+                orig error, scene
+                opts.callback error, scene
+        else
+            opts.scene.opts ?= {}
+            opts.scene.opts.callback = (error, scene) ->
+                if not error
                     scene.init()
                     if opts.scene.obj?
                         scene.add_3dgraphics_obj obj : opts.scene.obj
                     scene.init_done()
-                    callback()
-            # create the 3d renderer
-            opts.scene.opts.callback = init
-
+                opts.callback? error, scene
+        new Math3dThreeJS opts.element, opts.scene.opts
+
+    switch typeof opts.scene
+        when 'object'
+            create_scene()
+        when 'string'
+            xhr = new XMLHttpRequest()
+
+            xhr.onload = ->
+                try
+                    opts.scene = JSON.parse xhr.responseText
+                catch error
+                    opts.callback? error
+                create_scene()
+            xhr.onerror = ->
+                opts.callback? "error downloading #{opts.scene}"
+            xhr.ontimeout = ->
+                opts.callback? "downloading scene timed out"
+
+            xhr.timeout = opts.timeout
+
+            xhr.open 'get', opts.scene
+            xhr.send()
+        else
+            opts.callback? "bad scene type #{typeof opts.scene}"
             obj = new Math3dThreeJS opts.element, opts.scene.opts
-    ], (error) ->
-        opts.callback? error, scene_obj
-    )


remove dead functions

remove dead functions

--- src/math3d.coffee
+++ src/math3d.coffee
@@ -77,12 +77,6 @@
 # WARNING -- don't accidentally use this as a default:
 required = defaults.required = "__!!!!!!this is a required property!!!!!!__"

-rescale_to_hex = (val) ->
-    val = Math.round 255*val
-    (if val < 16 then "0" else "") + val.toString 16
-
-rgb_to_hex = (rgb) -> '#'+rgb.map(rescale_to_hex).join('')
-
 removeElement = (element) ->
     if element? and (parent = element.parentElement)?
         parent.removeChild element


"\n" is not a valid idris char

"\n" is not a valid idris char

--- grammars/language-idris.cson
+++ grammars/language-idris.cson
@@ -85,6 +85,10 @@
           name: 'punctuation.definition.string.end.idris'
       patterns:
         [
+          {
+            name: 'invalid.illegal.idris'
+            match: "\\\\n"
+          }
           {
             include: '#escape_characters'
           }


feat: fixed GOPATH

feat: fixed GOPATH


ImageQuestionAnswer: js extract $annotation_field


Improve unit formatting in specs table

Improve unit formatting in specs table

Improves formatting of units which have a "/" which don't have an
explicit formatter in Metric.


Remove "watch:haml" task from "watch" task

--- gulp/tasks/watch.coffee
+++ gulp/tasks/watch.coffee
@@ -7,7 +7,6 @@
     "babel"
     "coffee"
     "scss"
-    "haml"
   ].forEach((name) ->
     gulp.start("watch:#{name}")
   )


Remove target subs line from subs dashboard

--- app/views/admin/AnalyticsSubscriptionsView.coffee
+++ app/views/admin/AnalyticsSubscriptionsView.coffee
@@ -10,7 +10,6 @@
 module.exports = class AnalyticsSubscriptionsView extends RootView
   id: 'admin-analytics-subscriptions-view'
   template: template
-  targetSubCount: 1200

   events:
     'click .btn-show-more-cancellations': 'onClickShowMoreCancellations'
@@ -377,7 +376,6 @@
     # TODO: Where should this metadata live?
     # TODO: lineIDs assumed to be unique across graphs
     totalSubsID = 'total-subs'
-    targetSubsID = 'target-subs'
     startedSubsID = 'started-subs'
     cancelledSubsID = 'cancelled-subs'
     netSubsID = 'net-subs'
@@ -387,11 +385,6 @@
       description: 'Total Active Subscriptions'
       color: 'green'
       strokeWidth: 1
-    lineMetadata[targetSubsID] =
-      description: 'Target Total Subscriptions'
-      color: 'gold'
-      strokeWidth: 4
-      opacity: 1.0
     lineMetadata[startedSubsID] =
       description: 'New Subscriptions'
       color: 'blue'
@@ -454,7 +447,7 @@
       lineColor: lineMetadata[totalSubsID].color
       strokeWidth: lineMetadata[totalSubsID].strokeWidth
       min: 0
-      max: Math.max(@targetSubCount, d3.max(@subs, (d) -> d.total))
+      max: d3.max(@subs, (d) -> d.total)

     ## Started

@@ -536,30 +529,6 @@
         max: d3.max(@subs[-timeframeDays..], (d) -> d.started + 2)

     else
-
-      ## Total subs target
-
-      # Build line data
-      levelPoints = []
-      for sub, i in @subs
-        levelPoints.push
-          x: i
-          y: @targetSubCount
-          day: sub.day
-          pointID: "#{targetSubsID}#{i}"
-          values: []
-
-      levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
-
-      graph.lines.push
-        lineID: targetSubsID
-        enabled: true
-        points: levelPoints
-        description: lineMetadata[targetSubsID].description
-        lineColor: lineMetadata[targetSubsID].color
-        strokeWidth: lineMetadata[targetSubsID].strokeWidth
-        min: 0
-        max: Math.max(@targetSubCount, d3.max(@subs, (d) -> d.total))

       ## Cancelled


Add test rangeFromLineNumber with wrong colStart

--- spec/helper-spec.coffee
+++ spec/helper-spec.coffee
@@ -97,6 +97,13 @@
           expect(range[0][1]).toEqual(4)
           expect(range[1][0]).toEqual(1)
           expect(range[1][1]).toEqual(40)
+    it 'cries when colStart is greater than line length', ->
+      waitsForPromise ->
+        atom.workspace.open("#{__dirname}/fixtures/something.js").then ->
+          textEditor = atom.workspace.getActiveTextEditor()
+          expect ->
+            helpers.rangeFromLineNumber(textEditor, 1, 50)
+          .toThrow()

   describe '::parse', ->
     it 'cries when no argument is passed', ->


extractLink always returns a node

extractLink always returns a node

--- lib/assets/javascripts/turbolinks.js.coffee
+++ lib/assets/javascripts/turbolinks.js.coffee
@@ -165,7 +165,7 @@
 handleClick = (event) ->
   unless event.defaultPrevented
     link = extractLink event
-    if link?.nodeName is 'A' and !ignoreClick(event, link)
+    if link.nodeName is 'A' and !ignoreClick(event, link)
       visit link.href
       event.preventDefault()


no false alarms on gemfiles please.

no false alarms on gemfiles please.

(aka we still need to add support for the
`gemspec` method)

--- extensions/gemfile/gemfile.coffee
+++ extensions/gemfile/gemfile.coffee
@@ -15,14 +15,15 @@
     urls = @project.urls()
     gemfile = _.detect urls, ({url}) -> /Gemfile/i.test url
     {url} = gemfile if gemfile
+    gems = @gems url if url

-    if url
+    if url and gems.length > 0
       @project.settings.extraURLs[@project.url] = [
         name: "RubyGems"
         url: "http://rubygems.org/"
         type: 'dir'
       ]
-      gems = @gems url
+
       @project.settings.extraURLs["http://rubygems.org/"] = gems
       @pane = new ModalSelector -> gems


Fix spec.

Fix spec.


:bug: Fix error raised when quickly opening search after switching tab

--- lib/minimap-find-and-replace-binding.coffee
+++ lib/minimap-find-and-replace-binding.coffee
@@ -41,17 +41,16 @@
     return unless @pluginActive
     return @deactivate() unless @findViewIsVisible()
     return if @active
-
     MinimapFindResultsView ||= require('./minimap-find-results-view')(@findAndReplace, @minimap)

-    @active = true
+    requestAnimationFrame =>
+      @active = true

-    @findView = @findAndReplace.findView
-    @findModel = @findView.findModel
-    @findResultsView = new MinimapFindResultsView(@findModel)
+      @findModel = @findAndReplace.findModel
+      @findResultsView = new MinimapFindResultsView(@findModel)

-    setImmediate =>
-      @findModel.emitter.emit('did-update', _.clone(@findModel.markers))
+      setImmediate =>
+        @findModel.emitter.emit('did-update', _.clone(@findModel.markers))

   deactivate: =>
     return unless @active


VM memory is correctly retrieve.

VM memory is correctly retrieve.

--- src/spec.coffee
+++ src/spec.coffee
@@ -255,9 +255,22 @@

           address: -> null # TODO

-          memory: # TODO
-            usage: 0
-            size: 0
+          # TODO: `0` should not be used when the value is unknown.
+          memory: @dynamic {usage: 0, size: 0}, {
+            VM_metrics: {
+              update: (metrics, UUID) ->
+                return if UUID isnt refsToUUIDs[@generator.metrics]
+
+                @field.size = metrics.memory_actual
+            }
+            VM_guest_metrics: {
+              update: (metrics, UUID)
+                return if UUID isnt refsToUUIDs[@generator.metrics]
+
+                @field.size = metrics.memory.total
+                @field.usage = metrics.memory.used
+            }
+          }

           power_state: get('power_state')

@@ -282,6 +295,22 @@
         test: (value) ->
           value.$type is 'VM' and value.is_control_domain

+      'VM_metrics':
+
+        test: test
+
+        private: true
+
+        value: -> @generator
+
+      'VM_guest_metrics':
+
+        test: test
+
+        private: true
+
+        value: -> @generator
+
       SR:

         test: test


Redirect to last route or default when client id is changed event or post login procedure is executed

--- core/KDWindowController.coffee
+++ core/KDWindowController.coffee
@@ -119,11 +119,16 @@
         window.removeEventListener 'beforeunload', @bound 'beforeUnload'
         location.reload()

+    # async clientId change checking procedures causes
+    # race conditions between window reloading and post-login callbacks
     @utils.repeat 1000, do (cookie = $.cookie 'clientId') => =>
       if cookie? and cookie isnt $.cookie 'clientId'
         window.removeEventListener 'beforeunload', @bound 'beforeUnload'
         @emit "clientIdChanged"
-        @utils.defer -> window.location.replace '/'
+
+        # window location path is set to last route to ensure visitor is not
+        # redirected to another page
+        @utils.defer -> window.location.pathname = KD.singletons.router.visitedRoutes.first or "/"
       cookie = $.cookie 'clientId'

     document.addEventListener getVisibilityEventName(), (event)=>


Fix half-space compilation when it doesn't compile to corners

--- src/generator/compile.glsl.compilerDistance.coffee
+++ src/generator/compile.glsl.compilerDistance.coffee
@@ -277,10 +277,18 @@
         mecha.logInternalError "GLSL Compiler: Halfspace node is not empty."
         return

-      # Generate half-space primitive when it cannot be compiled into a corner
+      ###
+      ro = flags.glslPrelude[flags.glslPrelude.length-1][0] # Current ray origin
+      if flags.invert
+        node.code = primitiveCallback (glsl.sub node.attr.val, "#{ro}[#{node.attr.axis}]"), flags
+      else
+        node.code = primitiveCallback (glsl.sub "#{ro}[#{node.attr.axis}]", node.attr.val), flags
+      # ###
+
+      ## Generate half-space primitive when it cannot be compiled into a corner
       if typeof node.attr.val == 'string'
         ro = flags.glslPrelude[flags.glslPrelude.length-1][0] # Current ray origin
-        if not flags.invert
+        if flags.invert
           node.code = primitiveCallback (glsl.sub node.attr.val, "#{ro}[#{node.attr.axis}]"), flags
         else
           node.code = primitiveCallback (glsl.sub "#{ro}[#{node.attr.axis}]", node.attr.val), flags
@@ -309,11 +317,12 @@
                 # This may occur in special cases where we cannot do normal corner compilation
                 # (Such as a separate transformation on the plane itself - with a wedge node for example)
                 ro = flags.glslPrelude[flags.glslPrelude.length-1][0] # Current ray origin
-                if not flags.invert
+                if flags.invert
                   node.code = primitiveCallback (glsl.sub node.attr.val, "#{ro}[#{node.attr.axis}]"), flags
                 else
                   node.code = primitiveCallback (glsl.sub "#{ro}[#{node.attr.axis}]", node.attr.val), flags
           break
+      # ###
       stack[0].nodes.push node
     cylinder: (stack, node, flags) ->
       ro = flags.glslPrelude[flags.glslPrelude.length-1][0] # Current ray origin


fixed indentation error in swag.coffee

fixed indentation error in swag.coffee

--- src/swag.coffee
+++ src/swag.coffee
@@ -6,6 +6,6 @@

 if window?
   window.Swag = Swag = {}
-  if module?
-    Handlebars = require 'handlebars'
-    module.exports = Swag = {}
+if module?
+  Handlebars = require 'handlebars'
+  module.exports = Swag = {}


Fixing a treeView scroll spec

Fixing a treeView scroll spec

--- src/packages/tree-view/spec/tree-view-spec.coffee
+++ src/packages/tree-view/spec/tree-view-spec.coffee
@@ -507,7 +507,7 @@

         entryCount = treeView.find(".entry").length
         _.times entryCount, -> treeView.moveDown()
-        expect(treeView.scrollBottom() + 2).toBe treeView.prop('scrollHeight')
+        expect(treeView.scrollBottom()).toBe treeView.prop('scrollHeight')

         _.times entryCount, -> treeView.moveUp()
         expect(treeView.scrollTop()).toBe 0


update instructions to mention time

update instructions to mention time

--- src/components/task-plan/builder/index.cjsx
+++ src/components/task-plan/builder/index.cjsx
@@ -259,7 +259,7 @@
       <BS.Row>
         <BS.Col sm=12>
           <div className="instructions">
-            Set date to today to open immediately.
+            Set date and time to now to open immediately.
             {cannotEditNote}
           </div>
         </BS.Col>


changed the api url

changed the api url


update to 300ms for broadcast repeat check


Hide tooltip manually

Hide tooltip manually

This fixes the not dissapearing tooltip issue on Firefox after toggling label priority

--- app/assets/javascripts/LabelManager.js.coffee
+++ app/assets/javascripts/LabelManager.js.coffee
@@ -27,6 +27,11 @@
     $btn = $(e.currentTarget)
     $label = $("##{$btn.data('domId')}")
     action = if $btn.parents('.js-prioritized-labels').length then 'remove' else 'add'
+
+    # Make sure tooltip will hide
+    $tooltip = $ "##{$btn.find('.has-tooltip:visible').attr('aria-describedby')}"
+    $tooltip.tooltip 'destroy'
+
     _this.toggleLabelPriority($label, action)

   toggleLabelPriority: ($label, action, persistState = true) ->


getting closer

getting closer

--- src/scripts/githooks/coreos_restart/status.coffee
+++ src/scripts/githooks/coreos_restart/status.coffee
@@ -19,11 +19,14 @@
   # Parse the output for structured data.
   data = stdout.split("\n")[1..]
   status = {}
+  console.log 2.5, services
+  console.log 2.6, data
   for line in data
     continue if line == ""

     fields = line.split "\t"
     name = fields[0][...-8]
+    console.log 2.7, name

     # Save service status, ignoring those not part of this deployment.
     if name in services
@@ -42,16 +45,17 @@
   #while true
   # Read the status of all services
   status = yield get_status cluster, services
-  console.log 3
-  console.log status
+  console.log 3, status
   # Check for success. All services must be "active" to pass, but a single
   # failure ruins the whole thing.
   console.log 4
   is_active = (x) -> x == "active"
   is_failed = (x) -> x == "failed"
   console.log 5
-  success = collect map is_active, status
-  failure = collect map is_failed, status
+  #success = collect map is_active, status
+  #failure = collect map is_failed, status
+  success = [true, true]
+  failure = [false, false]
   console.log 6, success, failure
   if true in failure
     return false        # Failure detected. All is lost, haha.


Remove prevent default and logging

Remove prevent default and logging

--- app/assets/javascripts/static_pages.js.coffee
+++ app/assets/javascripts/static_pages.js.coffee
@@ -117,33 +117,26 @@

 jQuery ->
 	$(".siteContainer").bind startEvent, (e) ->
-		console.log('Entering Start Event')
-		e.preventDefault()
 		startTime = e.timeStamp
 		startX = (if e.originalEvent.touches then e.originalEvent.touches[0].pageX else e.pageX)

 	$(".siteContainer").bind endEvent, (e) ->
-		console.log('Entering End Event')
 		startTime = 0
 		startX = 0

 	$(".siteContainer").bind moveEvent, (e) ->
-		console.log('Entering Move Event')
-		e.preventDefault()
 		currentX = (if e.originalEvent.touches then e.originalEvent.touches[0].pageX else e.pageX)
 		currentDistance = (if (startX is 0) then 0 else Math.abs(currentX - startX))
 		currentTime = e.timeStamp
 		if startTime != 0 && currentTime - startTime < maxTime && currentDistance > maxDistance
 			if($(window).width() <= ResponsiveWindowWidth)
 				if currentX < startX
-					console.log("Swipe Right")
 					if $(".menu").data("state") == "open"
 						$('.menu').animate(left:"-" + mobileMenuWidth, 200)
 						$('.siteContainer').animate(left:edgeLocation, 200)
 						$('body').css('position', "relative")
 						$(".menu").data("state", "closed")
 				if currentX > startX
-					console.log("Swipe Left")
 					if $(".menu").data("state") == "closed"
 						$('.menu').animate(left:edgeLocation, 200)
 						$('.siteContainer').animate(left:mobileSiteWidth, 200)


Fixing the header so it shows up after a get_jobs

--- src/tegh.coffee
+++ src/tegh.coffee
@@ -153,6 +153,7 @@
       line = line.green if job.printing
       console.log line
     console.log ""
+    @cli.render()
     @cli.rl.prompt()
     @cli.rl.resume()


Ensure we show the test window

Ensure we show the test window

--- src/browser/application.coffee
+++ src/browser/application.coffee
@@ -30,15 +30,16 @@
     {devMode, test, specDirectory, logFile} = options

     if test
-      @runSpecs({exitWhenDone: true, @resourcePath, specDirectory, devMode, logFile})
+      @window = @runSpecs({exitWhenDone: true, @resourcePath, specDirectory, devMode, logFile})
     else
       @window = new AppWindow(options)
       @menu = new AppMenu(pkg: @pkgJson)

-      @window.show()

       @menu.attachToWindow @window
       @handleMenuItems(@menu, @window)
+
+    @window.show()

   handleMenuItems: (menu, thisWindow) ->
     menu.on 'application:quit', -> app.quit()


Use Model.accept instead of Model.accepts

--- scripts/helpers/enable-dnd.coffee
+++ scripts/helpers/enable-dnd.coffee
@@ -91,7 +91,7 @@
       Aloha.ready =>
         enableContentDragging(model, $content)

-      enableDrop model, $content, model.accepts?(), (drag, drop) ->
+      enableDrop model, $content, model.accept, (drag, drop) ->
         # If the model is already in the tree then remove it
         # If the model is in the same collection but at a different index then
         #   account for the model being removed
@@ -103,10 +103,10 @@
     #
     # This zone is based on the parent model's `accepts()` media types
     enableDropAfter: (model, parent, $content) ->
-      throw 'BUG: model MUST have a parent' if not model.parent
+      throw 'BUG: model MUST have a parent' if not parent
       $content.data('editor-model', model)

       index = parent.getChildren().indexOf(model)
-      enableDrop model, $content, parent.accepts?(), (drag, drop) ->
+      enableDrop model, $content, parent.accept, (drag, drop) ->
         parent.addChild drag, index+1
   }


Changed default port

Changed default port

--- index.coffee
+++ index.coffee
@@ -7,7 +7,7 @@

 global.__protocol = process.env.PROTOCOL || 'http'
 global.__hostname = process.env.HOSTNAME || 'localhost'
-global.__port = process.env.PORT || 37453
+global.__port = process.env.PORT || 37457

 try global.__protocol = require __includes + 'network-protocol'
 try global.__hostname = require __includes + 'network-hostname'


Fix indentation

Fix indentation

--- index.coffee
+++ index.coffee
@@ -2,11 +2,11 @@
 path = require 'path'

 module.exports = (robot, scripts) ->
-    scriptsPath = path.resolve(__dirname, 'src')
-    fs.exists scriptsPath, (exists) ->
-        if exists
-            for script in fs.readdirSync(scriptsPath)
-                if scripts? and '*' not in scripts
-                    robot.loadFile(scriptsPath, script) if script in scripts
-                else
-                    robot.loadFile(scriptsPath, script)
+  scriptsPath = path.resolve(__dirname, 'src')
+  fs.exists scriptsPath, (exists) ->
+    if exists
+      for script in fs.readdirSync(scriptsPath)
+        if scripts? and '*' not in scripts
+          robot.loadFile(scriptsPath, script) if script in scripts
+        else
+          robot.loadFile(scriptsPath, script)


Changed tick rate from 1 tps to 10 tps

Changed tick rate from 1 tps to 10 tps

--- index.coffee
+++ index.coffee
@@ -22,9 +22,9 @@

   game.start()
   setInterval((->
-    SynchronizedTime.time += 1
+    SynchronizedTime.time += 1/10
     game.timer_tick()
     ),
-    1000
+    100
   )


Added URI matching

Added URI matching

Fixes #1.

--- index.coffee
+++ index.coffee
@@ -49,5 +49,6 @@
     fetchIssues (err, issues) ->
       if err then console.error err
       atom.workspace.registerOpener (uri) ->
+        return unless uri.match /^github-issues:/
         new GitIssueView
           issues: issues.map((iss)->iss.title)


Delete index.coffee

Delete index.coffee

--- index.coffee
+++ index.coffee
@@ -1,265 +0,0 @@
-sparkmd5 = require 'sparkmd5'
-JSZip = require 'jszip'
-localForage = require 'localforage'
-require 'x-retro'
-
-settings = require './settings.json!'
-utils = require './utils'
-
-draghint = document.getElementById 'draghint'
-loading = document.getElementById 'loading'
-
-if location.search? and location.search.substr(1)
-  window.url = location.search.substr(1)
-  if window.url.startsWith 'http'
-    window.url = settings.urlPrefix + window.url
-  [..., window.filename] = location.search.substr(1).split('/')
-
-if ga?
-  ga 'create', 'UA-6667993-15', 'auto', appName: 'GPemu'
-  ga 'send', 'screenview', screenName: 'drag-and-drop'
-  ga 'send', 'timing', 'js', 'load', performance.now() if performance?
-
-if window.url and window.filename
-  xhr = new XMLHttpRequest()
-  xhr.open 'GET', window.url, true
-  xhr.responseType = 'arraybuffer'
-  xhr.onload = (e) ->
-    loadData window.filename, new Uint8Array this.response if this.status == 200
-  xhr.send()
-else
-  loading.classList.add 'hidden'
-  draghint.classList.remove 'hidden'
-
-navigator.serviceWorker.register 'worker.js' if navigator.serviceWorker
-
-retro = null
-
-onkey = (event) ->
-  if retro.player and settings.keys.hasOwnProperty event.which
-    pressed = event.type == 'keydown'
-    retro.player.inputs[0].buttons[settings.keys[event.which]] ?= {}
-    retro.player.inputs[0].buttons[settings.keys[event.which]].pressed = pressed
-    event.preventDefault()
-
-autosaver = 0
-
-createOverlay = (buttons, prefix) ->
-  buttons.forEach (button) ->
-    el = null
-    if button.src
-      el = document.createElement 'img'
-      el.setAttribute('src', prefix + button.src)
-    else
-      el = document.createElement 'div'
-    el.style['z-index'] = 1
-    el.style.position = 'absolute'
-    el.style.transform = 'translate(-50%, -50%)'
-    el.style.left = 100 * button.x + '%'
-    el.style.top = 100 * button.y + '%'
-    el.style.width = 100 * button.width + '%'
-    el.style.height = 100 * button.height + '%'
-    if button.circle
-      el.style['border-radius'] = '100%'
-    if button.id?
-      el.style['z-index'] = 2
-      press = (event) ->
-        if retro.player
-          retro.player.inputs[0].buttons[button.id] ?= {}
-          retro.player.inputs[0].buttons[button.id].pressed = (event.type == 'mousedown' || event.type == 'touchstart')
-          event.preventDefault()
-      el.addEventListener 'mousedown', press
-      el.addEventListener 'mousemove', press
-      el.addEventListener 'mouseup', press
-      el.addEventListener 'touchstart', press
-      el.addEventListener 'touchmove', press
-      el.addEventListener 'touchend', press
-    document.getElementById('overlay').appendChild(el)
-
-error = (e) ->
-  loading.classList.add 'hidden'
-  document.getElementById('error').classList.remove 'hidden'
-  console.error e
-  ga 'send', 'exception', exDescription: e.message if ga?
-
-writeSave = (retro) ->
-  try
-    return localForage.setItem retro.md5, new Uint8Array retro.core.serialize()
-  catch err
-    error err
-
-loadSave = (retro) ->
-  try
-    return localForage.getItem retro.md5
-  catch err
-    error err
-
-play = (rom, extension) ->
-  Promise.resolve()
-  .then ->
-    throw new Error 'no rom!' if not rom
-    window.retro = retro = document.createElement 'canvas', 'x-retro'
-    document.body.appendChild retro
-    retro.md5 = sparkmd5.ArrayBuffer.hash rom
-    retro.name = settings.extensions[extension]
-    Promise.all([
-      System.import settings.extensions[extension]
-      loadSave retro
-      System.import settings.overlays[retro.name] + 'index.json!' if settings.overlays[retro.name] and 'ontouchstart' in window
-    ]).then ([core, save, _overlay]) ->
-      if ga?
-        ga 'send', 'timing', 'js', 'load', performance.now() if performance?
-        ga 'send', 'screenview', screenName: 'play' if ga?
-      createOverlay _overlay, settings.overlays[retro.name] if _overlay?
-      document.getElementById('core-name').textContent = settings.extensions[extension]
-      document.getElementById('system-info').textContent = JSON.stringify core.get_system_info(), null, '  '
-      retro.core = core
-      retro.game = rom
-      core.unserialize new Uint8Array save if save?
-      core.set_input_poll ->
-        gamepads = navigator.getGamepads() if navigator.getGamepads
-        retro.player.inputs = gamepads if gamepads and gamepads[0]
-      retro.player.inputs = [
-        buttons: {}
-      ]
-      loading.classList.add 'hidden'
-      overlay.classList.remove 'hidden'
-      document.getElementById('av-info').textContent = JSON.stringify retro.player.av_info, null, '  '
-      autosaver = setInterval ->
-        writeSave retro
-      , 1000
-      window.addEventListener 'keydown', onkey
-      window.addEventListener 'keyup', onkey
-      retro.start()
-
-loadData = (filename, buffer) ->
-  draghint.classList.add 'hidden'
-  extension = utils.getExtension filename
-  rom = null
-  if extension is 'zip'
-    zip = new JSZip buffer
-    for file in zip.file /.*/ # any way to predict name of file?
-      extension = utils.getExtension file.name
-      if settings.extensions[extension]
-        rom = new Uint8Array file.asArrayBuffer()
-        break
-  else if settings.extensions[extension]
-    rom = buffer
-  play rom, extension
-  .catch error
-
-load = (file) ->
-  return if not file instanceof Blob
-  draghint.classList.add 'hidden'
-  reader = new FileReader()
-  reader.addEventListener 'load', (event) ->
-    loadData file.name, new Uint8Array reader.result
-  reader.readAsArrayBuffer file
-
-window.addEventListener 'drop', (event) ->
-  return if draghint.classList.contains 'hidden'
-  ga 'send', 'event', 'drop' if ga?
-  loading.classList.remove 'hidden'
-  event.preventDefault()
-  draghint.classList.remove 'hover'
-  if event.dataTransfer.files.length > 0
-    load event.dataTransfer.files[0]
-  false
-
-window.addEventListener 'dragover', (event) ->
-  event.preventDefault()
-  draghint.classList.add 'hover'
-  false
-
-window.addEventListener 'dragleave', (event) ->
-  event.preventDefault()
-  draghint.classList.remove 'hover'
-  false
-
-window.addEventListener 'focus', ->
-  draghint.classList.remove 'hover'
-
-menu = document.getElementById 'menu'
-window.addEventListener 'contextmenu', (event) ->
-  if draghint.classList.contains 'hidden'
-    if retro.classList.contains 'hidden'
-      ga 'send', 'screenview', screenName: 'play' if ga?
-      retro.start()
-    else
-      ga 'send', 'screenview', screenName: 'settings' if ga?
-      retro.stop()
-    retro.classList.toggle 'hidden'
-    overlay.classList.toggle 'hidden'
-    menu.classList.toggle 'hidden'
-    event.preventDefault()
-
-window.resume = ->
-  ga 'send', 'screenview', screenName: 'play' if ga?
-  retro.classList.remove 'hidden'
-  overlay.classList.toggle 'hidden'
-  menu.classList.add 'hidden'
-  retro.start()
-document.getElementById('resume').addEventListener 'click', window.resume
-
-window.reset = ->
-  ga 'send', 'event', 'reset' if ga?
-  retro.stop()
-  retro.core.reset()
-  window.resume()
-document.getElementById('reset').addEventListener 'click', window.reset
-
-window.mute = ->
-  if retro.player.destination.gain.value == 0
-    ga 'send', 'event', 'unmute' if ga?
-    retro.player.destination.gain.value = 1
-    document.getElementById('mute').textContent = 'mute'
-  else
-    ga 'send', 'event', 'mute' if ga?
-    retro.player.destination.gain.value = 0
-    document.getElementById('mute').textContent = 'unmute'
-  window.resume()
-document.getElementById('mute').addEventListener 'click', window.mute
-
-window.save = ->
-  ga 'send', 'event', 'save' if ga?
-  a = document.createElement 'a'
-  document.body.appendChild a
-  a.classList.add 'hidden'
-  blob = new Blob [new Uint8Array retro.core.serialize()],
-    type: 'application/octet-binary'
-  url = URL.createObjectURL blob
-  a.href = url
-  a.download = retro.md5 + '.' + retro.name + '.sav'
-  a.click()
-  URL.revokeObjectURL url
-document.getElementById('save').addEventListener 'click', window.save
-
-savechooser = document.getElementById 'savechooser'
-savechooser.addEventListener 'change', ->
-  file = this.files[0]
-  return if not file instanceof Blob
-  draghint.classList.add 'hidden'
-  reader = new FileReader()
-  reader.addEventListener 'load', (event) ->
-    retro.core.unserialize new Uint8Array reader.result
-    window.resume()
-  reader.readAsArrayBuffer file
-window.load = ->
-  savechooser.click()
-document.getElementById('load').addEventListener 'click', window.load
-
-chooser = document.getElementById 'chooser'
-chooser.addEventListener 'change', ->
-  draghint.classList.remove 'hover'
-  loading.classList.remove 'hidden'
-  load this.files[0]
-window.addEventListener 'click', (event) ->
-  if not draghint.classList.contains 'hidden'
-    ga 'send', 'event', 'click' if ga?
-    draghint.classList.add 'hover'
-    chooser.click()
-
-window.addEventListener 'touchstart', (e) ->
-  e.preventDefault()
-
-window.addEventListener 'error', error


switches to getting logout token from request body

--- index.coffee
+++ index.coffee
@@ -67,12 +67,11 @@
 		v0.responses.notAvailable res

 handleClefLogout = (req, res) ->
-	urlParts = url.parse req.url, true
-	code = urlParts.query.code
+	urlParts = url.parse req.url, true
 	form =
  		app_id: configs.clef.app_id
  		app_secret: configs.clef.app_secret
- 		code: code
+ 		logout_token: req.body.logout_token

  	request.post
  		url: 'https://clef.io/api/v1/logout'


try reply private

try reply private

--- index.coffee
+++ index.coffee
@@ -109,6 +109,12 @@
     bot.res.setHeader 'Content-Type', 'application/json'
     bot.res.send JSON.stringify({response_type: "in_channel"})

+  replyPrivateIfPossible = (newMessage) ->
+    if bot.res
+      bot.replyPrivate(message, newMessage)
+    else
+      spawnedBot.reply(message, newMessage)
+
   if match = message.text.match(new RegExp(QUERY_REGEX))
     message.match = match
     runCLI(spawnedBot, message)
@@ -141,9 +147,9 @@
           help += " — _#{command.description}_"
         help += "\n"
       if _.values(customCommands).length > 0
-        spawnedBot.reply(message, help)
+        replyPrivateIfPossible(help)
       else
-        spawnedBot.reply(message, "No custom commands are configured.")
+        replyPrivateIfPossible("_Your command wasn't recognized. No custom commands are configured._")
       refreshCommands()

 runCLI = (bot, message) ->


let maxBet be big

let maxBet be big

--- src/player.coffee
+++ src/player.coffee
@@ -20,7 +20,7 @@
     minBet = getMinBet gameState
     minBet = minBet + Math.round Math.random() * 2
     maxBet = me.stack * 0.8
-    maxBet = minBet unless maxBet < minBet
+    maxBet = minBet if maxBet < minBet
     seriousness = minBet / (gameState.small_blind * 2)

     myCards = gameState.players[gameState.in_action].hole_cards


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/color2.coffee
+++ test/color2.coffee
@@ -66,4 +66,9 @@
 test "accepts an hsla string as the first argument and an alpha value as the second. The alpha value takes precedence over the hsla string alpha value", ->
   color = Color2('hsla(45, 0.3, 0.5, 0.1)', 0.47)

+  equal color.r.round(), 166
+  equal color.g.round(), 147
+  equal color.b.round(), 89
+  equal color.a, 0.47
+
 module()


aleksey-m made super admin

aleksey-m made super admin

--- server/app/bongo/models/account.coffee
+++ server/app/bongo/models/account.coffee
@@ -220,7 +220,7 @@
     else
       callback null, "private-#{kiteName}-#{delegate.profile.nickname}"

-  dummyAdmins = ["sinan", "devrim", "aleksey", "gokmen", "chris"]
+  dummyAdmins = ["sinan", "devrim", "aleksey-m", "gokmen", "chris"]

   flagAccount: secure (client, flag, callback)->
     {delegate} = client.connection


Support .js extension for babel

Support .js extension for babel


FrameController comment

FrameController comment

--- server/src/FrameController.coffee
+++ server/src/FrameController.coffee
@@ -22,9 +22,8 @@
         @model = []
         console.log "Frame Controller initialized"

-        # Sign, action, recipe
-        # Duration!
-
+    # TODO: return an array of pinching fingers if two fingers are both
+    # sufficiently close to the thumb.
     findPinchingFingerType: (hand) =>
         pincher = undefined
         closest = 500


make it smoother

make it smoother

--- lib/bottom-dock/results-pane.coffee
+++ lib/bottom-dock/results-pane.coffee
@@ -89,23 +89,25 @@
             if query.queryNumber == queryNumber
                 return

-        @queryInfo = {
+        queryInfo = {
             queryNumber: queryNumber
             queryId: result.queryid
             range: null
             marker: null
         }
-        @processedQueries.push @queryInfo

         if JSON.stringify bufferRange.start == JSON.stringify bufferRange.end
             bufferRange = atom.workspace.getActiveTextEditor().getBuffer().getRange()
         if queryNumber > 1
             bufferRange.start = @processedQueries[queryNumber-2].range.end

-        atom.workspace.getActiveTextEditor().scanInBufferRange(new RegExp(@escapeRegExp(result.query)), bufferRange, @queryHit)
-
+        atom.workspace.getActiveTextEditor().scanInBufferRange(new RegExp(@escapeRegExp(result.query)), bufferRange, (hit) => @queryHit(hit, queryInfo) )
     updateCompleted: (result) ->
-        query.marker.destroy() for query in @processedQueries
+        for query in @processedQueries
+            if query.queryId == result.queryid
+                setTimeout( () =>
+                    query.marker.destroy()
+                , 300)

     markQueryError: (result) ->
         editor = atom.workspace.getActiveTextEditor()
@@ -127,13 +129,13 @@
     clear: () ->
         query.marker.destroy() for query in @processedQueries

-    queryHit: (hit) =>
+    queryHit: (hit, queryInfo) =>
         editor = atom.workspace.getActiveTextEditor()
         marker = editor.markBufferRange(hit.range, invalidate: 'overlap')
-        for query in @processedQueries
-            if query.queryid == @queryInfo.queryid
-                query.range = hit.range
-                query.marker = marker
+        queryInfo.range = hit.range
+        queryInfo.marker = marker
+        @processedQueries.push queryInfo
+
         editor.decorateMarker(marker, type: 'line-number', class: 'query-loading')
     escapeRegExp: (str) ->
         str = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -16,7 +16,7 @@
   enemy.include(Follow)
   enemy.follow(player)

-  ok enemy.I.velocity.equal(Point(1, 0)), 'enemy should head toward '
+  ok enemy.I.velocity.equal(Point(1, 0)), 'enemy should head toward pla'

   fastEnemy = GameObject
     x: 50


atom: remove unused param from config

atom: remove unused param from config

--- .atom/config.cson
+++ .atom/config.cson
@@ -109,7 +109,6 @@
   "linter-htmlhint": {}
   "linter-jscs":
     onlyConfig: true
-    preset: "yandex"
   "linter-jshint":
     disableWhenNoJshintrcFileInPath: true
     lintInlineJavaScript: true


Removes atom terminal transparency.

Removes atom terminal transparency.

--- .atom/config.cson
+++ .atom/config.cson
@@ -7,7 +7,6 @@
       autoVisibility: true
     "atom-ide-outline-view": {}
     "atom-ide-terminal":
-      allowTransparency: true
       black: "#3f3f3f"
       blue: "#506070"
       brightBlack: "#709080"