App.UserItemController = Em.ObjectController.extend
  actions:
    remove: ->
      user = @get("model").deleteRecord()
      successCallback  = =>
        console.log("deleted")
      errorCallback = =>
        console.log("error whatever...")
      user.save().then(successCallback, errorCallback)

App.UserItemController = Em.ObjectController.extend
  needs: ["application"]
  currentUser: Ember.computed.alias("controllers.application.currentUser")

  isCurrentUser: (->
    @get("currentUser").id == @get("model").id
  ).property("currentUser")

  actions:
    remove: ->
      user = @get("model").deleteRecord()
      successCallback  = =>
        console.log("deleted")
      errorCallback = =>
        console.log("error whatever...")
      user.save().then(successCallback, errorCallback)

Add isCurrentUser property to UserItemController


angular.module("app").controller "AccountBalancesController", ($scope, $location, $stateParams, $state, Wallet, Utils) ->

    $scope.accounts = Wallet.accounts
    $scope.balances = Wallet.balances
    $scope.utils = Utils

    $scope.formatAsset = Utils.formatAsset

    Wallet.refresh_accounts()

Remove refresh. Already called in parent controller


# Description:
#   Interacts with the Google Maps API.
#
# Commands:
#   hubot map me <query> - Returns a map view of the area returned by `query`.

module.exports = (robot) ->

  robot.respond /(?:(satellite|terrain|hybrid)[- ])?map me (.+)/i, (msg) ->
    mapType  = msg.match[1] or "roadmap"
    location = msg.match[2]
    mapUrl   = "http://maps.google.com/maps/api/staticmap?markers=" +
                escape(location) +
                "&size=400x400&maptype=" +
                mapType +
                "&sensor=false" +
                "&format=png" # So campfire knows it's an image
    url      = "http://maps.google.com/maps?q=" +
               escape(location) +
              "&hl=en&sll=37.0625,-95.677068&sspn=73.579623,100.371094&vpsrc=0&hnear=" +
              escape(location) +
              "&t=m&z=11"

    msg.send mapUrl
    msg.send url

# Description:
#   Interacts with the Google Maps API.
#
# Commands:
#   hubot map me <query> - Returns a map view of the area returned by `query`.

module.exports = (robot) ->

  robot.respond /(?:(satellite|terrain|hybrid)[- ])?map me (.+)/i, (msg) ->
    mapType  = msg.match[1] or "roadmap"
    location = msg.match[2]
    mapUrl   = "http://maps.google.com/maps/api/staticmap?markers=" +
                encodeURIComponent(location) +
                "&size=400x400&maptype=" +
                mapType +
                "&sensor=false" +
                "&format=png" # So campfire knows it's an image
    url      = "http://maps.google.com/maps?q=" +
               encodeURIComponent(location) +
              "&hl=en&sll=37.0625,-95.677068&sspn=73.579623,100.371094&vpsrc=0&hnear=" +
              encodeURIComponent(location) +
              "&t=m&z=11"

    msg.send mapUrl
    msg.send url

Change string encoding function from escape to encodeURIComponent Encode function could not multibyte string for url.


React = require 'react'
Router = require 'react-router'

{CourseStore} = require '../../../flux/course'

TimeZoneSettingsLink = React.createClass

  propTypes:
    courseId: React.PropTypes.string.isRequired

  contextTypes:
    router: React.PropTypes.func

  render: ->
    <Router.Link
      className='course-time-zone'
      to='courseSettings'
      params={courseId: @props.courseId}
    >
      {CourseStore.getTimezone(@props.courseId)}
    </Router.Link>

module.exports = TimeZoneSettingsLink

React  = require 'react'
Router = require 'react-router'
BS     = require 'react-bootstrap'

{CourseStore} = require '../../../flux/course'

TimeZoneSettingsLink = React.createClass

  propTypes:
    courseId: React.PropTypes.string.isRequired

  contextTypes:
    router: React.PropTypes.func

  render: ->
    tooltip =
      <BS.Tooltip id='change-course-time'>
        Click to change course time zone
      </BS.Tooltip>
    <Router.Link
      className='course-time-zone'
      to='courseSettings'
      params={courseId: @props.courseId}
    >
      <BS.OverlayTrigger placement='top' overlay={tooltip}>
        <span>{CourseStore.getTimezone(@props.courseId)}</span>
      </BS.OverlayTrigger>
    </Router.Link>

module.exports = TimeZoneSettingsLink

Add tooltip to course timezone change

Add tooltip to course timezone change


PythonTools = require '../lib/python-tools'

describe "PythonTools", ->
  beforeEach ->
    waitsForPromise ->
      atom.packages.activatePackage('python-tools')

  describe "when a response is returned from tools.py", ->
    it "correctly deserializes JSON", ->
      pythonTools = atom.packages.getActivePackage('python-tools').mainModule
      pythonTools.handleJsonResponse('''{
        "type": "usages",
        "definitions": {
          "line": 0, "column": 0, "path": "foo.py", "name": "bar"
        }
      }''')

    it "informs the user with an info notification when no items were found", ->
      pythonTools = atom.packages.getActivePackage('python-tools').mainModule
      pythonTools.handleJediToolsResponse(
        type: "usages"
        definitions: []
      )
      [notification] = atom.notifications.getNotifications()
      expect(notification.type).toBe 'info'

    it "informs the user with an error notifiation on invalid type", ->
      pythonTools = atom.packages.getActivePackage('python-tools').mainModule
      pythonTools.handleJediToolsResponse(
        type: "monkeys"
        definitions: [
          {
            line: 0
            column: 0
          }
        ]
      )
      [notification] = atom.notifications.getNotifications()
      expect(notification.type).toBe 'error'

PythonTools = require '../lib/python-tools'

describe "PythonTools", ->
  pythonTools = null
  beforeEach ->
    waitsForPromise ->
      atom.packages.activatePackage('python-tools')
    runs ->
      pythonTools = atom.packages.getActivePackage('python-tools').mainModule

  describe "when a response is returned from tools.py", ->
    it "correctly deserializes JSON", ->
      pythonTools.handleJsonResponse('''{
        "type": "usages",
        "definitions": {
          "line": 0, "column": 0, "path": "foo.py", "name": "bar"
        }
      }''')

    it "informs the user with an info notification when no items were found", ->
      pythonTools.handleJediToolsResponse(
        type: "usages"
        definitions: []
      )
      [notification] = atom.notifications.getNotifications()
      expect(notification.type).toBe 'info'

    it "informs the user with an error notifiation on invalid type", ->
      pythonTools.handleJediToolsResponse(
        type: "monkeys"
        definitions: [{
            line: 0
            column: 0
        }   ]
      )
      [notification] = atom.notifications.getNotifications()
      expect(notification.type).toBe 'error'

Move pythonTools assignment to beforeEach


goog.provide 'spark.utils'

counter = Math.floor Math.random() * 2147483648

###*
  Returns a unique id. Ported from TartJS.
  https://github.com/tart/tartJS/blob/master/tart/tart.js#L26 -- amcalar <3

  @export
  @return {string} Unique id.
###
spark.utils.getUid = ->
  return (counter++).toString 36

###*
  Concats strings together with a space.

  @export
  @param {...*} var_args A list of strings to concatenate.
  @return {string} The concatenation of {@code var_args}.
###
spark.utils.concatString = (var_args) ->
  strings = []

  for arg in arguments when typeof arg is 'string'
    if arg.indexOf(' ') > -1
      for item in arg.split ' '
        strings.push item if strings.indexOf(item) is -1
    else
      strings.push arg

  return Array.prototype.join.call strings, ' '

goog.provide 'spark.utils'

counter = Math.floor Math.random() * 2147483648

###*
  Returns a unique id. Ported from TartJS.
  https://github.com/tart/tartJS/blob/master/tart/tart.js#L26 -- amcalar <3

  @export
  @return {string} Unique id.
###
spark.utils.getUid = ->
  return (counter++).toString 36

###*
  Concats strings together with a space.

  @export
  @param {...*} var_args A list of strings to concatenate.
  @return {string} The concatenation of {@code var_args}.
###
spark.utils.concatString = (var_args) ->
  strings = []

  for arg in arguments when typeof arg is 'string'
    if arg.indexOf(' ') > -1
      for item in arg.split ' '
        strings.push item if strings.indexOf(item) is -1
    else
      strings.push arg

  return strings.join ' '

Utils: Use native array.join to concat strings.

cihangir <3


# Description
#   Obtiene el nombre de la persona o empresa del RUT consultado
#
# Commands:
#   hubot info rut <rut> -> RUT: <rut>, Nombre: <nombre>
#
# Author:
#   lgaticaq

infoRut = require("info-rut")

module.exports = (robot) ->
  robot.respond /info rut (.*)/i, (msg) ->
    rut = msg.match[1]
    infoRut rut, (err, fullName) ->
      if err
        msg.send "RUT no encontrado"
      else
        msg.send "RUT: #{rut}, Nombre: #{fullName}"

# Description
#   Obtiene el nombre de la persona o empresa del RUT consultado y viceversa
#
# Dependencies:
#   "info-rut": "^1.0.0"
#
# Commands:
#   hubot info-rut rut <rut> -> RUT: <rut>, Nombre: <nombre>
#   hubot info-rut nombre <nombre> -> RUT: <rut>, Nombre: <nombre>
#
# Author:
#   lgaticaq

infoRut = require("info-rut")

module.exports = (robot) ->
  robot.respond /info-rut rut (.*)/i, (res) ->
    rut = res.match[1]
    infoRut.getFullName(rut)
      .then (fullName) ->
        res.send "RUT: #{rut}, Nombre: #{fullName}"
      .catch (err) ->
        res.reply "ocurrio un error al consultar el rut"
        robot.emit "error", err, res

  robot.respond /info-rut nombre (.*)/i, (res) ->
    name = res.match[1]
    infoRut.getRut(name)
      .then (results) ->
        if results.length > 0
          for r in results
            res.send "RUT: #{r.rut}, Nombre: #{r.fullName}"
        else
          res.reply "no hay resultados para #{name}"
      .catch (err) ->
        res.reply "ocurrio un error al consultar el nombre"
        robot.emit "error", err, res

Change get full name and add get rut

Change get full name and add get rut


#= require qunit
#= require rails
#= require_directory ./unit

window.setupFrame = (env, url) ->
  stop()

  env.iframe = document.createElement 'iframe'
  env.iframe.src = "/frame"
  env.iframe.onload = ->
    env.iframe.onload = ->

    env.window   = env.win = env.iframe.contentWindow
    env.document = env.doc = env.iframe.contentDocument
    env.$        = env.iframe.contentWindow.jQuery

    start()

  fixture = document.getElementById 'qunit-fixture'
  fixture.appendChild env.iframe

window.click = (element) ->
  event = document.createEvent 'MouseEvents'
  event.initEvent 'click', true, true
  element.dispatchEvent event

$(document).delegate 'a[href]', 'click', (event) ->
  return if event.defaultPrevented || event.isDefaultPrevented?()
  window.location = event.target.href
  return

# Target form submissions to iframe
guid = 1
$(document).bind 'submit', (event) ->
  return if event.defaultPrevented || event.isDefaultPrevented?()
  name   = "frame#{guid++}"
  iframe = $ "<iframe id=#{name} name=#{name}>"
  $(event.target).attr 'target', name
  $('#qunit-fixture').append iframe

if Zepto?
  $(document).bind 'ajaxSuccess', (event, xhr) ->
    if xhr.getResponseHeader('Content-Type') is 'application/javascript'
      eval xhr.responseText

#= require qunit
#= require_directory ./unit

window.setupFrame = (env, url) ->
  stop()

  env.iframe = document.createElement 'iframe'
  env.iframe.src = "/frame"
  env.iframe.onload = ->
    env.iframe.onload = ->

    env.window   = env.win = env.iframe.contentWindow
    env.document = env.doc = env.iframe.contentDocument
    env.$        = env.iframe.contentWindow.jQuery

    start()

  fixture = document.getElementById 'qunit-fixture'
  fixture.appendChild env.iframe

window.click = (element) ->
  event = document.createEvent 'MouseEvents'
  event.initEvent 'click', true, true
  element.dispatchEvent event

$(document).delegate 'a[href]', 'click', (event) ->
  return if event.defaultPrevented || event.isDefaultPrevented?()
  window.location = event.target.href
  return

# Target form submissions to iframe
guid = 1
$(document).bind 'submit', (event) ->
  return if event.defaultPrevented || event.isDefaultPrevented?()
  name   = "frame#{guid++}"
  iframe = $ "<iframe id=#{name} name=#{name}>"
  $(event.target).attr 'target', name
  $('#qunit-fixture').append iframe

if Zepto?
  $(document).bind 'ajaxSuccess', (event, xhr) ->
    if xhr.getResponseHeader('Content-Type') is 'application/javascript'
      eval xhr.responseText

Test env doesn't need rails.js

Test env doesn't need rails.js


define ['angular', 'angularRoute', 'controllers'], (angular) ->
    getFirstPage = ->
        if window.isAuthenticated
            '/user/' + window.user + '/'
        else
            '/welcome/'

    app = angular.module('coviolations', ['ngRoute', 'coviolations.controllers'])
        .config ['$routeProvider', '$locationProvider', ($routeProvider, $locationProvider) ->
            $routeProvider
                .when '/',
                    redirectTo: getFirstPage()
                .when '/welcome/',
                    templateUrl: '/static/views/index.html'
                    controller: 'IndexCtrl'
                .when '/projects/manage/',
                    templateUrl: '/static/views/manage.html'
                    controller: 'ManageCtrl'
                .when '/projects/:owner/:name/',
                    templateUrl: '/static/views/project.html'
                    controller: 'ProjectCtrl'
                .when '/tasks/:pk/',
                    templateUrl: '/static/views/task.html'
                    controller: 'TaskCtrl'
                .when '/user/:user/',
                    templateUrl: '/static/views/dashboard.html'
                    controller: 'UserPageCtrl'
                .when '/not_found/',
                    templateUrl: '/static/views/not_found.html'
                .when '/access/:task/',
                    templateUrl: '/static/views/access.html'
                    controller: 'AccessCtrl'
                .when '/access/:owner/:name/',
                    templateUrl: '/static/views/access.html'
                    controller: 'AccessCtrl'
                .otherwise
                    redirectTo: '/not_found/'
        ]

    app.run ($rootScope) ->
        $rootScope.getId = (obj) -> obj._id if obj

define ['angular', 'angularRoute', 'controllers'], (angular) ->
    getFirstPage = ->
        if window.isAuthenticated
            '/user/' + window.user + '/'
        else
            '/welcome/'

    app = angular.module('coviolations', ['ngRoute', 'coviolations.controllers'])
        .config ['$routeProvider', '$locationProvider', ($routeProvider, $locationProvider) ->
            $routeProvider
                .when '/',
                    redirectTo: getFirstPage()
                .when '/dashboard/',
                    redirectTo: getFirstPage()
                .when '/welcome/',
                    templateUrl: '/static/views/index.html'
                    controller: 'IndexCtrl'
                .when '/projects/manage/',
                    templateUrl: '/static/views/manage.html'
                    controller: 'ManageCtrl'
                .when '/projects/:owner/:name/',
                    templateUrl: '/static/views/project.html'
                    controller: 'ProjectCtrl'
                .when '/tasks/:pk/',
                    templateUrl: '/static/views/task.html'
                    controller: 'TaskCtrl'
                .when '/user/:user/',
                    templateUrl: '/static/views/dashboard.html'
                    controller: 'UserPageCtrl'
                .when '/not_found/',
                    templateUrl: '/static/views/not_found.html'
                .when '/access/:task/',
                    templateUrl: '/static/views/access.html'
                    controller: 'AccessCtrl'
                .when '/access/:owner/:name/',
                    templateUrl: '/static/views/access.html'
                    controller: 'AccessCtrl'
                .otherwise
                    redirectTo: '/not_found/'
        ]

    app.run ($rootScope) ->
        $rootScope.getId = (obj) -> obj._id if obj

Add redirect from dashboard to user page


exports.beforeEach = (fn) ->
  global.beforeEach ->
    result = fn()
    if result instanceof Promise
      waitsForPromise(-> result)

exports.afterEach = (fn) ->
  global.afterEach ->
    result = fn()
    if result instanceof Promise
      waitsForPromise(-> result)

['it', 'fit', 'ffit', 'fffit'].forEach (name) ->
  exports[name] = (description, fn) ->
    global[name] description, ->
      result = fn()
      if result instanceof Promise
        waitsForPromise(-> result)

waitsForPromise = (fn) ->
  promise = fn()
  waitsFor 'spec promise to resolve', 30000, (done) ->
    promise.then(
      done,
      (error) ->
        jasmine.getEnv().currentSpec.fail(error)
        done()
    )

exports.beforeEach = (fn) ->
  global.beforeEach ->
    result = fn()
    if result instanceof Promise
      waitsForPromise(-> result)

exports.afterEach = (fn) ->
  global.afterEach ->
    result = fn()
    if result instanceof Promise
      waitsForPromise(-> result)

['it', 'fit', 'ffit', 'fffit'].forEach (name) ->
  exports[name] = (description, fn) ->
    global[name] description, ->
      result = fn()
      if result instanceof Promise
        waitsForPromise(-> result)

waitsForPromise = (fn) ->
  promise = fn()
  # This timeout is 3 minutes. We need to bump it back down once we fix backgrounding
  # of the renderer process on CI. See https://github.com/atom/electron/issues/4317
  waitsFor 'spec promise to resolve', 3 * 60 * 1000, (done) ->
    promise.then(
      done,
      (error) ->
        jasmine.getEnv().currentSpec.fail(error)
        done()
    )

Revert "Reduce spec timeout duration"

Revert "Reduce spec timeout duration"

This reverts commit e03df6e1a48fea12782b25df0b81790e4f4a056c.


argv = require('yargs')
      .options('d', {
        alias: 'dir',
        default: '.',
        describe: 'Served files directory'
      })
      .options('p', {
        alias: 'port',
        default: '1234',
        describe: 'Runs Shuss on the specified port'
      })
      .options('verbose', {
        boolean: true,
        describe: 'Speak to me'
      })
      .options('l', {
        alias: 'livereload'
        boolean: true,
        describe: 'Enables LiveReload'
      })
      .options('f', {
        alias: 'file',
        describe: 'Config file path'
      })
      .options('v', {
        alias: 'version'
        boolean: true,
        describe: 'Return actual Shuss version'
      })
      .argv
ShussServer = require './shuss-server'

class ShussCli
  constructor:(@argv)->

  run:(@config, @logger)=>
    if @argv.version
      @_version()
    else
      @_start()

  _version: ()->
    console.log require('../package').version

  _start: ()->
    @logger.debug 'starting'

    @config.load @argv
    @config.loadFile path if path = @argv.file
    @config.validate()
    @logger.resetConfig()

    new ShussServer(@config, @logger).start()

module.exports = new ShussCli argv

argv = require('yargs')
      .options('d',
        alias: 'dir'
        default: '.'
        describe: 'Served files directory'
      )
      .options('p',
        alias: 'port'
        default: '1234'
        describe: 'Runs Shuss on the specified port'
      )
      .options('verbose',
        boolean: true
        describe: 'Speak to me'
      )
      .options('l',
        alias: 'livereload'
        boolean: true
        describe: 'Enables LiveReload'
      )
      .options('f',
        alias: 'file'
        describe: 'Config file path'
      )
      .options('v',
        alias: 'version'
        boolean: true
        describe: 'Return actual Shuss version'
      )
      .argv
ShussServer = require './shuss-server'

class ShussCli
  constructor:(@argv)->

  run:(@config, @logger)=>
    if @argv.version
      @_version()
    else
      @_start()

  _version: ()->
    console.log require('../package').version

  _start: ()->
    @logger.debug 'starting'

    @config.load @argv
    @config.loadFile path if path = @argv.file
    @config.validate()
    @logger.resetConfig()

    new ShussServer(@config, @logger).start()

module.exports = new ShussCli argv

Update to a better CoffeeScript syntax

Update to a better CoffeeScript syntax

Fixes #4
Fixes #6


#= require libraries
#= require_tree .

$ ->
  $('.alert').delay(4000).fadeOut('slow')
  $('.chosen').chosen()
  $('.timeago').timeago()

# Have a loading screen when turbolinks is working it's magic
document.addEventListener 'page:fetch', ->
  html = "

"
  $('body').prepend(html)

document.addEventListener 'page:receive', ->
  $('#loading').remove()

Add closing tag to turbolinks loading message.


angular.module('loomioApp').directive 'previousProposalsCard', ($routeParams) ->
  scope: {discussion: '='}
  restrict: 'E'
  templateUrl: 'generated/components/thread_page/previous_proposals_card/previous_proposals_card.html'
  replace: true
  controller: ($scope, $rootScope, $location, Records) ->

    Records.votes.fetchMyVotes($scope.discussion)
    Records.proposals.fetchByDiscussion($scope.discussion).then ->
      $rootScope.$broadcast 'threadPageProposalsLoaded'

    lastRecentlyClosedProposal = ->
      return unless $scope.anyProposals() and !$scope.discussion.hasActiveProposal()
      proposal = $scope.discussion.closedProposals()[0]
      proposal if moment().add(-1, 'month') < proposal.closedAt

    $scope.$on 'setSelectedProposal', (event, proposal) ->
      $scope.selectedProposalId = (proposal or lastRecentlyClosedProposal() or {}).id

    $scope.anyProposals = ->
      $scope.discussion.closedProposals().length > 0

    return

angular.module('loomioApp').directive 'previousProposalsCard', ->
  scope: {discussion: '='}
  restrict: 'E'
  templateUrl: 'generated/components/thread_page/previous_proposals_card/previous_proposals_card.html'
  replace: true
  controller: ($scope, $rootScope, $location, Records) ->

    Records.votes.fetchMyVotes($scope.discussion)
    Records.proposals.fetchByDiscussion($scope.discussion).then ->
      $rootScope.$broadcast 'threadPageProposalsLoaded'

    lastRecentlyClosedProposal = ->
      return unless $scope.anyProposals() and !$scope.discussion.hasActiveProposal()
      proposal = $scope.discussion.closedProposals()[0]
      proposal if moment().add(-1, 'month') < proposal.closedAt

    $scope.$on 'setSelectedProposal', (event, proposal) ->
      $scope.selectedProposalId = (proposal or lastRecentlyClosedProposal() or {}).id

    $scope.anyProposals = ->
      $scope.discussion.closedProposals().length > 0

    return

Fix search result lmo href

Fix search result lmo href


###
# Mentions is a named function that will process Mentions
# @param {Object} message - The message object
###

class MentionsServer
	constructor: (message) ->
		# If message starts with /me, replace it for text formatting
		mentions = []
		message.msg.replace /(?:^|\s|\n)(?:@)([A-Za-z0-9-_.]+)/g, (match, mention) ->
			mentions.push mention
		if mentions.length isnt 0
			mentions = _.unique mentions
			verifiedMentions = []
			mentions.forEach (mention) ->
				verifiedMention = Meteor.users.findOne({username: mention}, {fields: {_id: 1, username: 1}})
				verifiedMentions.push verifiedMention if verifiedMention?
			if verifiedMentions.length isnt 0
				message.mentions = verifiedMentions
		return message

RocketChat.callbacks.add 'beforeSaveMessage', MentionsServer

###
# Mentions is a named function that will process Mentions
# @param {Object} message - The message object
###

class MentionsServer
	constructor: (message) ->
		# If message starts with /me, replace it for text formatting
		mentions = []
		message.msg.replace /(?:^|\s|\n)(?:@)([A-Za-z0-9-_.]+)/g, (match, mention) ->
			mentions.push mention
		if mentions.length isnt 0
			mentions = _.unique mentions
			verifiedMentions = []
			mentions.forEach (mention) ->
				if mention is 'all'
					verifiedMention =
						_id: mention
						username: mention
				else
					verifiedMention = Meteor.users.findOne({username: mention}, {fields: {_id: 1, username: 1}})

				verifiedMentions.push verifiedMention if verifiedMention?
			if verifiedMentions.length isnt 0
				message.mentions = verifiedMentions
		return message

RocketChat.callbacks.add 'beforeSaveMessage', MentionsServer

Allow save mentions to 'all'

Allow save mentions to 'all'


class CommentListViewController extends KDListViewController

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

    options.viewOptions or=
      type                : 'comments'
      dataPath            : 'id'
      itemClass           : CommentListItemView
      itemOptions         :
        activity          : data

    super options, data

    commentView = @getDelegate()

    @getListView().on 'ItemWasAdded', (item) ->
      commentView.forwardEvent item, 'MentionStarted'
      commentView.forwardEvent item, 'MentionHappened'
      commentView.forwardEvent item, 'MouseEnterHappenedOnMention'
      commentView.forwardEvent item, 'MouseLeaveHappenedOnMention'

  instantiateListItems: (items) ->

    super items.sort (a, b) -> a.createdAt - b.createdAt

  addItem: (item, index) ->

    super item, index

  loadView: (mainView) ->

    super mainView

    {replies} = @getData()
    @instantiateListItems replies  if replies.length

  setScrollView: (mainView) ->

    mainView.addSubView @customScrollView or @scrollView
    @scrollView.addSubView @getListView()
    @showLazyLoader no  if @getOption 'startWithLazyLoader'

    @scrollView.on 'LazyLoadThresholdReached', @bound 'showLazyLoader'

class CommentListViewController extends KDListViewController

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

    options.viewOptions or=
      type                : 'comments'
      dataPath            : 'id'
      itemClass           : CommentListItemView
      itemOptions         :
        activity          : data

    super options, data

    commentView = @getDelegate()

    @getListView().on 'ItemWasAdded', (item) ->
      commentView.forwardEvent item, 'MentionStarted'
      commentView.forwardEvent item, 'MentionHappened'
      commentView.forwardEvent item, 'MouseEnterHappenedOnMention'
      commentView.forwardEvent item, 'MouseLeaveHappenedOnMention'

  instantiateListItems: (items) ->
    super items.sort (a, b) -> new Date(a.createdAt) - new Date(b.createdAt)

  addItem: (item, index) ->

    super item, index

  loadView: (mainView) ->

    super mainView

    {replies} = @getData()
    @instantiateListItems replies  if replies.length

  setScrollView: (mainView) ->

    mainView.addSubView @customScrollView or @scrollView
    @scrollView.addSubView @getListView()
    @showLazyLoader no  if @getOption 'startWithLazyLoader'

    @scrollView.on 'LazyLoadThresholdReached', @bound 'showLazyLoader'

Activity: Fix wrong comment ordering on pageLoad bug


currentTest = {}
startTime = null

QUnit.testStart (context) ->
  currentTest = {}
  currentTest.name = context.name
  currentTest.assertions = 0
  currentTest.backtrace = []
  startTime = (new Date()).getTime()

QUnit.log (context) ->
  if context.result
    currentTest.assertions++
    return

  stackTrace = []
  currentTest.backtrace = []

  # qunit handles exceptions in a werid way. It prepends "Died"
  # to the stacktrace and shoves that in message
  if context.message.match(/^Died/)
    currentTest.error = true
    currentTest.message = context.source
    stackTrace = context.message

  # General Assertion Error
  else if context.message
    currentTest.assertions++
    currentTest.failed = true
    currentTest.message = context.message
    stackTrace = context.source

  # Failed expectations
  else if context.expected
    currentTest.failed = true
    currentTest.message = "Expected: #{context.expected}, Actual: #{context.actual}"
    stackTrace = context.source

  # format the backtrace accordingly
  for line in stackTrace.split("\n")
    matches = line.match(/(file:\/\/|https?:\/\/|\/.+:\d+)/)
    if matches
      currentTest.backtrace.push matches[1]
    else
      currentTest.backtrace.push line

QUnit.testDone (context) ->
  currentTest.time = (new Date()).getTime() - startTime
  window.logger.message(currentTest)

QUnit.done (context) ->
  window.unitTestsDone = true

QUnit.config.autorun = false

@currentTest = {}
@startTime = null

QUnit.testStart (context) =>
  @currentTest = {}
  @currentTest.name = context.name
  @currentTest.assertions = 0
  @currentTest.backtrace = []
  @startTime = (new Date()).getTime()

QUnit.log (context) =>
  if context.result
    @currentTest.assertions++
    return

  stackTrace = []
  @currentTest.backtrace = []

  # qunit handles exceptions in a werid way. It prepends "Died"
  # to the stacktrace and shoves that in message
  if context.message.match(/^Died/)
    @currentTest.error = true
    @currentTest.message = context.source
    stackTrace = context.message

  # General Assertion Error
  else if context.message
    @currentTest.assertions++
    @currentTest.failed = true
    @currentTest.message = context.message
    stackTrace = context.source

  # Failed expectations
  else if context.expected
    @currentTest.failed = true
    @currentTest.message = "Expected: #{context.expected}, Actual: #{context.actual}"
    stackTrace = context.source

  # format the backtrace accordingly
  for line in stackTrace.split("\n")
    matches = line.match(/(file:\/\/|https?:\/\/|\/.+:\d+)/)
    if matches
      @currentTest.backtrace.push matches[1]
    else
      @currentTest.backtrace.push line

QUnit.testDone (context) =>
  @currentTest.time = (new Date()).getTime() - @startTime
  window.logger.message(@currentTest)

QUnit.done (context) =>
  window.unitTestsDone = true

QUnit.config.autorun = false

Use => for clearer code

Use => for clearer code


React = require 'react'
ReactDOM = require 'react-dom'

module.exports = React.createClass
  XLINK_NS: 'http://www.w3.org/1999/xlink'

  getDefaultProps: ->
    src: ''
    aspectRatio: NaN

  getInitialState: ->
    naturalWidth: 0
    naturalHeight: 0

  componentDidMount: ->
    @loadImage @props.src

  componentWillReceiveProps: (nextProps) ->
    unless nextProps.src is @props.src
      @loadImage nextProps.src

  loadImage: (src) ->
    img = new Image
    img.onload = =>
      {naturalWidth, naturalHeight} = img
      @setState {naturalWidth, naturalHeight}
    img.src = src

  render: ->
    min = Math.min @state.naturalWidth, @state.naturalHeight

    width = min
    height = min

    if @props.aspectRatio < 1
      width = @props.aspectRatio * height
    else if @props.aspectRatio > 1
      height = @props.aspectRatio * width

    x = (@state.naturalWidth - width) / 2
    y = (@state.naturalHeight - height) / 2

    <svg viewBox="#{x} #{y} #{width} #{height}" {...@props}>
      <image ref="image" x="0" y="0" />
    </svg>

  componentDidUpdate: ->
    image = ReactDOM.findDOMNode @refs.image
    image.setAttribute 'width', @state.naturalWidth
    image.setAttribute 'height', @state.naturalHeight
    image.setAttributeNS @XLINK_NS, 'href', @props.src

React = require 'react'
ReactDOM = require 'react-dom'

module.exports = React.createClass
  XLINK_NS: 'http://www.w3.org/1999/xlink'

  getDefaultProps: ->
    src: ''
    aspectRatio: NaN

  getInitialState: ->
    naturalWidth: 0
    naturalHeight: 0

  componentDidMount: ->
    @loadImage @props.src

  componentWillReceiveProps: (nextProps) ->
    unless nextProps.src is @props.src
      @loadImage nextProps.src

  loadImage: (src) ->
    img = new Image
    img.onload = =>
      {naturalWidth, naturalHeight} = img
      @setState {naturalWidth, naturalHeight}
    img.src = src

  render: ->
    min = Math.min @state.naturalWidth, @state.naturalHeight

    width = min
    height = min

    if @props.aspectRatio < 1
      width = @props.aspectRatio * height
    else if @props.aspectRatio > 1
      height = @props.aspectRatio * width

    x = (@state.naturalWidth - width) / 2
    y = (@state.naturalHeight - height) / 2

    <svg viewBox="#{x} #{y} #{width} #{height}" src={@props.src} width={@props.width} height={@props.height}>
      <image ref="image" x="0" y="0" />
    </svg>

  componentDidUpdate: ->
    image = ReactDOM.findDOMNode @refs.image
    image.setAttribute 'width', @state.naturalWidth
    image.setAttribute 'height', @state.naturalHeight
    image.setAttributeNS @XLINK_NS, 'href', @props.src

Fix unknown props on croppedImage svg

Fix unknown props on croppedImage svg


sysPath     = require 'path'
compileHBS  = require './ember-handlebars-compiler'

module.exports = class EmberHandlebarsCompiler
  brunchPlugin: yes
  type: 'template'
  extension: 'hbs'
  precompile: off
  root: null
  modulesPrefix: 'module.exports = '

  constructor: (@config) ->
    if @config.files.templates.precompile is on
      @precompile = on
    if @config.files.templates.root?
      @root = sysPath.join 'app', @config.files.templates.root, sysPath.sep
    if @config.modules.wrapper is off
      @modulesPrefix = ''
    null

  compile: (data, path, callback) ->
    try
      tmplPath = path.replace @root, ''
      tmplPath = tmplPath.replace /\\/g, '/'
      tmplPath = tmplPath.substr 0, tmplPath.length - sysPath.extname(tmplPath).length
      tmplName = "Ember.TEMPLATES['#{tmplPath}']"
      if @precompile is on
        content = compileHBS data.toString()
        result = "#{@modulesPrefix}#{tmplName} = Ember.Handlebars.template(#{content});"
      else
        content = JSON.stringify data.toString()
        result = "#{@modulesPrefix}#{tmplName} = Ember.Handlebars.compile(#{content});"
    catch err
      error = err
    finally
      callback error, result

sysPath     = require 'path'
compileHBS  = require './ember-handlebars-compiler'

module.exports = class EmberHandlebarsCompiler
  brunchPlugin: yes
  type: 'template'
  extension: 'hbs'
  precompile: off
  root: null
  modulesPrefix: 'module.exports = '

  constructor: (@config) ->
    if @config.files.templates.precompile is on
      @precompile = on
    if @config.files.templates.root?
      @root = sysPath.join 'app', @config.files.templates.root, sysPath.sep
    if @config.modules.wrapper is off
      @modulesPrefix = ''
    if @config.files.templates.defaultExtension?
      @extension = @config.files.templates.defaultExtension
    null

  compile: (data, path, callback) ->
    try
      tmplPath = path.replace @root, ''
      tmplPath = tmplPath.replace /\\/g, '/'
      tmplPath = tmplPath.substr 0, tmplPath.length - sysPath.extname(tmplPath).length
      tmplName = "Ember.TEMPLATES['#{tmplPath}']"
      if @precompile is on
        content = compileHBS data.toString()
        result = "#{@modulesPrefix}#{tmplName} = Ember.Handlebars.template(#{content});"
      else
        content = JSON.stringify data.toString()
        result = "#{@modulesPrefix}#{tmplName} = Ember.Handlebars.compile(#{content});"
    catch err
      error = err
    finally
      callback error, result

Use the configured default extension

Use the configured default extension

Right now the code does not take defaultExtension into account.


exports.config = (config) ->
  # File path glob patterns.
  # All file paths matching these glob patterns will be watched for changes,
  # and when they are detected, the matching URL cache will be expired.
  config.watch "app/assets/**"
  config.watch "vendor/assets/**"

  # Match file paths to their corresponding URLs.
  # The first argument is the match pattern, and the second argument is the
  # translation function. Any captures made by the matching pattern will be
  # passed into the translation function in the order they are matched. The
  # returned URL String from the translation function will be used to expire
  # the cache for that URL.
  config.match ':location/assets/javascripts/*', javascript_path
  config.match ':location/assets/stylesheets/*', stylesheet_path

  # Establish a white list of URL Strings of the paths to cache.
  # If an incoming request URL does not match an include pattern, it will not
  # be cached and will be simply reverse proxied to the server.
  config.include /\.js$/

  return

javascript_path = (location, filepath) ->
  return "/assets/#{filepath}?body=1"

stylesheet_path = (location, filepath) ->
  return "/assets/application.css?body=1"

exports.config = (config) ->
  # File path glob patterns.
  # All file paths matching these glob patterns will be watched for changes,
  # and when they are detected, the matching URL cache will be expired.
  config.watch "app/assets/**"
  config.watch "vendor/assets/**"

  # Match file paths to their corresponding URLs.
  # The first argument is the match pattern, and the second argument is the
  # translation function. Any captures made by the matching pattern will be
  # passed into the translation function in the order they are matched. The
  # returned URL String from the translation function will be used to expire
  # the cache for that URL.
  config.match ':location/assets/javascripts/*', javascript_path
  config.match ':location/assets/stylesheets/*', stylesheet_path

  # Establish a white list of URL Strings of the paths to cache.
  # If an incoming request URL does not match an include pattern, it will not
  # be cached and will be simply reverse proxied to the server.
  config.include /\.js\?body=1$/
  config.include /\.css\?body=1$/
  config.include /\.(jpg|jpeg|gif|png|svg)$/i

  return

javascript_path = (location, filepath) ->
  return "/assets/#{filepath}?body=1"

stylesheet_path = (location, filepath) ->
  return "/assets/application.css?body=1"

Add white list to Rails example config

Add white list to Rails example config

	modified:   examples/rails.coffee


{View} = require 'space-pen'
$ = require 'jquery'
_ = nodeRequire 'underscore'

module.exports =
class WrapGuideView extends View
  @activate: ->
    rootView.eachEditor (editor) ->
      editor.underlayer.append(new WrapGuideView(editor)) if editor.attached

  @content: ->
    @div class: 'wrap-guide'

  initialize: (@editor) ->
    @observeConfig 'editor.fontSize', => @updateGuide()
    @subscribe @editor, 'editor:path-changed', => @updateGuide()
    @subscribe @editor, 'editor:min-width-changed', => @updateGuide()
    @subscribe $(window), 'resize', => @updateGuide()

  getDefaultColumn: ->
    config.get('editor.preferredLineLength') ? 80

  getGuideColumn: (path) ->
    customColumns = config.get('wrapGuide.columns')
    return @getDefaultColumn() unless _.isArray(customColumns)
    for customColumn in customColumns
      continue unless _.isObject(customColumn)
      pattern = customColumn['pattern']
      continue unless pattern
      return parseInt(customColumn['column']) if new RegExp(pattern).test(path)
    @getDefaultColumn()

  updateGuide: ->
    column = @getGuideColumn(@editor.getPath(), @defaultColumn)
    if column > 0
      columnWidth = @editor.charWidth * column
      if columnWidth < @editor.layerMinWidth or columnWidth < @editor.width()
        @css('left', columnWidth).show()
      else
        @hide()
    else
      @hide()

{View} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'

module.exports =
class WrapGuideView extends View
  @activate: ->
    rootView.eachEditor (editor) ->
      editor.underlayer.append(new WrapGuideView(editor)) if editor.attached

  @content: ->
    @div class: 'wrap-guide'

  initialize: (@editor) ->
    @observeConfig 'editor.fontSize', => @updateGuide()
    @subscribe @editor, 'editor:path-changed', => @updateGuide()
    @subscribe @editor, 'editor:min-width-changed', => @updateGuide()
    @subscribe $(window), 'resize', => @updateGuide()

  getDefaultColumn: ->
    config.get('editor.preferredLineLength') ? 80

  getGuideColumn: (path) ->
    customColumns = config.get('wrapGuide.columns')
    return @getDefaultColumn() unless _.isArray(customColumns)
    for customColumn in customColumns
      continue unless _.isObject(customColumn)
      pattern = customColumn['pattern']
      continue unless pattern
      return parseInt(customColumn['column']) if new RegExp(pattern).test(path)
    @getDefaultColumn()

  updateGuide: ->
    column = @getGuideColumn(@editor.getPath(), @defaultColumn)
    if column > 0
      columnWidth = @editor.charWidth * column
      if columnWidth < @editor.layerMinWidth or columnWidth < @editor.width()
        @css('left', columnWidth).show()
      else
        @hide()
    else
      @hide()

Use node's require instead of internal require


"*":
  editor:
    showIndentGuide: true
    fontFamily: "Inconsolata"
    invisibles: {}
    scrollPastEnd: true
    softWrap: true
    softWrapAtPreferredLineLength: true
    preferredLineLength: 100
  core:
    ignoredNames: [
      ".bundle"
      ".git"
      "log"
      "repositories"
      "tmp"
      "vendor"
    ]
    hideGitIgnoredFiles: true
    disabledPackages: [
      "background-tips"
      "exception-reporting"
      "metrics"
      "latexer"
    ]
  "spell-check":
    grammars: [
      "text.plain"
      "source.gfm"
      "text.git-commit"
    ]
  welcome:
    showOnStartup: false
  "release-notes":
    viewedVersion: "0.89.0"
  "autocomplete-bibtex":
    bibtex: [
      "/Users/briandanielak/Documents/bibtex/2015-10-21-zotero-library/2015-10-21-zotero-library.bib"
    ]
  "autocomplete-plus": {}
  Zen:
    softWrap: true
    typewriter: true
    minimap: true
    width: 140
  "markdown-table-formatter": {}
  latex: {}
  "make-runner": {}

"*":
  editor:
    showIndentGuide: true
    fontFamily: "Inconsolata"
    invisibles: {}
    scrollPastEnd: true
    softWrap: true
    softWrapAtPreferredLineLength: true
    preferredLineLength: 100
    fontSize: 16
  core:
    ignoredNames: [
      ".bundle"
      ".git"
      "log"
      "repositories"
      "tmp"
      "vendor"
    ]
    hideGitIgnoredFiles: true
    disabledPackages: [
      "background-tips"
      "exception-reporting"
      "metrics"
      "latexer"
    ]
  "spell-check":
    grammars: [
      "text.plain"
      "source.gfm"
      "text.git-commit"
    ]
  welcome:
    showOnStartup: false
  "release-notes":
    viewedVersion: "0.89.0"
  "autocomplete-bibtex":
    bibtex: [
      "/Users/brian/dev/JLS-Manuscript-Rebecca-Study/Drafts/bibliography.bib"
    ]
  "autocomplete-plus": {}
  Zen:
    softWrap: true
    typewriter: true
    minimap: true
    width: 140
  "markdown-table-formatter": {}
  latex: {}
  "make-runner": {}
  minimap:
    plugins:
      "highlight-selected": true

Set default BibTeX library in Atom

Set default BibTeX library in Atom


linterPath = atom.packages.getLoadedPackage("linter").path
Linter = require "#{linterPath}/lib/linter"
{CompositeDisposable} = require 'atom'

class LinterPhp extends Linter
  # The syntax that the linter handles. May be a string or
  # list/tuple of strings. Names should be all lowercase.
  @syntax: ['text.html.php', 'source.php']

  # A string, list, tuple or callable that returns a string, list or tuple,
  # containing the command line (with arguments) used to lint.
  cmd: 'php -l -n -d display_errors=On -d log_errors=Off'

  executablePath: null

  linterName: 'php'

  # A regex pattern used to extract information from the executable's output.
  regex: '(Parse|Fatal) (?<error>error):(\\s*(?<type>parse|syntax) error,?)?\\s*' +
         '(?<message>(unexpected \'(?<near>[^\']+)\')?.*) ' +
         'in .*? on line (?<line>\\d+)'

  constructor: (editor) ->
    super(editor)
    @disposables = new CompositeDisposable

    @disposables.add atom.config.observe 'linter-php.phpExecutablePath', =>
      @executablePath = atom.config.get 'linter-php.phpExecutablePath'

  destroy: ->
    # atom.config.unobserve 'linter-php.phpExecutablePath'
    @disposables.dispose();

  createMessage: (match) ->
    # message might be empty, we have to supply a value
    if match and match.type == 'parse' and not match.message
      message = 'parse error'
    super(match)

module.exports = LinterPhp

linterPath = atom.packages.getLoadedPackage("linter").path
Linter = require "#{linterPath}/lib/linter"
{CompositeDisposable} = require 'atom'

class LinterPhp extends Linter
  # The syntax that the linter handles. May be a string or
  # list/tuple of strings. Names should be all lowercase.
  @syntax: ['text.html.php', 'source.php']

  # A string, list, tuple or callable that returns a string, list or tuple,
  # containing the command line (with arguments) used to lint.
  cmd: 'php -l -n -d display_errors=On -d log_errors=Off'

  executablePath: null

  linterName: 'php'

  # A regex pattern used to extract information from the executable's output.
  regex: '(Parse|Fatal) (?<error>error):(\\s*(?<type>parse|syntax) error,?)?\\s*' +
         '(?<message>(unexpected \'(?<near>[^\']+)\')?.*) ' +
         'in .*? on line (?<line>\\d+)'

  constructor: (editor) ->
    super(editor)
    @disposables = new CompositeDisposable

    @disposables.add atom.config.observe 'linter-php.phpExecutablePath', =>
      @executablePath = atom.config.get 'linter-php.phpExecutablePath'

  destroy: ->
    @disposables.dispose()

  createMessage: (match) ->
    # message might be empty, we have to supply a value
    if match and match.type == 'parse' and not match.message
      message = 'parse error'
    super(match)

module.exports = LinterPhp

Remove commented out line and ;

Remove commented out line and ;


kd                    = require 'kd'
KDView                = kd.View
KDTabView             = kd.TabView
KDTabPaneView         = kd.TabPaneView
TeamMembersCommonView = require './teammemberscommonview.coffee'

module.exports = class AdminMembersView extends KDView

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

    options.cssClass = 'member-related'

    super options, data

    @createTabView()

  createTabView: ->

    data    = @getData()
    tabView = new KDTabView hideHandleCloseIcons: yes

    tabView.addPane allMembersPane     = new KDTabPaneView name: 'All Members'
    tabView.addPane adminsPane         = new KDTabPaneView name: 'Admins'
    tabView.addPane moderatorsPane     = new KDTabPaneView name: 'Moderators'
    tabView.addPane blockedMembersPane = new KDTabPaneView name: 'Blocked'

    allMembersPane.addSubView  new TeamMembersCommonView { fetcherMethod: 'fetchMembers'    }, data
    adminsPane.addSubView      new TeamMembersCommonView { fetcherMethod: 'fetchAdmins'     }, data
    moderatorsPane.addSubView  new TeamMembersCommonView { fetcherMethod: 'fetchModerators' }, data
    # blockedMembersPane.addSubView new TeamMembersView {}, data

    tabView.showPaneByIndex 0
    @addSubView tabView

kd                    = require 'kd'
KDView                = kd.View
KDTabView             = kd.TabView
KDTabPaneView         = kd.TabPaneView
TeamMembersCommonView = require './teammemberscommonview'
GroupsBlockedUserView = require '../groupsblockeduserview'

module.exports = class AdminMembersView extends KDView

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

    options.cssClass = 'member-related'

    super options, data

    @createTabView()

  createTabView: ->

    data    = @getData()
    tabView = new KDTabView hideHandleCloseIcons: yes

    tabView.addPane allMembersPane = new KDTabPaneView name: 'All Members'
    tabView.addPane adminsPane     = new KDTabPaneView name: 'Admins'
    tabView.addPane moderatorsPane = new KDTabPaneView name: 'Moderators'
    tabView.addPane blockedMembersPane = new KDTabPaneView name: 'Blocked'

    allMembersPane.addSubView  new TeamMembersCommonView { fetcherMethod: 'fetchMembers'    }, data
    adminsPane.addSubView      new TeamMembersCommonView { fetcherMethod: 'fetchAdmins'     }, data
    moderatorsPane.addSubView  new TeamMembersCommonView { fetcherMethod: 'fetchModerators' }, data
    blockedMembersPane.addSubView new GroupsBlockedUserView {}, data

    tabView.showPaneByIndex 0
    @addSubView tabView

AdminMembersView: Put current blocked users view into modal.


validateParameters = (params) ->
  result = {
    warnings: []
    errors: []
  }

  for paramName, param of params
    if param['required'] == true and (param['example'] == '' or param['example'] == undefined)
      text = "Required URI parameter '#{paramName}' has no example value."
      result['errors'].push text

    switch param['type']
      when 'string'
        unless isNaN(Number(String(param['example'])))
          text = "URI parameter '#{paramName}' is declared as 'string' but it is a number."
          result['errors'].push text
      when 'number'
        if isNaN(parseFloat(param['example']))
          text = "URI parameter '#{paramName}' is declared as 'number' but it is a string."
          result['errors'].push text
      when 'boolean'
        if param['example'] != 'true' or param['example'] != 'false'
          text = "URI parameter '#{paramName}' is decalred as 'boolean' but it is not. "
          result['errors'].push text

    if param['values'].length > 0
      values = param['values'].map (value) -> value['value']
      unless values.indexOf(param['example']) > -1
        text = "URI parameter '#{paramName}' example value is not one of enum values."
        result['errors'].push text

  return result

module.exports = validateParameters

validateParameters = (params) ->
  result = {
    warnings: []
    errors: []
  }

  for paramName, param of params
    if param['required'] == true and (param['example'] == '' or param['example'] == undefined)
      text = "Required URI parameter '#{paramName}' has no example value."
      result['errors'].push text

    switch param['type']
      when 'string'
        unless isNaN(Number(String(param['example'])))
          text = "URI parameter '#{paramName}' is declared as 'string' but it is a number."
          result['errors'].push text
      when 'number'
        if isNaN(parseFloat(param['example']))
          text = "URI parameter '#{paramName}' is declared as 'number' but it is a string."
          result['errors'].push text
      when 'boolean'
        if param['example'] != 'true' and param['example'] != 'false'
          text = "URI parameter '#{paramName}' is declared as 'boolean' but it is not. "
          result['errors'].push text

    if param['values'].length > 0
      values = param['values'].map (value) -> value['value']
      unless values.indexOf(param['example']) > -1
        text = "URI parameter '#{paramName}' example value is not one of enum values."
        result['errors'].push text

  return result

module.exports = validateParameters

Fix for boolean example validation.

Fix for boolean example validation.

Only fail when boolean example isn't true or false - previous version always failed (example can't be both true and false at the same time).


module.exports = (obj, methodName, key, logger) ->
	metrics = require('./metrics')

	if typeof obj[methodName] != 'function'
		throw new Error("[Metrics] expected object property '#{methodName}' to be a function")

	realMethod = obj[methodName]
	key = "methods.#{key}"

	obj[methodName] = (originalArgs...) ->

		[firstArgs..., callback] = originalArgs
		if !callback? || typeof callback != 'function'
			throw new Error(
				"[Metrics] expected wrapped method '#{methodName}' to be invoked with a callback"
			)

		timer = new metrics.Timer(key)
		start = new Date()

		realMethod.call this, firstArgs..., (callbackArgs...) ->
			timer.done()
			elapsedTime = new Date() - start
			if logger?
				logger.log {key, elapsedTime}, "[Metrics] timed async method call"
			callback.apply this, callbackArgs

module.exports = (obj, methodName, key, logger) ->
	metrics = require('./metrics')

	if typeof obj[methodName] != 'function'
		throw new Error("[Metrics] expected object property '#{methodName}' to be a function")

	realMethod = obj[methodName]
	key = "methods.#{key}"

	obj[methodName] = (originalArgs...) ->

		[firstArgs..., callback] = originalArgs
		if !callback? || typeof callback != 'function'
			throw new Error(
				"[Metrics] expected wrapped method '#{methodName}' to be invoked with a callback"
			)

		timer = new metrics.Timer(key)

		realMethod.call this, firstArgs..., (callbackArgs...) ->
			elapsedTime = timer.done()
			if logger?
				logger.log {key, elapsedTime}, "[Metrics] timed async method call"
			callback.apply this, callbackArgs

Clean up, don't allocate an extra date

Clean up, don't allocate an extra date


moment = require('moment')
config = require('./config')
util = require('util')

module.exports = (program) ->
  posts = []
  config.postsDb.createReadStream()
    .on('data', (data) ->
      write = true
      if program.year?
        unless moment(data.value.created_time).year() is program.year
          write = false
      if program.month?
        unless moment(data.value.created_time).month() is (program.month - 1) # Stupid JS dates
          write = false
      if write
        posts.push data.value
    )
    .on('error',  (err) ->
      console.log('LevelDB Error', err)
    )
    .on('close',  (err) ->
      console.log util.inspect(posts, { depth: null })
    )

moment = require('moment')
config = require('./config')

module.exports = (program) ->
  posts = []
  config.postsDb.createReadStream()
    .on('data', (data) ->
      write = true
      if program.year?
        unless moment(data.value.created_time).year() is program.year
          write = false
      if program.month?
        unless moment(data.value.created_time).month() is (program.month - 1) # Stupid JS dates
          write = false
      if write
        posts.push data.value
    )
    .on('error',  (err) ->
      console.log('LevelDB Error', err)
    )
    .on('close',  (err) ->
      console.log JSON.stringify(posts, null, 4)
    )

Write out actual JSON duh

Write out actual JSON duh


describe "DotLedger.Views.Transactions.Table", ->
  createView = ->
    collection =  new DotLedger.Collections.Transactions

    view = new DotLedger.Views.Transactions.Table
      collection: collection
    view

  it "should be defined", ->
    expect(DotLedger.Views.Transactions.Table).toBeDefined()

  it "should use the correct template", ->
    expect(DotLedger.Views.Transactions.Table).toUseTemplate('transactions/table')

  it "can be rendered", ->
    view = createView()
    expect(view.render).not.toThrow()

  it "renders the date label", ->
    view = createView().render()
    expect(view.$el).toContainText('Date')

  it "renders the name label", ->
    view = createView().render()
    expect(view.$el).toContainText('Name')

  it "renders the category label", ->
    view = createView().render()
    expect(view.$el).toContainText('Category')

  it "renders the spent label", ->
    view = createView().render()
    expect(view.$el).toContainText('Spent')

  it "renders the received label", ->
    view = createView().render()
    expect(view.$el).toContainText('Received')

Add tests for transactions table labels.


connect   = require 'connect'
express   = require 'express'
requisite = require 'requisite'
root      = require('./utils').root
stylus    = require 'stylus'

app = express()

app.set 'views', root '/views'
app.set 'view engine', 'jade'
app.locals.pretty = true

# Stylus middleware. Serves bunlded CSS/Stylus files from assets/css at
# static/css.
app.use '/static/css', stylus.middleware
  src: root '/assets/css'
  dest: root '/static/css'

# Express static middleware. Having this first in the middleware stack ensures
# that static js files are still served normally, instead of being bunlded by
# requisite.
app.use express.static root()

# Requisite middleware. Takes an entry module and bundles all dependencies
# required from there. Serves bundled JavaScript files from assets/js at
# static/js.
app.use '/static/js', requisite.middleware
  export: 'app'
  entry: root '/assets/js/app'
  paths: [root()]

app.use connect.logger 'dev'
app.use connect.errorHandler()

app.get '/', (req, res) ->
  res.render 'index'

module.exports = app

connect   = require 'connect'
express   = require 'express'
requisite = require 'requisite'
root      = require('./utils').root
stylus    = require 'stylus'

app = express()

app.set 'views', root '/views'
app.set 'view engine', 'jade'
app.locals.pretty = true

# Stylus middleware. Serves bunlded CSS/Stylus files from assets/css at
# static/css.
app.use '/static/css', stylus.middleware
  src: root 'assets/css'
  dest: root 'static/css'

# Express static middleware. Having this first in the middleware stack ensures
# that static js files are still served normally, instead of being bunlded by
# requisite.
app.use express.static root()

# Requisite middleware. Takes an entry module and bundles all dependencies
# required from there. Serves bundled JavaScript files from assets/js at
# static/js.
app.use '/static/js', requisite.middleware
  # Entry point for our client-side code is assets/js/app.coffee. The extension
  # is optional, requisite will figure it out.
  entry: root 'assets/js/app'

  # Export entry module globally as 'app'
  export: 'app'

  # Additional paths to look for required modules in
  paths: [root()]

app.use connect.logger 'dev'
app.use connect.errorHandler()

app.get '/', (req, res) ->
  res.render 'index'

module.exports = app

Add a few more comments in example.

Add a few more comments in example.


path        = require 'path'
fs          = require 'fs'
mkdirp      = require 'mkdirp'
MetaCoffee  = (require './prettyfier') require './index'

targetDirectory = process.argv[2]
fileName = process.argv[3]

code = fs.readFileSync fileName, "utf-8"
compiled = MetaCoffee.compile code

targetFileName = path.basename fileName, path.extname fileName

mkdirp.sync targetDirectory
fs.writeFileSync (path.join targetDirectory, targetFileName), compiled, "utf-8"

path        = require 'path'
fs          = require 'fs'
mkdirp      = require 'mkdirp'
MetaCoffee  = (require './prettyfier') require './index'

targetDirectory = process.argv[2]
fileName = process.argv[3]

code = fs.readFileSync fileName, "utf-8"
compiled = MetaCoffee.compile code

targetFileName = path.basename fileName, path.extname fileName

mkdirp.sync targetDirectory
fs.writeFileSync (path.join targetDirectory, targetFileName + '.js'), compiled, "utf-8"

Revert removal of js extension

Revert removal of js extension


angular.module('clurtch.components.tabs.find.controllers', [])

.controller 'FindCtrl', [
  '$scope'
  'Yelp'
  'SortTwoColumns'
  ($scope, Yelp, SortTwoColumns)->
    Yelp.get().success (data) ->
      $scope.items = $scope.sortTwoColumns data.businesses
]

angular.module('clurtch.components.tabs.find.controllers', [])

.controller 'FindCtrl', [
  '$scope'
  'Yelp'
  ($scope, Yelp)->
    Yelp.get().success (data) ->
      $scope.items = data.businesses
]

Remove tuple creation service in tab ctrl


React     = require('react/addons')
TestUtils = React.addons.TestUtils

module.exports =
  # Generates a shallow render for a given component with properties and children
  shallowRenderComponent: (component, props, children...) ->
    shallowRenderer = TestUtils.createRenderer()
    shallowRenderer.render(React.createElement(component, props,
      children.length > 1 ? children : children[0]))
    shallowRenderer.getRenderOutput()

TestUtils = React.addons.TestUtils

module.exports =
  renderComponent: (Component, props={}, state={}) ->
    component = TestUtils.renderIntoDocument(<Component {...props}/>)
    component.setState(state) unless state == {}
    component

  shallowRenderComponent: (component, props, children...) ->
    shallowRenderer = TestUtils.createRenderer()
    shallowRenderer.render(React.createElement(component, props,
      children.length > 1 ? children : children[0]))
    shallowRenderer.getRenderOutput()

Add test helper to render into document

Add test helper to render into document


{View} = require 'atom'

module.exports =
class CursorPositionView extends View
  @content: ->
    @div class: 'cursor-position inline-block'

  initialize: (@statusBar) ->
    @subscribe @statusBar, 'active-buffer-changed', @updateCursorPositionText
    @subscribe atom.workspaceView, 'cursor:moved', @updateCursorPositionText

  destroy: ->
    @remove()

  afterAttach: ->
    @updateCursorPositionText()

  updateCursorPositionText: =>
    editor = atom.workspace.getActiveEditor()
    if position = editor?.getCursorBufferPosition()
      @text("#{position.row + 1},#{position.column + 1}").show()
    else
      @hide()

{View} = require 'atom'

module.exports =
class CursorPositionView extends View
  @content: ->
    @div class: 'cursor-position inline-block', =>
      @span outlet: 'cursorPosition'

  initialize: (@statusBar) ->
    @subscribe @statusBar, 'active-buffer-changed', @updateCursorPositionText
    @subscribe atom.workspaceView, 'cursor:moved', @updateCursorPositionText

  destroy: ->
    @remove()

  afterAttach: ->
    @updateCursorPositionText()

  updateCursorPositionText: =>
    editor = atom.workspace.getActiveEditor()
    if position = editor?.getCursorBufferPosition()
      @cursorPosition.text("#{position.row + 1},#{position.column + 1}").show()
    else
      @cursorPosition.hide()

Use a span to hold the cursor position text

This fixes an issue where detaching and re-attaching the status bar
would cause the cursor position div not to be shown. The reason
why it wasn't shown is that it would get an inline display: block style
for some reason (overriding the display: inline-block), which breaks layout.
I'm guessing that this is a jQuery thing related to how it handles
hiding/showing DOM nodes.


angular.module("admin.utils").factory "StatusMessage", ->
  new class StatusMessage
    types:
      progress: {style: {color: '#ff9906'}}
      alert:    {style: {color: 'grey'}}
      notice:   {style: {color: 'grey'}}
      success:  {style: {color: '#9fc820'}}
      failure:  {style: {color: '#da5354'}}

    statusMessage:
      text: ""
      style: {}

    invalidMessage: ""

    setValidation: (isValid) ->
      if isValid
        StatusMessage.invalidMessage = ''
      else
        StatusMessage.invalidMessage = t("admin.form_invalid")

    active: ->
      @statusMessage.text != ''

    display: (type, text) ->
      @statusMessage.text = text
      @statusMessage.style = @types[type].style
      null

    clear: ->
      @statusMessage.text = ''
      @statusMessage.style = {}

angular.module("admin.utils").factory "StatusMessage", ->
  new class StatusMessage
    types:
      progress: {style: {color: '#ff9906'}}
      alert:    {style: {color: 'grey'}}
      notice:   {style: {color: 'grey'}}
      success:  {style: {color: '#9fc820'}}
      failure:  {style: {color: '#da5354'}}
      error:   {style: {color: '#da5354'}}

    statusMessage:
      text: ""
      style: {}

    invalidMessage: ""

    setValidation: (isValid) ->
      if isValid
        StatusMessage.invalidMessage = ''
      else
        StatusMessage.invalidMessage = t("admin.form_invalid")

    active: ->
      @statusMessage.text != ''

    display: (type, text) ->
      @statusMessage.text = text
      @statusMessage.style = @types[type].style
      null

    clear: ->
      @statusMessage.text = ''
      @statusMessage.style = {}

Add new "error" attribute in the StatusMessage

It is used by `admin/payments/services/stripe_elements.js.coffee`


ETahi.QuestionCheckComponent = ETahi.QuestionComponent.extend
  layoutName: 'components/question/check_component'
  multipleAdditionalData: false
  displayContent: Em.computed.alias('checked')

  checked: ((key, value, oldValue) ->
    if arguments.length > 1
      #setter
      @set('model.answer', value)
    else
      #getter
      answer = @get('model.answer')
      answer == 'true' || answer == true
  ).property('model.answer')

  actions:
    additionalDataAction: ()->
      @get('additionalData').pushObject({})

ETahi.QuestionCheckComponent = ETahi.QuestionComponent.extend
  layoutName: 'components/question/check_component'
  multipleAdditionalData: false
  displayContent: Em.computed.oneWay('checked')

  checked: ((key, value, oldValue) ->
    if arguments.length > 1
      #setter
      @set('model.answer', value)
    else
      #getter
      answer = @get('model.answer')
      answer == 'true' || answer == true
  ).property('model.answer')

  actions:
    additionalDataAction: ()->
      @get('additionalData').pushObject({})

Make the alias between checked and displayContent one way.

displayContent shouldn't be set via handlebars for the checkbox
component.  Setting it would cause the checked computed property to
evaluate before the task value was correctly set, and the model computed
property would explode.


window.Posts ?= {}

window.Posts.PostsFactory = ($http, $q)->

  fetchPosts = (page) ->
    params = {}
    angular.extend(params, {category: @filter.join(",")}) unless filterPresent()
    angular.extend(params, {page: page}) if page != 1
    angular.extend(params, {sort: @sort}) if @sort != "top"

    $http({method: "GET", cache: true, url: PostsFactory.url, params: params}).then (response) =>
      @posts = response.data.posts
      @categories = response.data.categories
      return $q.reject("CNF") unless _categoryExists(@categories, @filter)
      response

  fetchCategories = ->
    $http({method: "GET", cache: true, url: PostsFactory.url}).then (response) =>
      @categories = response.data.categories
      response

  setOptions = (options = {}) ->
    @sort = options.sort
    @filter = _.without(options.filter, "").sort()

  filterPresent = ->
    !_.isEmpty(@filter)

  _categoryExists = (categories, category) ->
    return true if _.isEmpty(category)
    !_.isEmpty(_.intersection(_.pluck(categories, 'slug'), category))

  PostsFactory =
    url: "#{window.UtisakApiUrl}/vesti"
    posts: @posts
    categories: @categories
    filter: @filter
    filterPresent: filterPresent
    fetchCategories: fetchCategories
    fetchPosts: fetchPosts
    setOptions: setOptions

window.Posts ?= {}

window.Posts.PostsFactory = ($http, $q)->

  fetchPosts = (page) ->
    params = {}
    angular.extend(params, {category: @filter.join(",")}) if @filterPresent()
    angular.extend(params, {page: page}) if page != 1
    angular.extend(params, {sort: @sort}) if @sort != "top"

    $http({method: "GET", cache: true, url: PostsFactory.url, params: params}).then (response) =>
      @posts = response.data.posts
      @categories = response.data.categories
      return $q.reject("CNF") unless _categoryExists(@categories, @filter)
      response

  fetchCategories = ->
    $http({method: "GET", cache: true, url: PostsFactory.url}).then (response) =>
      @categories = response.data.categories
      response

  setOptions = (options = {}) ->
    @sort = options.sort
    @filter = _.without(options.filter, "").sort()

  filterPresent = ->
    !_.isEmpty(@filter)

  _categoryExists = (categories, category) ->
    return true if _.isEmpty(category)
    !_.isEmpty(_.intersection(_.pluck(categories, 'slug'), category))

  PostsFactory =
    url: "#{window.UtisakApiUrl}/vesti"
    posts: @posts
    categories: @categories
    filter: @filter
    filterPresent: filterPresent
    fetchCategories: fetchCategories
    fetchPosts: fetchPosts
    setOptions: setOptions

Fix parsing filter for API requests

Fix parsing filter for API requests


Authenticate:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
SubscriptionList:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
      on:
        204: 'check-configure-whitelist'
    'check-configure-whitelist':
      task: 'meshblu-core-task-check-configure-whitelist'
      datastoreCollection: 'devices'
      on:
        204: 'get-subscriptions'
    'get-subscriptions':
      task: 'meshblu-core-task-get-subscriptions'
      datastoreCollection: 'subscriptions'
UpdateDevice:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
      on:
        204: 'check-configure-whitelist'
    'check-configure-whitelist':
      task: 'meshblu-core-task-check-configure-whitelist'
      datastoreCollection: 'devices'
      on:
        204: 'update-device'
    'update-device':
      task: 'meshblu-core-task-update-device'
      datastoreCollection: 'devices'
      on:
        678: 'clear-device-in-cache'
    'clear-device-in-cache':
      task: 'meshblu-core-task-clear-device-in-cache'
      cacheNamespace: 'cache:device'

Authenticate:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
SubscriptionList:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
      on:
        204: 'check-configure-whitelist'
    'check-configure-whitelist':
      task: 'meshblu-core-task-check-configure-whitelist'
      datastoreCollection: 'devices'
      on:
        204: 'get-subscriptions'
    'get-subscriptions':
      task: 'meshblu-core-task-get-subscriptions'
      datastoreCollection: 'subscriptions'
UpdateDevice:
  start: 'authenticate'
  tasks:
    'authenticate':
      filter: 'Authenticate'
      on:
        204: 'check-configure-whitelist'
    'check-configure-whitelist':
      task: 'meshblu-core-task-check-configure-whitelist'
      datastoreCollection: 'devices'
      on:
        204: 'check-update-device-is-valid'
    'check-update-device-is-valid':
      task: 'meshblu-core-task-check-update-device-is-valid'
      on:
        204: 'update-device'
    'update-device':
      task: 'meshblu-core-task-update-device'
      datastoreCollection: 'devices'
      on:
        678: 'clear-device-in-cache'
    'clear-device-in-cache':
      task: 'meshblu-core-task-clear-device-in-cache'
      cacheNamespace: 'cache:device'

Add update device valid check

Add update device valid check


'menu': [
  'label': 'Edit'
  'submenu': [
    'label': 'Select Grammar'
    'command': 'grammar-selector:show'
  ]
]

'context-menu':
  '.overlayer': [
    'label': 'Change Grammar'
    'command': 'grammar-selector:show'
  ]

Add change item to editor context menu

Add change item to editor context menu


###
WebSocket Interface for the WebSocketRails client.
###
class WebSocketRails.WebSocketConnection

  constructor: (@url,@dispatcher) ->
    @_conn           = new WebSocket("ws://#{@url}")
    @_conn.onmessage = @on_message
    @_conn.onclose   = @on_close

  trigger: (event_name, data, connection_id) =>
    payload = JSON.stringify [event_name, data]
    @_conn.send payload

  trigger_channel: (channel_name, event_name, data, connection_id) =>
    payload = JSON.stringify [channel_name, event_name, data]
    @_conn.send payload

  on_message: (event) =>
    data = JSON.parse event.data
    console.log data
    @dispatcher.new_message data

  on_close: (event) =>
    @dispatcher.dispatch 'connection_close', {}

###
WebSocket Interface for the WebSocketRails client.
###
class WebSocketRails.WebSocketConnection

  constructor: (@url,@dispatcher) ->
    @url             = "ws://#{@url}" unless @url.match(/^wss?:\/\//)
    @_conn           = new WebSocket(@url)
    @_conn.onmessage = @on_message
    @_conn.onclose   = @on_close

  trigger: (event_name, data, connection_id) =>
    payload = JSON.stringify [event_name, data]
    @_conn.send payload

  trigger_channel: (channel_name, event_name, data, connection_id) =>
    payload = JSON.stringify [channel_name, event_name, data]
    @_conn.send payload

  on_message: (event) =>
    data = JSON.parse event.data
    console.log data
    @dispatcher.new_message data

  on_close: (event) =>
    @dispatcher.dispatch 'connection_close', {}

Allow urls that already have the ws:// scheme, add it if it's missing. This also allows for wss:// for websockets over ssl.


# Keybindings require three things to be fully defined: A selector that is
# matched against the focused element, the keystroke and the command to
# execute.
#
# Below is a basic keybinding which registers on all platforms by applying to
# the root workspace element.

# For more detailed documentation see
# https://atom.io/docs/latest/advanced/keymaps
'.workspace':
  'ctrl-alt-b': 'latex:build'

'.editor':
  'ctrl-alt-b': 'latex:build'

Change keymap selector from `.workspace` to `.editor`


_ = require "underscore"

Markup = require "./markup"
p = require "../../core/properties"

class DivView extends Markup.View
  tagName: "div"

  render: () ->
    super()
    if @mget('render_as_text') == true
        @$el.text(@mget('text'))
    else
        @$el.html(@mget('text'))
    return @

class Div extends Markup.Model
  type: "Div"
  default_view: DivView

  props: () ->
    return _.extend {}, super(), {
      render_as_text: [ p.Bool,   false]
    }

module.exports =
  Model: Div
  View: DivView

Adjust the white space to make the linter happy


define(['listener'], (Listener) ->
  class SinglePlayerListener extends Listener
    notify: (player1, player2, point) ->
     console.log "Collision: #{player1} #{player2} #{point}"
     @game.killPlayer(player2, point)

  SinglePlayerListener
)

define(['listener'], (Listener) ->
  class SinglePlayerListener extends Listener
    notify: (player1, player2, point) ->
     console.log "Collision: #{player1.name} #{player2.name} #{point}"
     @game.runAfterTick((game) -> game.killPlayer(player2, point))

  SinglePlayerListener
)

Kill player after current tick in SinglePlayerListener


path = require "path"

module.exports =
  repoForPath: (goalPath) ->
    for projectPath, i in atom.project.getPaths()
      if goalPath is projectPath or goalPath.indexOf(projectPath + path.sep) is 0
        return atom.project.getRepositories()[i]
    null

  getStyleObject: (el) ->
    styleProperties = window.getComputedStyle(el)
    styleObject = {}
    for property of styleProperties
      value = styleProperties.getPropertyValue property
      camelizedAttr = property.replace /\-([a-z])/g, (a, b) -> b.toUpperCase()
      styleObject[camelizedAttr] = value
    styleObject

  getFullExtension: (filePath) ->
    basename = path.basename(filePath)
    position = basename.indexOf('.')
    if position > 0 then basename[position..] else ''

  updateEditorsForPath: (oldPath, newPath) ->
    editors = atom.workspace.getTextEditors()
    for editor in editors
      filePath = editor.getPath()
      if filePath?.startsWith(oldPath)
        editor.getBuffer().setPath(filePath.replace(oldPath, newPath))

Remove function accidentally committed with merge


goog.provide 'app.Routes'

goog.require 'este.Routes'

class app.Routes extends este.Routes

  ###*
    @constructor
    @extends {este.Routes}
  ###
  constructor: ->
    super()
    @home = new este.Route '/', Routes.MSG_HOME
    @newSong = new este.Route '/@me/songs/new', Routes.MSG_NEW_SONG
    @song = new este.Route '/@me/songs/:urlArtist/:urlName', 'Routes.MSG_NEW_SONG'
    @notFound = new este.Route '*'

    @list = [
      @home
      @newSong
      @song
      @notFound
    ]

  ###*
    @desc app.Routes
  ###
  @MSG_HOME: goog.getMsg 'Songary | Your personal songbook'

  ###*
    @desc app.Routes
  ###
  @MSG_NEW_SONG: goog.getMsg 'New Song | Songary'

  # ###*
  #   @desc app.Routes
  # ###
  # @MSG_SONG: goog.getMsg '{$songName} - {$artist} | Songary'

goog.provide 'app.Routes'

goog.require 'este.Routes'

class app.Routes extends este.Routes

  ###*
    @param {app.Storage} storage
    @constructor
    @extends {este.Routes}
  ###
  constructor: (@storage) ->
    super()

    @home = @route '/'
    @newSong = @route '/@me/songs/new'
    @song = @route '/@me/songs/:urlArtist/:urlName'
    @notFound = @route '*'

Update app.Routes to new este.Routes. Simply!


PEG = require 'pegjs'
{fs} = require 'atom'
grammarSrc = fs.read(require.resolve('./snippet-body.pegjs'))
module.exports = PEG.buildParser(grammarSrc, trackLineAndColumn: true)

PEG = require 'pegjs'
{fs} = require 'atom'
grammarSrc = fs.readFileSync(require.resolve('./snippet-body.pegjs'), 'utf8')
module.exports = PEG.buildParser(grammarSrc, trackLineAndColumn: true)

Use fs::readFileSync instead of deprecated fs::read


class CursorPositionView extends HTMLElement
  initialize: ->
    @classList.add('cursor-position', 'inline-block')

    @activeItemSubscription = atom.workspace.onDidChangeActivePaneItem (activeItem) =>
      @subscribeToActiveTextEditor()

    @subscribeToActiveTextEditor()

  destroy: ->
    @activeItemSubscription.dispose()
    @cursorSubscription?.dispose()

  subscribeToActiveTextEditor: ->
    @cursorSubscription?.dispose()
    @cursorSubscription = @getActiveTextEditor()?.onDidChangeCursorPosition =>
      @updatePosition()
    @updatePosition()

  getActiveTextEditor: ->
    atom.workspace.getActiveTextEditor()

  updatePosition: ->
    if position = @getActiveTextEditor()?.getCursorBufferPosition()
      @textContent = "#{position.row + 1}:#{position.column + 1}"
    else
      @textContent = ''

module.exports = document.registerElement('status-bar-cursor', prototype: CursorPositionView.prototype, extends: 'div')

class CursorPositionView extends HTMLElement
  initialize: ->
    @classList.add('cursor-position', 'inline-block')

    @activeItemSubscription = atom.workspace.onDidChangeActivePaneItem (activeItem) =>
      @subscribeToActiveTextEditor()

    @subscribeToActiveTextEditor()

    @tooltip = atom.tooltips.add(this, title: "Line x, Column y")

  destroy: ->
    @activeItemSubscription.dispose()
    @cursorSubscription?.dispose()
    @tooltip.dispose()

  subscribeToActiveTextEditor: ->
    @cursorSubscription?.dispose()
    @cursorSubscription = @getActiveTextEditor()?.onDidChangeCursorPosition =>
      @updatePosition()
    @updatePosition()

  getActiveTextEditor: ->
    atom.workspace.getActiveTextEditor()

  updatePosition: ->
    if position = @getActiveTextEditor()?.getCursorBufferPosition()
      row = position.row + 1
      column = position.column + 1
      @textContent = "#{row}:#{column}"
      @tooltip?.dispose()
      @tooltip = atom.tooltips.add(this, title: "Line #{row}, Column #{column}")
    else
      @textContent = ''
      @tooltip?.dispose()

module.exports = document.registerElement('status-bar-cursor', prototype: CursorPositionView.prototype, extends: 'div')

Add tooltip to cursor position status

Add tooltip to cursor position status


Chaplin = require 'chaplin'

module.exports = class BaseView extends Chaplin.View

  autoRender: true

  getTemplateFunction: -> @template

  delegateNewEvents: (events) ->
    @_delegateEvents events

  # This is different from Chaplin.View::dispose in that it doesn't try to
  # remove the el on disposal.
  dispose: ->
    return if @disposed

    throw new Error('Your `initialize` method must include a super call to
      Chaplin `initialize`') unless @subviews?

    # Dispose subviews
    subview.dispose() for subview in @subviews

    # Unbind handlers of global events
    @unsubscribeAllEvents()

    # Unbind all referenced handlers
    @stopListening()

    # Remove all event handlers on this module
    @off()

    # Remove all event handlers on view
    @undelegateEvents()

    # Remove element references, options,
    # model/collection references and subview lists
    properties = [
      'el', '$el',
      'options', 'model', 'collection',
      'subviews', 'subviewsByName',
      '_callbacks'
    ]
    delete this[prop] for prop in properties

    # Finished
    @disposed = true

    # You’re frozen when your heart’s not open
    Object.freeze? this

Chaplin = require 'chaplin'

module.exports = class BaseView extends Chaplin.View

  autoRender: true

  getTemplateFunction: -> @template

  delegateNewEvents: (events) ->
    @_delegateEvents events

  render: ->

    super

    if @bindings
      @stickit()

    @

  # This is different from Chaplin.View::dispose in that it doesn't try to
  # remove the el on disposal.
  dispose: ->
    return if @disposed

    throw new Error('Your `initialize` method must include a super call to
      Chaplin `initialize`') unless @subviews?

    # Dispose subviews
    subview.dispose() for subview in @subviews

    # Unbind handlers of global events
    @unsubscribeAllEvents()

    # Unbind all referenced handlers
    @stopListening()

    # Remove all event handlers on this module
    @off()

    # Remove all event handlers on view
    @undelegateEvents()

    # Remove element references, options,
    # model/collection references and subview lists
    properties = [
      'el', '$el',
      'options', 'model', 'collection',
      'subviews', 'subviewsByName',
      '_callbacks'
    ]
    delete this[prop] for prop in properties

    # Finished
    @disposed = true

    # You’re frozen when your heart’s not open
    Object.freeze? this

Call @stickit() at end of default View render if bindings available


$(document).ready ->
  quick_add_url_button = $('#quick-add-url-button')
  input = $('#quick-add-url')
  status = quick_add_url_button

  quick_add_url_button.click ->
    status.text('Submitting URL')
    url = input.val()

    $.ajax '/src_images/',
      type: 'post'
      contentType: 'application/json'
      dataType: 'json'
      data: JSON.stringify(url: url)
      success: (data) ->
        status.text('Submitted URL')
        count = 0
        timer = setInterval ->
          $.ajax "/src_images/#{data.id}",
            type: 'head',
            success: ->
              clearInterval(timer)
              window.location.replace("/gend_images/new?src=#{data.id}")
            error: ->
              clearInterval(timer)
              status.text('Error loading URL')
          count += 1
          if count >= 10
            clearInterval(timer)
        , 1000
      error: ->
        status.text('Error submitting URL')

  input.keypress (e) ->
    if e.which == 13
      quick_add_url_button.click()

$(document).ready ->
  quick_add_url_button = $('#quick-add-url-button')
  input = $('#quick-add-url')
  status = quick_add_url_button

  quick_add_url_button.click ->
    status.text('Submitting URL')
    url = input.val()

    $.ajax '/src_images/',
      type: 'post'
      contentType: 'application/json'
      dataType: 'json'
      data: JSON.stringify(url: url)
      success: (data) ->
        status.text('Submitted URL')
        count = 0
        timer = setInterval ->
          $.ajax "/src_images/#{data.id}",
            type: 'head',
            success: ->
              clearInterval(timer)
              window.location.replace("/gend_images/new?src=#{data.id}")
          count += 1
          if count >= 10
            clearInterval(timer)
            status.text('Error loading URL')
        , 1000
      error: ->
        status.text('Error submitting URL')

  input.keypress (e) ->
    if e.which == 13
      quick_add_url_button.click()

Fix bug in quick load url retry logic.

Fix bug in quick load url retry logic.


require './shim/phantomjs-bind'

window.Promise = require 'bluebird'
if process.env.NODE_ENV == 'development'
  Promise.longStackTraces()

window.Rdb = require('rdb/index')

require './shim/phantomjs-bind'

unless window.Promise?
  window.Promise = require 'bluebird'

  if process.env.NODE_ENV == 'development'
    Promise.longStackTraces()

window.Rdb = require('rdb/index')

Use bluebird only as polyfill

Use bluebird only as polyfill


class CMS.Views.ModuleEdit extends Backbone.View
  tagName: 'section'
  className: 'edit-pane'

  events:
    'click .cancel': 'cancel'
    'click .module-edit': 'editSubmodule'
    'click .save-update': 'save'

  initialize: ->
    @$el.load @model.editUrl(), =>
      @model.loadModule(@el)

      # Load preview modules
      XModule.loadModules('display')

  save: (event) ->
    event.preventDefault()
    @model.save().success(->
      alert("Your changes have been saved.")
    ).error(->
      alert("There was an error saving your changes. Please try again.")
    )

  cancel: (event) ->
    event.preventDefault()
    CMS.popView()

  editSubmodule: (event) ->
    event.preventDefault()
    previewType = $(event.target).data('preview-type')
    moduleType = $(event.target).data('type')
    CMS.pushView new CMS.Views.ModuleEdit
        model: new CMS.Models.Module
            id: $(event.target).data('id')
            type: if moduleType == 'None' then null else moduleType
            previewType: if previewType == 'None' then null else previewType

class CMS.Views.ModuleEdit extends Backbone.View
  tagName: 'section'
  className: 'edit-pane'

  events:
    'click .cancel': 'cancel'
    'click .module-edit': 'editSubmodule'
    'click .save-update': 'save'

  initialize: ->
    @$el.load @model.editUrl(), =>
      @model.loadModule(@el)

      # Load preview modules
      XModule.loadModules('display')

  save: (event) ->
    event.preventDefault()
    @model.save().done((previews) =>
      alert("Your changes have been saved.")
      previews_section = @$el.find('.previews').empty()
      $.each(previews, (idx, preview) =>
        preview_wrapper = $('<section/>', class: 'preview').append preview
        previews_section.append preview_wrapper
      )

      XModule.loadModules('display')
    ).fail(->
      alert("There was an error saving your changes. Please try again.")
    )

  cancel: (event) ->
    event.preventDefault()
    CMS.popView()

  editSubmodule: (event) ->
    event.preventDefault()
    previewType = $(event.target).data('preview-type')
    moduleType = $(event.target).data('type')
    CMS.pushView new CMS.Views.ModuleEdit
        model: new CMS.Models.Module
            id: $(event.target).data('id')
            type: if moduleType == 'None' then null else moduleType
            previewType: if previewType == 'None' then null else previewType

Update previews after a module is saved

Update previews after a module is saved


# Like sands through the hourglass, so are the days of our lives.
date = new Date().getTime()
require 'atom'
require 'window'

window.setUpEnvironment()
window.startup()
atom.show()
console.log "Load time: #{new Date().getTime() - date}"

# Like sands through the hourglass, so are the days of our lives.
date = new Date().getTime()
require 'atom'
require 'window'

window.setUpEnvironment()
window.startup()
setTimeout((-> atom.show()), 0)
console.log "Load time: #{new Date().getTime() - date}"

Call atom.show() from a setTimeout()

Call atom.show() from a setTimeout()

The window was previously flashing white if atom.show() was called
directly after window.startup()

Wrapping the call in a setTimeout with a zero delay seems to prevent
the white flash and the perceived amount of time to display the contents
appears to be the same.


LINES_TO_JUMP = 10

getEditSession = ->
  atom.workspaceView.getActiveView()?.activeEditSession

module.exports =
  activate: (state) ->
    atom.workspaceView.command 'line-jumper:move-up', =>
      getEditSession()?.moveCursorUp(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:move-down', =>
      getEditSession()?.moveCursorDown(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:select-up', =>
      getEditSession()?.selectUp(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:select-down', =>
      getEditSession()?.selectDown(LINES_TO_JUMP)

LINES_TO_JUMP = 10

getEditor = ->
  atom.workspaceView.getActiveView()?.editor

module.exports =
  activate: (state) ->
    atom.workspaceView.command 'line-jumper:move-up', =>
      getEditor()?.moveCursorUp(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:move-down', =>
      getEditor()?.moveCursorDown(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:select-up', =>
      getEditor()?.selectUp(LINES_TO_JUMP)

    atom.workspaceView.command 'line-jumper:select-down', =>
      getEditor()?.selectDown(LINES_TO_JUMP)

Update for api changes yet again.

Update for api changes yet again.


# The SplitStr component receives a string in the in port, splits it by
# string specified in the delimiter port, and send each part as a separate
# packet to the out port

noflo = require "../../lib/NoFlo"

class SplitStr extends noflo.Component
    constructor: ->
        @delimiterString = "\n"
        @strings = []
        @groups = []

        @inPorts =
            in: new noflo.Port()
            delimiter: new noflo.Port()
        @outPorts =
            out: new noflo.Port()
        @inPorts.delimiter.on "data", (data) =>
            if data.substr(0, 1) is '/' and data.substr(data.length - 1, 1) is '/'
                # Handle regular expressions
                data = new RegExp data.substr 1, data.length - 2
            @delimiterString = data
        @inPorts.in.on "begingroup", (group) =>
            @groups.push(group)
        @inPorts.in.on "data", (data) =>
            @strings.push data
        @inPorts.in.on "disconnect", (data) =>
            return @outPorts.out.disconnect() if @strings.length is 0
            for group in @groups
                @outPorts.out.beginGroup(group)
            @strings.join(@delimiterString).split(@delimiterString).forEach (line) =>
                @outPorts.out.send line
            for group in @groups
                @outPorts.out.endGroup()
            @outPorts.out.disconnect()
            @strings = []
            @groups = []

exports.getComponent = ->
    new SplitStr()

# The SplitStr component receives a string in the in port, splits it by
# string specified in the delimiter port, and send each part as a separate
# packet to the out port

noflo = require "../../lib/NoFlo"

class SplitStr extends noflo.Component
    constructor: ->
        @delimiterString = "\n"
        @strings = []
        @groups = []

        @inPorts =
            in: new noflo.Port()
            delimiter: new noflo.Port()
        @outPorts =
            out: new noflo.Port()
        @inPorts.delimiter.on "data", (data) =>
            if data.substr(0, 1) is '/' and data.substr(data.length - 1, 1) is '/' and data.length > 1
                # Handle regular expressions and not simply a slash
                data = new RegExp data.substr 1, data.length - 2
            @delimiterString = data
        @inPorts.in.on "begingroup", (group) =>
            @groups.push(group)
        @inPorts.in.on "data", (data) =>
            @strings.push data
        @inPorts.in.on "disconnect", (data) =>
            return @outPorts.out.disconnect() if @strings.length is 0
            for group in @groups
                @outPorts.out.beginGroup(group)
            @strings.join(@delimiterString).split(@delimiterString).forEach (line) =>
                @outPorts.out.send line
            for group in @groups
                @outPorts.out.endGroup()
            @outPorts.out.disconnect()
            @strings = []
            @groups = []

exports.getComponent = ->
    new SplitStr()

Allow for single slash to be a delimiter


# Description:
#   Rajinikanth is Chuck Norris of India, witness his awesomeness.
#
# Dependencies:
#   "cheerio": "0.7.0"
#
# Configuration:
#   None
#
# Commands:
#   hubot rajinikanth|rajini -- random Rajinikanth awesomeness
#   hubot rajinikanth|rajini me <user> -- let's see how <user> would do as Rajinikanth
#
# Author:
#   juzerali

cheerio = require('cheerio')
url = "http://rajinikanthfacts.com/"

module.exports = (robot) ->
  robot.respond /(rajinikanth|rajini)( me )?(.*)/i, (msg)->
    user = msg.match[3]
    msg.http(url)
      .get() (err, res, body) ->
        if err
          msg.send "Rajinikanth says: #{err}"
        else
          $ = cheerio.load(body)
          fact = $(".fact").find(".ftext").text()

          if !!user
            fact = fact.replace /raji?ni(kanth?)?/ig, user
          msg.send fact

# Description:
#   Rajinikanth is Chuck Norris of India, witness his awesomeness.
#
# Dependencies:
#   "cheerio": "0.7.0"
#
# Configuration:
#   None
#
# Commands:
#   hubot rajinikanth|rajini -- random Rajinikanth awesomeness
#   hubot rajinikanth|rajini me <user> -- let's see how <user> would do as Rajinikanth
#
# Author:
#   juzerali

cheerio = require('cheerio')
url = "http://rajinikanthfacts.com/"

module.exports = (robot) ->
  robot.respond /(?:rajinikanth|rajini)(?: me)? ?(.*)/i, (msg)->
    user = msg.match[1]
    msg.http(url)
      .get() (err, res, body) ->
        if err
          msg.send "Rajinikanth says: #{err}"
        else
          $ = cheerio.load(body)
          fact = $(".fact").find(".ftext").text()

          if !!user
            fact = fact.replace /raji?ni(kanth?)?/ig, user
          msg.send fact

Change the regex in such a way so that user's name is stripped automatically.

- Thanks to @technicalpickles


{APLArray} = require '../array'

@['⊃'] = (omega, alpha) ->
  if alpha

    # Pick (`⊃`)
    #
    # ⍬⊃3            <=> 3
    # 2⊃'PICK'       <=> 'C'
    # 1 0⊃2 2⍴'ABCD' <=> 'C'
    # 1⊃'foo' 'bar'  <=> 'bar'
    if alpha.shape.length > 1
      throw RankError
    pick = alpha.toArray()
    if pick.length isnt omega.shape.length
      throw RankError
    omega.get pick

  else

    # Disclose (`⊃`)
    #
    # ⊃(1 2 3)(4 5 6)   <=> 1 2 3
    # ⊃(1 2)(3 4 5)     <=> 1 2
    # ⊃'AB'             <=> 'A'
    # ⊃123              <=> 123
    # ⊃⍬                <=> 0
    #!    ⊃''               <=> ' '
    pick = []

  if omega.empty()
    APLArray.zero
  else
    x = omega.get pick
    if x instanceof APLArray then x else APLArray.scalar x

{APLArray} = require '../array'

@['⊃'] = (omega, alpha) ->
  if alpha

    # Pick (`⊃`)
    #
    # ⍬⊃3            <=> 3
    # 2⊃'PICK'       <=> 'C'
    # 1 0⊃2 2⍴'ABCD' <=> 'C'
    # 1⊃'foo' 'bar'  <=> 'bar'
    if alpha.shape.length > 1
      throw RankError
    pick = alpha.toArray()
    if pick.length isnt omega.shape.length
      throw RankError
    omega.get pick

  else

    # Disclose (`⊃`)
    #
    # ⊃(1 2 3)(4 5 6)   <=> 1 2 3
    # ⊃(1 2)(3 4 5)     <=> 1 2
    # ⊃'AB'             <=> 'A'
    # ⊃123              <=> 123
    # ⊃⍬                <=> 0
    #!    ⊃''               <=> ' '
    if omega.empty()
      return APLArray.zero
    pick = []

  x = omega.get pick
  if x instanceof APLArray then x else APLArray.scalar x

Fix pick into empty array.

Fix pick into empty array.


###
  jquery.turbolinks.js ~ v1.0.0-rc ~ https://github.com/kossnocorp/jquery.turbolinks

  jQuery plugin for drop-in fix binded events problem caused by Turbolinks

  The MIT License

  Copyright (c) 2012 Sasha Koss
###

$ = require?('jquery') || window.jQuery

# List for store callbacks passed to `$` or `$.ready`
callbacks = []

# Call each callback in list
ready = ->
  callback($) for callback in callbacks

# Turbolinks ready event
turbolinksReady = ->
  $.isReady = true
  ready()

# Fetch event handler
fetch = ->
  $(document).off(undefined, '**')
  $.isReady = false

# Bind `ready` to DOM ready event
$(ready)

# Store callbacks in list on `$` and `$.ready`
$.fn.ready = (callback) ->
  callbacks.push(callback)
  callback($) if $.isReady

# Bind ready to passed event
$.setReadyEvent = (event) ->
  $(document)
    .off('.turbolinks-ready')
    .on(event + '.turbolinks-ready', turbolinksReady)

# Bind fetch event
$.setFetchEvent = (event) ->
  $(document)
    .off('.turbolinks-fetch')
    .on(event + '.turbolinks-fetch', fetch)

# Bind `ready` to Tubolinks page:load
$.setReadyEvent('page:load')

# Bind fetch to Turbolinks page:fetch
$.setFetchEvent('page:fetch')

###
  jquery.turbolinks.js ~ v1.0.0-rc1 ~ https://github.com/kossnocorp/jquery.turbolinks

  jQuery plugin for drop-in fix binded events problem caused by Turbolinks

  The MIT License

  Copyright (c) 2012 Sasha Koss
###

$ = require?('jquery') || window.jQuery

# List for store callbacks passed to `$` or `$.ready`
callbacks = []

# Call each callback in list
ready = ->
  callback($) for callback in callbacks

# Turbolinks ready event
turbolinksReady = ->
  $.isReady = true
  ready()

# Fetch event handler
fetch = ->
  $(document).off(undefined, '**')
  $.isReady = false

# Bind `ready` to DOM ready event
$(ready)

# Store callbacks in list on `$` and `$.ready`
$.fn.ready = (callback) ->
  callbacks.push(callback)
  callback($) if $.isReady

# Bind ready to passed event
$.setReadyEvent = (event) ->
  $(document)
    .off('.turbolinks-ready')
    .on(event + '.turbolinks-ready', turbolinksReady)

# Bind fetch event
$.setFetchEvent = (event) ->
  $(document)
    .off('.turbolinks-fetch')
    .on(event + '.turbolinks-fetch', fetch)

# Bind `ready` to Tubolinks page:load
$.setReadyEvent('page:load')

# Bind fetch to Turbolinks page:fetch
$.setFetchEvent('page:fetch')

Set version in source file

Set version in source file


# # Kissmetrics Batch

class BatchKissmetricsClient
  @HOST: 'api.kissmetrics.com'
  @HTTP_METHOD: 'POST'
  @API_VERSION: 'v1'

  @process: (queue, apiKey, apiSecret, productGUID) ->
    http = require 'http'

    apiVersion = BatchKissmetricsClient.API_VERSION
    urlPath    = "#{apiVersion}/products/#{productGUID}/tracking/e"
    baseUrl    = "http://#{BatchKissmetricsClient.HOST}/#{urlPath}"
    signature  = BatchKissmetricsClient._generateSignature baseUrl, apiSecret
    # return "#{baseUrl}?_signature=#{signature}"

    request = http.request
      host: BatchKissmetricsClient.HOST
      path: "#{baseUrl}?_signature=#{signature}"
      headers:
        'X-KM-ApiKey': apiKey

    requestBody = JSON.stringify {data: queue.get()}
    request.write requestBody

    queue.clear()
    return request

  @_generateSignature: (url, apiSecret) ->
    'temporary-signature'

  constructor: (@options) ->
    @queue = options.queue

  add: (timestamp, data) ->
    data.timestamp = timestamp
    @_transformData data

    @queue.add data

  _transformData: (data) ->
    data.identity = data._p
    delete data._p

    if data.type is 'record'
      data.event = data._n
      delete data._n

    if data.type is 'alias'
      data.alias = data._n
      delete data._n

    delete data.type

module.exports = BatchKissmetricsClient

# # Kissmetrics Batch

class BatchKissmetricsClient
  @HOST: 'api.kissmetrics.com'
  @HTTP_METHOD: 'POST'
  @API_VERSION: 'v1'

  @process: (queue, apiKey, apiSecret, productGUID) =>
    http = require 'http'

    urlPath   = "#{@API_VERSION}/products/#{productGUID}/tracking/e"
    baseUrl   = "http://#{@HOST}/#{urlPath}"
    signature = @_generateSignature baseUrl, apiSecret

    request = http.request
      host: @HOST
      path: "#{baseUrl}?_signature=#{signature}"
      headers:
        'X-KM-ApiKey': apiKey

    requestBody = JSON.stringify {data: queue.get()}
    request.write requestBody

    queue.clear()
    return request

  @_generateSignature: (baseUrl, apiSecret) =>
    crypto = require 'crypto'
    signer = crypto.createHmac 'sha256', apiSecret

    encodedRequest = [@HTTP_METHOD, encodeURIComponent baseUrl].join('&')
    signer.update(encodedRequest).digest('base64')

  constructor: (@options) ->
    @queue = options.queue

  add: (timestamp, data) ->
    data.timestamp = timestamp
    @_transformData data

    @queue.add data

  _transformData: (data) ->
    data.identity = data._p
    delete data._p

    if data.type is 'record'
      data.event = data._n
      delete data._n

    if data.type is 'alias'
      data.alias = data._n
      delete data._n

    delete data.type

module.exports = BatchKissmetricsClient

Implement Kissmetrics' request signing and use context binding for static methods

Based on https://github.com/kissmetrics/uri_signer but simplified to the actual use case