reloadStylesheets = ->
  queryString = '?reload=' + new Date().getTime();
  $('link[rel="stylesheet"]').each ->
    @href = @href.replace(/\?.*|$/, queryString);

connect = (opts={}) ->
  # if user is running mozilla then use it's built-in WebSocket
  window.WebSocket ||= window.MozWebSocket

  connection = new WebSocket('ws://' + (opts.host || document.domain || 'localhost') + ':'+(opts.port || 8081))

  connection.onopen = ->
    console.log("Connected to watcher")

  connection.onerror = ->
    console.log("Unable to connect to watcher")

  connection.onmessage = (message) ->
    switch message
      when 'reload-css'
        reloadStylesheets()
      when 'reload-js'
        window.location.reload()

connect()

reloadStylesheets = ->
  queryString = '?reload=' + new Date().getTime();
  $('link[rel="stylesheet"]').each ->
    @href = @href.replace(/\?.*|$/, queryString);

connect = (opts={}) ->
  # if user is running mozilla then use it's built-in WebSocket
  window.WebSocket ||= window.MozWebSocket

  connection = new WebSocket('ws://' + (opts.host || document.domain || 'localhost') + ':'+(opts.port || 8081))

  connection.onopen = ->
    console.log("Connected to watcher")

  connection.onerror = ->
    console.log("Unable to connect to watcher")

  connection.onmessage = (message) ->
    switch message.data
      when 'reload-css'
        reloadStylesheets()
      when 'reload-js'
        window.location.reload()

connect()

Fix switch on wrong property

Fix switch on wrong property


Redis = require 'redis'
Url = require 'url'

POO_TRACKER_KEY = "poops"
POO_LATEST_KEY = "poops:latest_message"

info = Url.parse process.env.POO_REDIS_URL or "redis://localhost:6379/0"
redis_client = Redis.createClient(info.port, info.hostname)
redis_clent.auth info.auth.split(":")[1] if info.auth

module.exports = (robot) ->
  checkRedisForShit = ->
    redis_clent.lindex POO_TRACKER_KEY, -1, (err, reply) ->
      return console.error("Failed lindex with key '#{POO_TRACKER_KEY}' and index -1: #{err}") if err
      return if reply == null

      robot.messageRoom "#arrakis", "#{reply}"

      # clean up
      redis_clent.lrem POO_TRACKER_KEY, 0
      redis_clent.set POO_LATEST_KEY, reply

  robot.respond /poo tracker( me)?/i, (res) ->
    redis_client.get POO_LATEST_KEY, (err, reply) ->
      return console.error("Failed get with key '#{POO_TRACKER_KEY}': #{err}") if err
      return if reply == null
      return res.send "Latest poo: #{reply}"

  setInterval ->
    checkRedisForShit()
  , 1000

Redis = require 'redis'
Url = require 'url'

POO_TRACKER_KEY = "poops"
POO_LATEST_KEY = "poops:latest_message"

info = Url.parse process.env.POO_REDIS_URL or "redis://localhost:6379/0"
redis_client = Redis.createClient(info.port, info.hostname)
redis_clent.auth info.auth.split(":")[1] if info.auth

module.exports = (robot) ->
  checkRedisForShit = ->
    redis_clent.lindex POO_TRACKER_KEY, -1, (err, reply) ->
      return console.error("Failed lindex with key '#{POO_TRACKER_KEY}' and index -1: #{err}") if err
      return if reply == null

      room = process.env.HUBOT_IRC_ROOMS or "#arrakis"
      robot.messageRoom room, "#{reply}"

      # clean up
      redis_clent.lrem POO_TRACKER_KEY, 0
      redis_clent.set POO_LATEST_KEY, reply

  robot.respond /poo tracker( me)?/i, (res) ->
    redis_client.get POO_LATEST_KEY, (err, reply) ->
      return console.error("Failed get with key '#{POO_TRACKER_KEY}': #{err}") if err
      return if reply == null
      return res.send "Latest poo: #{reply}"

  setInterval ->
    checkRedisForShit()
  , 1000

Use the env for the room if available

Use the env for the room if available


# Include CSS in page
require('./catalog.scss')

# Load App
_ = require('lodash')
React = require('react')
{Routes, Route, Redirect} = require('react-router')
App = require('./components/App')
Page = require('./components/Page/Page')

window.Catalog = (config) ->
  defaultPageOptions =
    handler: Page
    iframe: config.iframe or false
    styles: config.styles or []

  router = Routes {location: 'hash'},
    Route _.extend({handler: App}, config),
      config.pages.map((page) ->
        Route _.extend(key: page.name, defaultPageOptions, page)
      ).concat(Redirect({key: 'not-found', from: '*', to: '/'}))

  React.renderComponent(router, document.body)

# Include CSS in page
require('./catalog.scss')

# Load App
_ = require('lodash')
React = require('react')
{Routes, Route, Redirect} = require('react-router')
App = require('./components/App')
Page = require('./components/Page/Page')

window.Catalog = (config) ->
  defaultPageOptions =
    handler: Page
    iframe: config.iframe or false
    styles: config.styles or []

  router = Routes {location: 'hash'},
    Route _.extend({key: 'root', handler: App}, config),
      config.pages.map (page) ->
        Route _.extend(key: page.name, defaultPageOptions, page)
    Redirect(from: '*', to: '/')

  React.renderComponent(router, document.body)

Fix missing key prop for redirect route handler


FiberUtils.synchronize = (guardObject, uniqueId, body, options={}) ->
  # Use the guard object to determine whether we have reentered.
  guards = guardObject._guards ?= {}
  guards[uniqueId] ?= new FiberUtils.OrderedFence options
  topLevel = guards[uniqueId].enter()

  try
    return body()
  finally
    guards[uniqueId].exit topLevel
    delete guards[uniqueId] if uniqueId of guards and not guards[uniqueId].isInUse()

Clean up guards when no fibers are waiting.


_ = require 'lodash'
direction = require './direction'

bindings = require '../key-bindings.json'

module.exports = exports = (game) ->
	game.on 'key.*', (ch, key) ->
		action = bindings[key.name ? key.full]

		if action?
			parts = action.split('.')

			if parts[0] is 'direction'
				parts[1] = direction.normalize parts[1], 1

			game.emit "action.#{parts.join '.'}", parts...

exports.bindings = bindings

_ = require 'lodash'
direction = require './direction'

bindings = require '../key-bindings.json'

module.exports = exports = (game) ->
	game.on 'key.*', (ch, key) ->
		action = bindings[key.full ? key.name]

		if action?
			parts = action.split('.')

			if parts[0] is 'direction'
				parts[1] = direction.normalize parts[1], 1

			game.emit "action.#{parts.join '.'}", parts...

exports.bindings = bindings

Use key.full before key.name for bindings


@CodequestManager = do (Backbone, Marionette) ->
  Marionette.Renderer.oldRender = Marionette.Renderer.render
  Marionette.Renderer.render = (template, data) ->
    template = template() if typeof template == 'function'

    unless JST[template]
      return Marionette.Renderer.oldRender(template, data)
    return JST[template](data)

  App = new Marionette.Application()

  App.Behaviors = {}

  App.currentUser = undefined

  App.pageSize = 10
  App.animationDurationMedium = 500

  App.on 'start', ->
    App.router = new App.Router
      controller: App.Controller

    App.root = new App.Root.Layout

    Marionette.Behaviors.behaviorsLookup = ->
      App.Behaviors
    App.currentUser = new App.Entities.User gon.currentUser
    App.vent.on 'reload:current:user', ->
      App.currentUser.fetch()
    $(document).foundation()

    App.Panel.Controller.showNavbar()

    Backbone.history.start
      pushState: true

    menuIcon = $('.menu-icon')
    navigation = $('.top-bar')

    $('body').on 'click', '[data-navigate]', (e) ->
      e.preventDefault()
      href = $(e.currentTarget).attr('href')
      App.router.navigate href, {trigger: true}
      menuIcon.click() if navigation.hasClass('expanded')
      navigation.click()
  App

$ ->
  CodequestManager.start()

@CodequestManager = do (Backbone, Marionette) ->
  Marionette.Renderer.oldRender = Marionette.Renderer.render
  Marionette.Renderer.render = (template, data) ->
    template = template() if typeof template == 'function'

    unless JST[template]
      return Marionette.Renderer.oldRender(template, data)
    return JST[template](data)

  App = new Marionette.Application()

  App.Behaviors = {}

  App.currentUser = undefined

  App.pageSize = 10
  App.animationDurationMedium = 500

  App.on 'start', ->
    App.router = new App.Router
      controller: App.Controller

    App.root = new App.Root.Layout

    Marionette.Behaviors.behaviorsLookup = ->
      App.Behaviors
    App.currentUser = new App.Entities.User gon.currentUser
    App.vent.on 'reload:current:user', ->
      App.currentUser.fetch()
    $(document).foundation()

    App.Panel.Controller.showNavbar()

    Backbone.history.start
      pushState: true

    menuIcon = $('.menu-icon')
    navigation = $('.top-bar')

    $('body').on 'click', '[data-navigate]', (e) ->
      return if e.metaKey
      e.preventDefault()
      href = $(e.currentTarget).attr('href')
      App.router.navigate href, {trigger: true}
      menuIcon.click() if navigation.hasClass('expanded')
      navigation.click()
  App

$ ->
  CodequestManager.start()

Make CMD+Click or CTRL+Click work

Make CMD+Click or CTRL+Click work


{Controller} = require 'spine'
template = require 'views/about_page'
$ = require 'jqueryify'

class AboutPage extends Controller
  className: 'about-page content-page'

  events:
    'click nav button[name="turn-page"]': 'onClickNavButton'

  elements:
    'nav button[name="turn-page"]': 'navButtons'

  constructor: ->
    super
    @html template

    @navButtons.first().click()

    $(window).on 'hashchange', @onPageChange

  onClickNavButton: ({currentTarget}) ->
    button = $(currentTarget)
    page = @el.find "[data-page='#{button.val()}']"

    page.add(page.siblings('[data-page]')).add(button).add(button.siblings('[name="turn-page"]')).removeClass 'before active after'

    page.prevAll('[data-page]').add(button.prevAll('[name="turn-page"]')).addClass 'before'
    page.add(button).addClass 'active'
    page.nextAll('[data-page]').add(button.nextAll('[name="turn-page"]')).addClass 'after'

    @onPageChange()

  onPageChange: =>
    setTimeout =>
      visibleProtoimages = @el.find 'img[data-src]:visible'
      @log visibleProtoimages
      @processProtoimage img for img in visibleProtoimages

  processProtoimage: (img) ->
    img = $(img)
    img.attr src: img.attr 'data-src'
    img.removeAttr 'data-src'

module.exports = AboutPage

{Controller} = require 'spine'
template = require 'views/about_page'
$ = require 'jqueryify'

class AboutPage extends Controller
  className: 'about-page content-page'

  events:
    'click nav button[name="turn-page"]': 'onClickNavButton'

  elements:
    'nav button[name="turn-page"]': 'navButtons'

  constructor: ->
    super
    @html template

    @navButtons.first().click()

    $(window).on 'hashchange', @onPageChange

  onClickNavButton: ({currentTarget}) ->
    button = $(currentTarget)
    page = @el.find "[data-page='#{button.val()}']"

    page.add(page.siblings('[data-page]')).add(button).add(button.siblings('[name="turn-page"]')).removeClass 'before active after'

    page.prevAll('[data-page]').add(button.prevAll('[name="turn-page"]')).addClass 'before'
    page.add(button).addClass 'active'
    page.nextAll('[data-page]').add(button.nextAll('[name="turn-page"]')).addClass 'after'

    @onPageChange()

  onPageChange: =>
    return unless @el.is ':visible'
    setTimeout =>
      visibleProtoimages = @el.find 'img[data-src]:visible'
      @processProtoimage img for img in visibleProtoimages

  processProtoimage: (img) ->
    img = $(img)
    img.attr src: img.attr 'data-src'
    img.removeAttr 'data-src'

module.exports = AboutPage

Clean up about page image loader

Clean up about page image loader


'use strict'

IBAN = require 'iban'

angular
  .module 'mm.iban', ['ng']
  .directive 'ngIban', ->
    restrict: 'A'
    require: 'ngModel'
    link: (scope, elem, attrs, ctrl) ->
      parseIban = (value) ->
        if value? then value.toUpperCase().replace /\s/g, '' else undefined

      isValidIban = (value) ->
        return true if not(attrs.required or value)

        iban = parseIban(value)
        IBAN.isValid iban

      ctrl.$validators.ngIban = (modelValue) ->
        isValidIban modelValue

      ctrl.$parsers.unshift (viewValue) ->
        if viewValue?
          valid = isValidIban viewValue
          if valid
            parsed = parseIban viewValue
            if parsed isnt viewValue
              ctrl.$setViewValue parsed
              ctrl.$render()
            parsed
          else
            viewValue

      ctrl.$formatters.unshift (modelValue) ->
        if modelValue?
          valid = isValidIban modelValue
          if valid
            parsed = parseIban modelValue
            if parsed isnt modelValue
              scope[attrs.ngModel] = parsed
            parsed
          else modelValue

      return

  .filter 'iban', ->
    (string, separator) ->
      parseIban = (value) ->
        if value? then value.toUpperCase().replace /\s/g, '' else undefined

      isValidIban = (value) ->
        iban = parseIban(value)
        IBAN.isValid iban

      valid = isValidIban string
      if valid
        IBAN.printFormat string, separator
      else
        string

'use strict'

IBAN = require 'iban'

angular
  .module 'mm.iban', ['ng']
  .directive 'ngIban', ->
    restrict: 'A'
    require: 'ngModel'
    scope:
      ngModel: '='
    link: (scope, elem, attrs, ctrl) ->
      parseIban = (value) ->
        if value? then value.toUpperCase().replace /\s/g, '' else undefined

      isValidIban = (value) ->
        return true if not(attrs.required or value)

        iban = parseIban(value)
        IBAN.isValid iban

      ctrl.$validators.ngIban = (modelValue) ->
        isValidIban modelValue

      ctrl.$parsers.unshift (viewValue) ->
        if viewValue?
          valid = isValidIban viewValue
          if valid
            parsed = parseIban viewValue
            if parsed isnt viewValue
              ctrl.$setViewValue parsed
              ctrl.$render()
            parsed
          else
            viewValue

      ctrl.$formatters.unshift (modelValue) ->
        if modelValue?
          valid = isValidIban modelValue
          if valid
            parsed = parseIban modelValue
            if parsed isnt modelValue
              scope.ngModel = parsed
            parsed
          else modelValue

      return

  .filter 'iban', ->
    (string, separator) ->
      parseIban = (value) ->
        if value? then value.toUpperCase().replace /\s/g, '' else undefined

      isValidIban = (value) ->
        iban = parseIban(value)
        IBAN.isValid iban

      valid = isValidIban string
      if valid
        IBAN.printFormat string, separator
      else
        string

Use isolated scope for directive

Use isolated scope for directive


should = require('chai').should()
bundle = require '../lib/bundle'

describe 'bundle', ->
  it 'should bundle all dependencies', (done) ->
    bundle
      entry: './fixtures/entry',
      exclude: /excluded/
      include: ['./fixtures/included']
      export: 'entry'
    , (err, bundle) ->
      done()

should = require('chai').should()
bundle = require '../lib/bundle'

opts =
  entry: './fixtures/entry',
  exclude: /excluded/
  include: ['./fixtures/included']
  export: 'entry'

describe 'bundle', ->
  it 'should bundle all dependencies', (done) ->
    bundle opts, (err, bundle) ->
      bundle.toString().should.contain "require.define('./relative'"
      done()

  it 'should bundle all dependencies and return promise', (done) ->
    bundle(opts).then (bundle) ->
      bundle.toString().should.contain "require.define('./relative'"
      done()

Update tests to test promise API as well.


define (require) ->
  $ = require('jquery')
  toc = require('cs!collections/toc')
  Node = require('cs!models/content/node')
  require('backbone-associations')

  return class Page extends Node
    defaults:
      authors: []

    constructor: () ->
      super(arguments...)
      toc.add(@)

    parse: (response, options) ->
      resonse = super(arguments...)

      # jQuery can not build a jQuery object with <head> or <body> tags,
      # and will instead move all elements in them up one level.
      # Use a regex to extract everything in the body and put it into a div instead.
      $body = $('<div>' + response.content.replace(/^[\s\S]*<body.*?>|<\/body>[\s\S]*$/g, '') + '</div>')
      $body.children('.title').eq(0).remove()
      response.content = $body.html()

      return response

define (require) ->
  $ = require('jquery')
  toc = require('cs!collections/toc')
  Node = require('cs!models/content/node')
  require('backbone-associations')

  return class Page extends Node
    defaults:
      authors: []

    constructor: () ->
      super(arguments...)
      toc.add(@)

    parse: (response, options) ->
      resonse = super(arguments...)

      # jQuery can not build a jQuery object with <head> or <body> tags,
      # and will instead move all elements in them up one level.
      # Use a regex to extract everything in the body and put it into a div instead.
      $body = $('<div>' + response.content.replace(/^[\s\S]*<body.*?>|<\/body>[\s\S]*$/g, '') + '</div>')
      $body.children('.title').eq(0).remove()
      $body.children('.abstract').eq(0).remove()
      response.content = $body.html()

      return response

Remove first .abstract element if it exists


#
# Auction related routes
#

express = require 'express'
routes = require './routes'

app = module.exports = express()
app.set 'views', __dirname + '/templates'
app.set 'view engine', 'jade'

app.get '/auction-registration/:id', routes.auctionRegistration
app.get '/auction/:id/bid/:artwork', routes.bid
app.get '/auction/:id/buyers-premium', routes.buyersPremium

# Support legacy feature route for Eigen
app.get '/feature/:id/bid/:artwork', routes.bid

Add /feature bid route for Eigen

Add /feature bid route for Eigen


#
module.exports =
class ObjectSelection
  constructor: (@options={}) ->
    @options.class ?= 'object-selection'

  setObject: (object) ->
    @_unbindObject(@object)
    @object = object
    @_bindObject(@object)

    @path.remove() if @path
    @path = null
    if @object
      @path = svg.path('').front()
      @path.node.setAttribute('class', @options.class + ' invisible-to-hit-test')
      @render()

  render: =>
    @object.render(@path)

  _bindObject: (object) ->
    return unless object
    object.on 'change', @render

  _unbindObject: (object) ->
    return unless object
    object.off 'change', @render

#
module.exports =
class ObjectSelection
  constructor: (@options={}) ->
    @options.class ?= 'object-selection'

  setObject: (object) ->
    @_unbindObject(@object)
    @object = object
    @_bindObject(@object)

    @path.remove() if @path
    @path = null
    if @object
      @path = svg.path('').front()
      @path.node.setAttribute('class', @options.class + ' invisible-to-hit-test')
      @render()

  render: =>
    @object.render(@path)

  _bindObject: (object) ->
    return unless object
    object.on 'change', @render

  _unbindObject: (object) ->
    return unless object
    object.removeListener 'change', @render

Use removeListener instead of off

Use removeListener instead of off


EnumerableWrapper =
  getLength: ->
    @value.length

  forEach: (callback) ->
    if @wrappers.constructor == Object
      callback(key, wrapper) for key, wrapper of @wrappers
    else if @wrappers.constructor == Array
      @wrappers.forEach(callback)

  map: (callback) ->
    @wrappers.map(callback)

  find: (callback) ->
    for wrapper, index in @wrappers when callback(wrapper, index, @wrappers)
      return wrapper
    false

  findIndex: (callback) ->
    for wrapper, index in @wrappers when callback(wrapper, index, @wrappers)
      return index
    return -1

  push: (value) ->
    length = @value.push(value)
    @set(@value)
    return length

  pop: ->
    last = @value.pop()
    @set(@value)
    return last

  insertAt: (index, value) ->
    # Use apply to handle value as a single value or an array.
    args = [index, 0].concat(value)
    Array.prototype.splice.apply(@value, args)
    @set(@value)

  removeAt: (index, howMany = 1) ->
    removed = @value.splice(index, howMany)
    @set(@value)
    return removed

module.exports = EnumerableWrapper

EnumerableWrapper =
  getLength: ->
    @value.length

  forEach: (callback) ->
    if @wrappers.constructor == Object
      callback(key, wrapper) for key, wrapper of @wrappers
    else if @wrappers.constructor == Array
      @wrappers.forEach(callback)

  map: (callback) ->
    @wrappers.map(callback)

  find: (callback) ->
    for wrapper, index in @wrappers when callback(wrapper, index, @wrappers)
      return wrapper
    null

  findIndex: (callback) ->
    for wrapper, index in @wrappers when callback(wrapper, index, @wrappers)
      return index
    return -1

  push: (value) ->
    length = @value.push(value)
    @set(@value)
    return length

  pop: ->
    last = @value.pop()
    @set(@value)
    return last

  insertAt: (index, value) ->
    # Use apply to handle value as a single value or an array.
    args = [index, 0].concat(value)
    Array.prototype.splice.apply(@value, args)
    @set(@value)

  removeAt: (index, howMany = 1) ->
    removed = @value.splice(index, howMany)
    @set(@value)
    return removed

module.exports = EnumerableWrapper

Return null when not found

Return null when not found


module.exports = (grunt) ->
  grunt.initConfig
    pkg: grunt.file.readJSON('package.json')

    coffee:
      glob_to_multiple:
        expand: true
        cwd: 'src'
        src: ['**/*.coffee']
        dest: 'lib'
        ext: '.js'

    coffeelint:
      options:
        no_empty_param_list:
          level: 'error'
        max_line_length:
          level: 'ignore'
        indentation:
          level: 'ignore'

      src: ['src/*.coffee']
      test: ['spec/*.coffee']
      gruntfile: ['Gruntfile.coffee']

    shell:
      test:
        command: 'node node_modules/.bin/jasmine-focused --coffee --captureExceptions --forceexit spec'
        options:
          stdout: true
          stderr: true
          failOnError: true

      'update-atomdoc':
        command: 'npm update grunt-atomdoc donna tello atomdoc'
        options:
          stdout: true
          stderr: true
          failOnError: true

  grunt.loadNpmTasks('grunt-contrib-coffee')
  grunt.loadNpmTasks('grunt-shell')
  grunt.loadNpmTasks('grunt-coffeelint')
  grunt.loadNpmTasks('grunt-atomdoc')

  grunt.registerTask 'clean', -> require('rimraf').sync('lib')
  grunt.registerTask('lint', ['coffeelint'])
  grunt.registerTask('default', ['coffee', 'lint'])
  grunt.registerTask('test', ['coffee', 'lint', 'shell:test'])

path = require('path')

module.exports = (grunt) ->
  grunt.initConfig
    pkg: grunt.file.readJSON('package.json')

    coffee:
      glob_to_multiple:
        expand: true
        cwd: 'src'
        src: ['**/*.coffee']
        dest: 'lib'
        ext: '.js'

    coffeelint:
      options:
        no_empty_param_list:
          level: 'error'
        max_line_length:
          level: 'ignore'
        indentation:
          level: 'ignore'

      src: ['src/*.coffee']
      test: ['spec/*.coffee']
      gruntfile: ['Gruntfile.coffee']

    shell:
      test:
        command: "#{path.normalize('node_modules/.bin/jasmine-focused')} --coffee --captureExceptions --forceexit spec"
        options:
          stdout: true
          stderr: true
          failOnError: true

      'update-atomdoc':
        command: 'npm update grunt-atomdoc donna tello atomdoc'
        options:
          stdout: true
          stderr: true
          failOnError: true

  grunt.loadNpmTasks('grunt-contrib-coffee')
  grunt.loadNpmTasks('grunt-shell')
  grunt.loadNpmTasks('grunt-coffeelint')
  grunt.loadNpmTasks('grunt-atomdoc')

  grunt.registerTask 'clean', -> require('rimraf').sync('lib')
  grunt.registerTask('lint', ['coffeelint'])
  grunt.registerTask('default', ['coffee', 'lint'])
  grunt.registerTask('test', ['coffee', 'lint', 'shell:test'])

Switch appveyor from apm to npm

Switch appveyor from apm to npm


Wheelmap.ToolbarController = Ember.Controller.extend
  needs: 'map'
  statusFilters: ['yes', 'limited', 'no', 'unknown']
  map: Ember.computed.alias('controllers.map')
  _extraFilter: false # Flag for executing special status filter behavior only once

  init: ()->
    @_super()

    if $.cookie('last_status_filters')
      @set('statusFilters', JSON.parse($.cookie('last_status_filters')))

  actions:
    toggleFilter: (wheelchair)->
      statusFilters = @get('statusFilters')

      if !@_extraFilter && statusFilters.length == 4
        # Extra logic if all status filters are set and one is clicked: deactivate the other filters
        statusFilters.clear()
        statusFilters.addObject(wheelchair)
        @_extraFilter = true
      else
        if statusFilters.contains(wheelchair)
          statusFilters.removeObject(wheelchair)
        else
          statusFilters.addObject(wheelchair)

  statusFiltersDidChange: (()->
    $.cookie('last_status_filters', JSON.stringify(@get('statusFilters')))
  ).observes('statusFilters.@each')

  filterNodes: (()->
    self = @

    @get('map').forEach (node)->
      node.set('isVisible', self.get('statusFilters').contains(node.get('wheelchair')))
  ).observes('map.@each.wheelchair', 'statusFilters.@each')

Wheelmap.ToolbarController = Ember.Controller.extend
  needs: 'map'
  statusFilters: ['yes', 'limited', 'no', 'unknown']
  _extraFilter: false # Flag for executing special status filter behavior only once

  init: ()->
    @_super()

    if $.cookie('last_status_filters')
      @set('statusFilters', JSON.parse($.cookie('last_status_filters')))

  actions:
    toggleFilter: (wheelchair)->
      statusFilters = @get('statusFilters')

      if !@_extraFilter && statusFilters.length == 4
        # Extra logic if all status filters are set and one is clicked: deactivate the other filters
        statusFilters.clear()
        statusFilters.addObject(wheelchair)
      else
        if statusFilters.contains(wheelchair)
          statusFilters.removeObject(wheelchair)
        else
          statusFilters.addObject(wheelchair)

      @_extraFilter = true

  statusFiltersDidChange: (()->
    $.cookie('last_status_filters', JSON.stringify(@get('statusFilters')))
  ).observes('statusFilters.@each')

  filterNodes: (()->
    self = @

    @get('controllers.map').forEach (node)->
      node.set('isVisible', self.get('statusFilters').contains(node.get('wheelchair')))
  ).observes('controllers.map.@each.wheelchair', 'statusFilters.@each')

Fix bug with not called observers listening to aliases.


import contest from "../../lib/contest"
import label from "../../lib/label"
import link from "../../lib/link"
import page from "../../lib/page"
import problem from "../../lib/problem"
import topic from "../../lib/topic"
import {ruen} from "../../lib/util"

export default sparse_tables = () ->
    return {
        topic: topic(
            ruen("Sparse tables, двоичный подъем", "Sparse tables, binary ascent"),
            ruen("Задачи на sparse tables", "Problems on sparse tables"),
        [   problem(113919),
        ], "sparse_tables"),
        advancedProblems: [
            problem(113550),
        ]
    }

import contest from "../../lib/contest"
import label from "../../lib/label"
import link from "../../lib/link"
import page from "../../lib/page"
import problem from "../../lib/problem"
import topic from "../../lib/topic"
import {ruen} from "../../lib/util"

export default sparse_tables = () ->
    return {
        topic: topic(
            ruen("Sparse tables, двоичный подъем", "Sparse tables, binary ascent"),
            ruen("Задачи на sparse tables", "Problems on sparse tables"),
        [   problem(113919),
            problem(752),
        ], "sparse_tables"),
        advancedProblems: [
            problem(113550),
        ]
    }

Add RMQ to sparse tables contest

Add RMQ to sparse tables contest


{CompositeDisposable} = require 'atom'

module.exports =
  config:
    executablePath:
      type: 'string'
      title: 'PHP Executable Path'
      default: 'php' # Let OS's $PATH handle the rest

  activate: ->
    @regex = '(Parse|Fatal) ' +
            '(?<error>error):(\\s*(?<type>parse|syntax) error,?)?\\s*' +
            '(?<message>(unexpected \'(?<near>[^\']+)\')?.*) ' +
            'in .*? on line (?<line>\\d+)'
    @subscriptions = new CompositeDisposable
    @subscriptions.add atom.config.observe 'linter-php.executablePath',
      (executablePath) =>
        @executablePath = executablePath

  deactivate: ->
    @subscriptions.dispose()

  provideLinter: ->
    path = require 'path'
    helpers = require('atom-linter')
    child_process = require 'child_process'
    provider =
      grammarScopes: ['text.html.php', 'source.php']
      scope: 'file'
      lintOnFly: false
      lint: (textEditor) =>
        filePath = textEditor.getPath()
        command = @executablePath
        parameters = []
        parameters.push('--syntax-check')
        parameters.push('--no-php-ini')
        parameters.push('--define', 'display_errors=On')
        parameters.push('--define', 'log_errors=Off')
        parameters.push('--file', filePath)
        return helpers.exec(command, parameters).then (output) =>
          messages = helpers.parse(output, @regex, {filePath: filePath})
          console.log(messages)
          return messages

{CompositeDisposable} = require 'atom'

module.exports =
  config:
    executablePath:
      type: 'string'
      title: 'PHP Executable Path'
      default: 'php' # Let OS's $PATH handle the rest

  activate: ->
    @regex = '(Parse|Fatal) ' +
            '(?<error>error):(\\s*(?<type>parse|syntax) error,?)?\\s*' +
            '(?<message>(unexpected \'(?<near>[^\']+)\')?.*) ' +
            'in .*? on line (?<line>\\d+)'
    @subscriptions = new CompositeDisposable
    @subscriptions.add atom.config.observe 'linter-php.executablePath',
      (executablePath) =>
        @executablePath = executablePath

  deactivate: ->
    @subscriptions.dispose()

  provideLinter: ->
    helpers = require('atom-linter')
    provider =
      grammarScopes: ['text.html.php', 'source.php']
      scope: 'file'
      lintOnFly: false
      lint: (textEditor) =>
        filePath = textEditor.getPath()
        command = @executablePath
        parameters = []
        parameters.push('--syntax-check')
        parameters.push('--no-php-ini')
        parameters.push('--define', 'display_errors=On')
        parameters.push('--define', 'log_errors=Off')
        parameters.push('--file', filePath)
        return helpers.exec(command, parameters).then (output) =>
          messages = helpers.parse(output, @regex, {filePath: filePath})
          console.log(messages)
          return messages

Remove no longer needed requires

Remove no longer needed requires


# Generated on 2014-12-25 using generator-bower 0.0.1
'use strict'

mountFolder = (connect, dir) ->
    connect.static require('path').resolve(dir)

module.exports = (grunt) ->
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)

  yeomanConfig =
    src: 'src'
    dist : 'dist'

  grunt.initConfig
    yeoman: yeomanConfig

    coffee:
      dist:
        files: [
          expand: true
          cwd: '<%= yeoman.src %>'
          src: '{,*/}*.coffee'
          dest: '<%= yeoman.dist %>'
          ext: '.js'
        ]

    uglify:
      build:
        src: '<%=yeoman.dist %>/forty-datetime.js'
        dest: '<%=yeoman.dist %>/forty-datetime.min.js'

    # TODO Add testing
    # mochaTest:
    #   test:
    #     options:
    #       reporter: 'spec'
    #       compilers: 'coffee:coffee-script'
    #     src: ['test/**/*.coffee']
    #
    # karma:
    #   options:
    #     configFile: 'config/karma-conf.js'
    #   unit:
    #     singleRun: true
    #
    #
    # grunt.loadNpmTasks('grunt-karma')

    grunt.registerTask 'default', [
      #'mochaTest'
      'coffee'
      'uglify'
    ]

# Generated on 2014-12-25 using generator-bower 0.0.1
'use strict'

mountFolder = (connect, dir) ->
    connect.static require('path').resolve(dir)

module.exports = (grunt) ->
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)

  yeomanConfig =
    src: 'src'
    dist : 'dist'

  grunt.initConfig
    yeoman: yeomanConfig

    coffee:
      dist:
        files: [
          expand: true
          cwd: '<%= yeoman.src %>'
          src: '{,*/}*.coffee'
          dest: '<%= yeoman.dist %>'
          ext: '.js'
        ]

    uglify:
      build:
        src: '<%=yeoman.dist %>/forty-datetime.js'
        dest: '<%=yeoman.dist %>/forty-datetime.min.js'

    #TODO Add testing
    mochaTest:
       test:
         options:
           reporter: 'spec'
           compilers: 'coffee:coffee-script'
         src: ['test/**/*.coffee']

    karma:
       options:
         configFile: 'config/karma-conf.js'
       unit:
         singleRun: true

    grunt.loadNpmTasks('grunt-karma')

    grunt.registerTask 'default', [
      'mochaTest'
      'coffee'
      'uglify'
    ]

Enable tests to absolutely fail

Enable tests to absolutely fail


AjaxPrefix.addAjaxPrefix(jQuery, -> CMS.prefix)

@CMS =
  Models: {}
  Views: {}

  prefix: $("meta[name='path_prefix']").attr('content')

_.extend CMS, Backbone.Events

$ ->
  Backbone.emulateHTTP = true

  $.ajaxSetup
    headers : { 'X-CSRFToken': $.cookie 'csrftoken' }
    dataType: 'json'

  $(document).ajaxError (event, jqXHR, ajaxSettings, thrownError) ->
    if ajaxSettings.notifyOnError is false
      return
    if jqXHR.responseText
        try
          message = JSON.parse(jqXHR.responseText).error
        catch
          message = _.str.truncate(jqXHR.responseText, 300)
    else
        message = gettext("This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.")
    msg = new CMS.Views.Notification.Error(
        "title": gettext("Studio's having trouble saving your work")
        "message": message
    )
    msg.show()

  window.onTouchBasedDevice = ->
    navigator.userAgent.match /iPhone|iPod|iPad/i

  $('body').addClass 'touch-based-device' if onTouchBasedDevice()

Adjust indentation to make coffeescript happy


User = require '../../../models/user.coffee'
Artwork = require '../../../models/artwork.coffee'
ArtworkInquiry = require '../../../models/artwork_inquiry.coffee'
openInquiryQuestionnaireFor = require '../../../components/inquiry_questionnaire/index.coffee'

module.exports = (id) ->
  user = User.instantiate()
  inquiry = new ArtworkInquiry notification_delay: 600
  artwork = new Artwork id: id

  artwork.fetch().then ->
    openInquiryQuestionnaireFor
      user: user
      artwork: artwork
      inquiry: inquiry

Promise = require 'bluebird-q'
User = require '../../../models/user.coffee'
Artwork = require '../../../models/artwork.coffee'
ArtworkInquiry = require '../../../models/artwork_inquiry.coffee'
openInquiryQuestionnaireFor = require '../../../components/inquiry_questionnaire/index.coffee'

module.exports = (id) ->
  user = User.instantiate()
  inquiry = new ArtworkInquiry notification_delay: 600
  artwork = new Artwork id: id

  Promise artwork.fetch()
    .then ->
      openInquiryQuestionnaireFor
        user: user
        artwork: artwork
        inquiry: inquiry

Return a *real* promise so that we can then/catch


{_, $, fs, View} = require 'atom'
MatchView = require './match-view'
path = require 'path'

module.exports =
class ResultView extends View
  @content: (filePath, matches) ->
    iconClass = if fs.isReadmePath(filePath) then 'icon-book' else 'icon-file-text'

    @li class: 'path list-nested-item', 'data-path': _.escapeAttribute(filePath), =>
      @div outlet: 'pathDetails', class: 'path-details list-item', =>
        @span class: 'disclosure-arrow'
        @span class: iconClass + ' icon'
        @span class: 'path-name bright', filePath.replace(project.getPath()+path.sep, '')
        @span outlet: 'description', class: 'path-match-number'
      @ul outlet: 'matches', class: 'matches list-tree', =>

  initialize: (@filePath, matches) ->
    @renderMatches(matches)

  renderMatches: (matches) ->
    @matches.empty()
    @description.text("(#{matches?.length})")

    if not matches or matches.length == 0
      @hide()
    else
      @show()
      @matches.append new MatchView({@filePath, match}) for match in matches

    null

  confirm: ->
    rootView.openSync(@filePath)

{_, $, fs, View} = require 'atom'
MatchView = require './match-view'
path = require 'path'

module.exports =
class ResultView extends View
  @content: (filePath, matches) ->
    iconClass = if fs.isReadmePath(filePath) then 'icon-book' else 'icon-file-text'

    @li class: 'path list-nested-item', 'data-path': _.escapeAttribute(filePath), =>
      @div outlet: 'pathDetails', class: 'path-details list-item', =>
        @span class: 'disclosure-arrow'
        @span class: iconClass + ' icon'
        @span class: 'path-name bright', filePath.replace(project.getPath()+path.sep, '')
        @span outlet: 'description', class: 'path-match-number'
      @ul outlet: 'matches', class: 'matches list-tree', =>

  initialize: (@filePath, matches) ->
    @renderMatches(matches)

  renderMatches: (matches) ->
    @matches.empty()
    @description.text("(#{matches?.length})")

    if not matches or matches.length == 0
      @hide()
    else
      @show()
      @matches.append new MatchView({@filePath, match}) for match in matches

    null

  confirm: ->
    rootView.open(@filePath)

Use RootView::open instead of RootView::openSync


fs     = require "fs"
class ContentManifest

	filters: [ ]

	constructor: (file,@options) ->
		@rawContent = fs.readFileSync(file,"utf8")
		@list = @rawContent.split /\n/

	addFilter: (pattern,filter) -> @filters.push { pattern: pattern, filter: filter }

	compile: ->
		content = ""
		for item in @list
			for f in @filters
				if item.match f.pattern
					content += f.filter(item)
					break
		return content

module.exports = ContentManifest

fs     = require "fs"
class ContentManifest

	filters: [ ]
	finalizeFilters: []

	constructor: (file,@options) ->
		@rawContent = fs.readFileSync(file,"utf8")
		@list = @rawContent.split /\n/

	###
	A filter is registered with a pattern and a callback,
	The callback takes a file path and should returns filtered content.
	###
	addFilter: (pattern,filter) -> @filters.push { pattern: pattern, filter: filter }

	###
	A finalize filter takes content in string and returns filtered content.
	###
	addFinalizeFilter: (filter) -> @finalizeFilters.push filter

	compile: ->
		content = ""
		for item in @list
			# strip comments
			continue unless item
			continue if item.match /^\s*#/
			item.replace /#.*/,""
			unless fs.existsSync(f)
				console.warn "File #{ f } does not exist."
				continue

			for f in @filters
				if item.match f.pattern
					content += f.filter(item)
					break
		for f in @finalizeFilters
			content = f(content)
		return content

module.exports = ContentManifest

Add finalize filter and comment filter support.


class SidebarController extends KDViewController

  constructor:->
    super

    mainController = KD.getSingleton 'mainController'
    mainController.on 'ManageRemotes', -> new ManageRemotesModal
    mainController.on 'ManageDatabases', -> new ManageDatabasesModal
    mainController.on 'AccountChanged', @bound 'accountChanged'
    mainController.ready @bound 'accountChanged'

  accountChanged:(account)->
    account or= KD.whoami()
    {profile} = account
    sidebar   = @getView()

    {
     avatar, finderHeader, navController
     avatarAreaIconMenu, finderController
     footerMenuController, resourcesController
    } = sidebar

    avatar.setData account
    finderHeader.setData account
    # temp fix
    # this should be done on framework level
    # check comments on KDObject::setData
    avatar.render()
    finderHeader.render()

    navController.reset()
    footerMenuController.reset()
    @resetAdminNavItems()

    avatarAreaIconMenu.accountChanged account

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

    resourcesController.reset()

  resetAdminNavItems:->
    # return unless KD.isLoggedIn()

    KD.whoami().fetchRole? (err, role)=>
      if role is "super-admin"
        @getView().navController.addItem
          title    : "Admin Panel"
          type     : "admin"
          loggedIn : yes
          callback : -> new AdminModal

class SidebarController extends KDViewController

  constructor:->
    super

    mainController = KD.getSingleton 'mainController'
    mainController.on 'ManageRemotes', -> new ManageRemotesModal
    mainController.on 'ManageDatabases', -> new ManageDatabasesModal
    mainController.on 'AccountChanged', @bound 'accountChanged'
    mainController.ready @bound 'accountChanged'

  accountChanged:(account)->
    account or= KD.whoami()
    {profile} = account
    sidebar   = @getView()

    {
     avatar, finderHeader, navController
     avatarAreaIconMenu, finderController
     footerMenuController, resourcesController
    } = sidebar

    avatar.setData account
    finderHeader.setData account
    # temp fix
    # this should be done on framework level
    # check comments on KDObject::setData
    avatar.render()
    finderHeader.render()

    navController.reset()
    footerMenuController.reset()
    @resetAdminNavItems()

    avatarAreaIconMenu.accountChanged account

    if KD.isLoggedIn()
      # get registered users vms
      # allready to go (don't for guests right now):
      finderController.reset()
      resourcesController.reset()

  resetAdminNavItems:->
    # return unless KD.isLoggedIn()

    KD.whoami().fetchRole? (err, role)=>
      if role is "super-admin"
        @getView().navController.addItem
          title    : "Admin Panel"
          type     : "admin"
          loggedIn : yes
          callback : -> new AdminModal

Fix the logic in SidebarController which triggers the FinderController reset to auto-mount vms


`// @ngInject`
angular.module('cobudget').config (RestangularProvider, config) ->
  RestangularProvider.setBaseUrl(config.apiEndpoint)
  RestangularProvider.setDefaultHttpFields
    withCredentials: true
  RestangularProvider.setDefaultHeaders
    Accept: "application/json"

  RestangularProvider.setResponseInterceptor (data, operation, what, url, response, deferred) ->
    if operation is "get"
      # Trim the 's' off so we can reference the singular root note name
      # This is a total hack and won't work for resources like "people"
      return response.data[what.substring(0, what.length-1)]
    if operation is "getList"
      return response.data[what]

  RestangularProvider.setRequestInterceptor (element, operation, what, url) ->
    if operation is "post"
      # Add singular root node to element
      newElem = {}
      newElem[what.substring(0, what.length-1)] = element
      return newElem
    if operation is "update"
      # Trim the 's' off so we can reference the singular root note name
      # This is a total hack and won't work for resources like "people"
      return response.data[what.substring(0, what.length-1)]

Add root node to POST contributions/

Add root node to POST contributions/


exports.config =
  files:
    javascripts:
      joinTo:
        'js/app.js': /^(vendor|bower_components|app)/

    stylesheets:
      joinTo: 'css/app.css'

    templates:
      joinTo: 'js/app.js'

  plugins:
    handlebars:
      include:
        enabled: false

exports.config =
  files:
    javascripts:
      joinTo:
        'js/app.js': /^(bower_components|vendor|app)/

    stylesheets:
      joinTo:
        'css/app.css': /^(bower_components|vendor|app)/

      order:
        before: ['bower_components/normalize-css/normalize.css']

    templates:
      joinTo: 'js/app.js'

  plugins:
    handlebars:
      include:
        enabled: false

Add normalize.css before other css files.


Controller = require 'zooniverse/controllers/base-controller'
Api = require 'zooniverse/lib/api'

class SubjectMetadata extends Controller

  template: (context) ->
    "

Volume: #{context.metadata?.volume} Year: #{context.metadata?.year} Page: #{context.metadata?.page_no}

    "

  metadata:
    volume: ''
    year: ''
    page_no: ''

  constructor: ->
    super

    classify_page = null
    @listenTo Api, 'ready', (e) =>
      currentProject = require 'zooniverse-readymade/current-project'
      classify_page = currentProject.classifyPages[0]

      @listenTo classify_page.Subject, 'select', (e, subject) =>
        @metadata = subject.metadata
        @el.html @template @

  listenTo: (thing, eventName, handler) ->
    addEvent = if 'on' of thing then 'on' else 'addEventListener'
    removeEvent = if 'off' of thing then 'off' else 'removeEventListener'

    thing[addEvent] eventName, handler

    @on 'destroy', ->
      thing[removeEvent] eventName, handler

module.exports = SubjectMetadata

Controller = require 'zooniverse/controllers/base-controller'
Api = require 'zooniverse/lib/api'

class SubjectMetadata extends Controller

  template: (context) ->
    "

Volume: #{context.metadata?.volume} Year: #{context.metadata?.year} Page: #{context.metadata?.page_no} (Read this article)

    "

  metadata:
    volume: ''
    year: ''
    page_no: ''

  constructor: ->
    super

    classify_page = null
    @listenTo Api, 'ready', (e) =>
      currentProject = require 'zooniverse-readymade/current-project'
      classify_page = currentProject.classifyPages[0]

      @listenTo classify_page.Subject, 'select', (e, subject) =>
        @metadata = subject.metadata
        @el.html @template @

  listenTo: (thing, eventName, handler) ->
    addEvent = if 'on' of thing then 'on' else 'addEventListener'
    removeEvent = if 'off' of thing then 'off' else 'removeEventListener'

    thing[addEvent] eventName, handler

    @on 'destroy', ->
      thing[removeEvent] eventName, handler

module.exports = SubjectMetadata

Add a more prominent link to the original journal


class window.ChosenActivator
  @activate: ->
    $(".js--chosen").not(".optional").chosen()
    $(".js--chosen.optional").chosen(allow_single_deselect: true)

$ ->
  ChosenActivator.activate()

  AjaxModal.on_show ->
    # Give the browser just enough time to set the width of the select before
    # activating Chosen. Otherwise, it will sometimes appear as 0-width.
    setTimeout(ChosenActivator.activate, 25);

class window.ChosenActivator
  @activate: ->
    $(".js--chosen").not(".optional").chosen()
    $(".js--chosen.optional").chosen(allow_single_deselect: true)

$ ->
  ChosenActivator.activate()

  AjaxModal.on_show ->
    # Give the browser just enough time to set the width of the select before
    # activating Chosen. Otherwise, it will sometimes appear as 0-width.
    setTimeout(ChosenActivator.activate, 100);

Increase timeout before loading chosen

Increase timeout before loading chosen

See #967. That still wasn't enough time.


kd = require 'kd'
KDListItemView = kd.ListItemView
KDCustomHTMLView = kd.CustomHTMLView
AvatarView = require 'app/commonviews/avatarviews/avatarview'

module.exports = class UserItem extends KDListItemView

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

    options.type           = 'user'
    options.justFirstName ?= yes

    super options, data

  viewAppended: ->

    { profile: { firstName, lastName, nickname} } = @getData()

    { size, justFirstName } = @getOptions()

    name = if justFirstName then firstName else "#{firstName} #{lastName}"

    @avatar    = new AvatarView
      origin   : nickname
      size     : size or width: 22, height: 22

    @name      = new KDCustomHTMLView
      cssClass : 'name'
      partial  : name

    @addSubView @avatar
    @addSubView @name

    @addSubView new KDCustomHTMLView
      tagName  : 'span'
      cssClass : 'remove'
      click    : =>
        @getDelegate().emit 'KickUserRequested', this

kd               = require 'kd'
AvatarView       = require 'app/commonviews/avatarviews/avatarview'
KDLoaderView     = kd.LoaderView
KDListItemView   = kd.ListItemView
KDCustomHTMLView = kd.CustomHTMLView

module.exports = class UserItem extends KDListItemView

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

    options.type           = 'user'
    options.justFirstName ?= yes

    super options, data

  viewAppended: ->

    { profile: { firstName, lastName, nickname} } = @getData()

    { size, justFirstName } = @getOptions()

    name = if justFirstName then firstName else "#{firstName} #{lastName}"

    @avatar    = new AvatarView
      origin   : nickname
      size     : size or width: 22, height: 22

    @name      = new KDCustomHTMLView
      cssClass : 'name'
      partial  : name

    @addSubView @avatar
    @addSubView @name

    @addSubView new KDCustomHTMLView
      tagName  : 'span'
      cssClass : 'remove'
      click    : =>
        @getDelegate().emit 'KickUserRequested', this

    @addSubView @loader = new KDLoaderView
      size     : width : 16
      cssClass : 'hidden'

  setLoadingMode: (disable) ->

    if disable
      @setClass 'in-progress'
      @loader.show()
    else
      @unsetClass 'in-progress'
      @loader.hide()

UserItem: Add loader and a method to deal with it.


if Meteor.isCordova
	if RocketChat.settings.get('Push_enable') is true
		Push.Configure {}

		Push.addListener 'token', (token) ->
			Meteor.call 'log', 'token', arguments

		Push.addListener 'error', (err) ->
			Meteor.call 'log', 'error', arguments
			if error.type == 'apn.cordova'
				Meteor.call 'log', err.error

		Push.addListener 'register', (evt) ->
			Meteor.call 'log', 'register', arguments

		Push.addListener 'alert', (notification) ->
			Meteor.call 'log', 'alert', arguments

		Push.addListener 'sound', (notification) ->
			Meteor.call 'log', 'sound', arguments

		Push.addListener 'badge', (notification) ->
			Meteor.call 'log', 'badge', arguments

		Push.addListener 'startup', (notification) ->
			Meteor.call 'log', 'startup', arguments

		Push.addListener 'message', (notification) ->
			Meteor.call 'log', 'message', arguments

if Meteor.isCordova
	Tracker.autorun ->
		if RocketChat.settings.get('Push_enable') is true
			Push.Configure {}

			Push.addListener 'token', (token) ->
				Meteor.call 'log', 'token', arguments

			Push.addListener 'error', (err) ->
				Meteor.call 'log', 'error', arguments
				if error.type == 'apn.cordova'
					Meteor.call 'log', err.error

			Push.addListener 'register', (evt) ->
				Meteor.call 'log', 'register', arguments

			Push.addListener 'alert', (notification) ->
				Meteor.call 'log', 'alert', arguments

			Push.addListener 'sound', (notification) ->
				Meteor.call 'log', 'sound', arguments

			Push.addListener 'badge', (notification) ->
				Meteor.call 'log', 'badge', arguments

			Push.addListener 'startup', (notification) ->
				Meteor.call 'log', 'startup', arguments

			Push.addListener 'message', (notification) ->
				Meteor.call 'log', 'message', arguments

Put Push config inside an autorun

Put Push config inside an autorun


'use strict'

App =
  items: [
    {name: 'Learn Brunch', check: true}
    {name: 'Find a way to automate tests', check: true}
    {name: 'Apply to my projects', check: false}
#    '...'
    {name: 'Profit!', check: false}
  ]

  init: ->
    tmpl = require 'views/list'
    html = tmpl items: App.items
    document.getElementsByTagName('body')[0].innerHTML += html
    return

module.exports = App

'use strict'

App =
  items: [
    {name: 'Learn Brunch', check: true}
    {name: 'Find a way to automate tests', check: true}
    {name: 'Apply to my projects', check: false}
#    '...'
    {name: 'Profit!', check: false}
  ]

  init: ->
    tmpl = require 'views/list'
    html = tmpl items: App.items
    document.body.innerHTML += html
    return

module.exports = App

Refactor my own knowledge on vanilla DOM manipulation

Gosh I didn't remember we could just use document.body instead of
document.getElementsByTagName('body')[0]! -_-'


ns = @edsc.models.data

ns.Project = do (ko) ->

  class Project
    constructor: ->
      @datasets = ko.observableArray()

    toggleDataset: (dataset) =>
      datasets = @datasets
      if datasets.contains(dataset)
        datasets.remove(dataset)
      else
        datasets.push(dataset)

  exports = Project

ns = @edsc.models.data

ns.Project = do (ko) ->

  class Project
    constructor: ->
      @datasets = ko.observableArray()

    toggleDataset: (dataset) =>
      datasets = @datasets
      if datasets.contains(dataset)
        datasets.remove(dataset)
      else
        datasets.push(dataset)

    hasDataset: (other) =>
      id = other.id()
      for dataset in @datasets()
        return true if dataset.id() == id
      false

  exports = Project

Fix issue where clearing filters would reset in-project status


_ = require "underscore"

Widget = require "./widget"
p = require "../../core/properties"

class AbstractButton extends Widget.Model
  type: "AbstractButton"

  @define {
      callback:    [ p.Instance          ]
      label:       [ p.String, "Button"  ]
      icon:        [ p.String            ]
      button_type: [ p.String, "default" ] # TODO (bev)
    }

module.exports =
  Model: AbstractButton

_ = require "underscore"

Widget = require "./widget"
p = require "../../core/properties"

class AbstractButton extends Widget.Model
  type: "AbstractButton"

  @define {
      callback:    [ p.Instance          ]
      label:       [ p.String, "Button"  ]
      icon:        [ p.Instance          ]
      button_type: [ p.String, "default" ] # TODO (bev)
    }

module.exports =
  Model: AbstractButton

Change AbstractButton.icon's type to Instance in bokehjs


_ = require "underscore"
$ = require "jquery"
$1 = require "bootstrap/modal"
ActionTool = require "./action_tool"
preview_save_tool_template = require "./preview_save_tool_template"

class PreviewSaveToolView extends ActionTool.View
  className: "bk-bs-modal"
  template: preview_save_tool_template

  initialize: (options) ->
    super(options)
    @render()

  render: () ->
    @$el.empty()
    @$el.html(@template())
    @$el.attr("tabindex", "-1")
    @$el.on('hidden', () => @$el.modal('hide'))
    @$el.modal({show: false})

  do: () ->
    canvas = @plot_view.canvas_view.canvas[0]
    @$('.bk-bs-modal-body img').attr("src", canvas.toDataURL());
    @$el.modal('show')

class PreviewSaveTool extends ActionTool.Model
  default_view: PreviewSaveToolView
  type: "PreviewSaveTool"
  tool_name: "Preview/Save"
  icon: "bk-tool-icon-preview-save"

module.exports =
  Model: PreviewSaveTool
  View: PreviewSaveToolView

_ = require "underscore"
$ = require "jquery"
$1 = require "bootstrap/modal"
ActionTool = require "./action_tool"
preview_save_tool_template = require "./preview_save_tool_template"

class PreviewSaveToolView extends ActionTool.View
  className: "bk-bs-modal"
  template: preview_save_tool_template

  initialize: (options) ->
    super(options)
    @render()

  render: () ->
    @$el.empty()
    @$el.html(@template())
    @$el.attr("tabindex", "-1")
    @$el.on('hidden', () => @$el.modal('hide'))
    @$el.modal({show: false})

  do: () ->
    canvas = @plot_view.canvas_view.canvas[0]
    @$('.bk-bs-modal-body img').attr("src", canvas.toDataURL());
    @$el.modal('show')

class PreviewSaveTool extends ActionTool.Model
  default_view: PreviewSaveToolView
  type: "PreviewSaveTool"
  tool_name: "Preview/Save"
  icon: "bk-tool-icon-save"

module.exports =
  Model: PreviewSaveTool
  View: PreviewSaveToolView

Use appropriate icon name in PreviewSaveTool


# Add a default clickhandler so we can use hrefs
Backbone.View::defaultClickHandler = (e, routeTo=null) ->
  routeTo ||= $(e.target).closest("a").attr("href")

  # Return if a modifier key is pressed or when Backbone has not properly been initialized
  # Make sure we return "true" so other functions can determine what happened
  # Note that the capitalization in Backbone.[H]istory is intentional
  if e.metaKey or e.ctrlKey or e.altKey
    window.open routeTo, "_blank"
  else if not Backbone.History.started
    window.open routeTo, FactlinkApp.linkTarget
  else
    Backbone.View::navigateTo routeTo
  e.preventDefault()
  false

Backbone.View::navigateTo = (routeTo) ->
  console.info "Navigating to " + routeTo, "from /" + Backbone.history.fragment
  if "/" + Backbone.history.fragment is routeTo
    Backbone.history.fragment = null
    Backbone.history.navigate routeTo,
      trigger: true
      replace: true
  else
    oldFragment = Backbone.history.fragment
    Backbone.history.navigate routeTo, false
    unless Backbone.history.loadUrl(routeTo)
      Backbone.history.navigate oldFragment, false
      window.open routeTo, FactlinkApp.linkTarget
      window.focus()

# HACK: this is needed because internal events did not seem to work
$(document).on "click", ":not(div.discussion-modal) a[rel=backbone]", Backbone.View::defaultClickHandler

# Add a default clickhandler so we can use hrefs
Backbone.View::defaultClickHandler = (e, routeTo=null) ->
  routeTo ||= $(e.target).closest("a").attr("href")

  # Return if a modifier key is pressed or when Backbone has not properly been initialized
  # Make sure we return "true" so other functions can determine what happened
  # Note that the capitalization in Backbone.[H]istory is intentional
  if e.metaKey or e.ctrlKey or e.altKey
    window.open routeTo, "_blank"
  else if not Backbone.History.started
    window.open routeTo, FactlinkApp.linkTarget
  else
    Backbone.View::navigateTo routeTo
  e.preventDefault()
  false

Backbone.View::navigateTo = (routeTo) ->
  console.info "Navigating to " + routeTo, "from /" + Backbone.history.fragment
  if "/" + Backbone.history.fragment is routeTo
    Backbone.history.fragment = null
    Backbone.history.navigate routeTo,
      trigger: true
      replace: true
  else
    oldFragment = Backbone.history.fragment
    Backbone.history.navigate routeTo, false
    unless Backbone.history.loadUrl(routeTo)
      Backbone.history.navigate oldFragment, false
      window.open routeTo, FactlinkApp.linkTarget
      window.focus()

# HACK: this is needed because internal events did not seem to work
$(document).on "click", ":not(body.client) a[rel=backbone]", Backbone.View::defaultClickHandler

Handle backbone links in the modal on the site properly


RedisWrapper = require('../../infrastructure/RedisWrapper')
rclient = RedisWrapper.client('sudomode')
logger = require('logger-sharelatex')

TIMEOUT_IN_SECONDS = 60 * 10

module.exports = SudoModeHandler =

	_buildKey: (userId) ->
		"SudoMode:{#{userId}}"

	activateSudoMode: (userId, callback=(err)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		duration = TIMEOUT_IN_SECONDS
		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback

	isSudoModeActive: (userId, callback=(err, isActive)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		rclient.get SudoModeHandler._buildKey(userId), (err, result) ->
			if err?
				return callback(err)
			callback(null, result == '1')

RedisWrapper = require('../../infrastructure/RedisWrapper')
rclient = RedisWrapper.client('sudomode')
logger = require('logger-sharelatex')

TIMEOUT_IN_SECONDS = 60 * 60

module.exports = SudoModeHandler =

	_buildKey: (userId) ->
		"SudoMode:{#{userId}}"

	activateSudoMode: (userId, callback=(err)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		duration = TIMEOUT_IN_SECONDS
		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback

	isSudoModeActive: (userId, callback=(err, isActive)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		rclient.get SudoModeHandler._buildKey(userId), (err, result) ->
			if err?
				return callback(err)
			callback(null, result == '1')

Increase sudo-mode time to one hour

Increase sudo-mode time to one hour


# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

$ ->
  $('[data-toggle="tooltip"]').tooltip(placement: 'right')

  $('.datepicker').datepicker
    format: 'dd/mm/yyyy',

  $('select#member_university_name').on 'change', (e) =>
    parentElement = $('#member_university_name_other').parents('.control-group')
    parentElement.hide()
    if e.target.value == 'Other (please specify)'
      parentElement.show()
      parentElement.find('input').focus()

  $('select#member_university_qualification').on 'change', (e) =>
    parentElement = $('#member_university_qualification_other').parents('.control-group')
    parentElement.hide()
    if e.target.value == 'Other (please specify)'
      parentElement.show()
      parentElement.find('input').focus()

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

$ ->
  $('[data-toggle="tooltip"]').tooltip(placement: 'right')

  $('.datepicker').datepicker
    format: 'dd/mm/yyyy',
    viewMode: 2

  $('select#member_university_name').on 'change', (e) =>
    parentElement = $('#member_university_name_other').parents('.control-group')
    parentElement.hide()
    if e.target.value == 'Other (please specify)'
      parentElement.show()
      parentElement.find('input').focus()

  $('select#member_university_qualification').on 'change', (e) =>
    parentElement = $('#member_university_qualification_other').parents('.control-group')
    parentElement.hide()
    if e.target.value == 'Other (please specify)'
      parentElement.show()
      parentElement.find('input').focus()

Improve date picker UX by defaulting to year first


# Description
#   Notifies based on the results of xcode builds and controls xcode builds
#
# Dependencies
#   None
#
# Configuration
#   None
#
# Commands:
#   hubot build <bot name> - Start a build for bot named <bot name> UNIMPLEMENTED
#
# Author:
#   bmnick

url = require('url')
querystring = require('querystring')

module.exports = (robot) ->
  robot.router.get "/hubot/xcode-publish-notify", (req, res) ->
    query = querystring.parse(url.parse(req.url).query)
    app = query.app || null
    success = query.success == "true" || false
    version = query.version || null
    number = query.number || null
    error = query.error || null

    if success
      robot.messageRoom '#publishmobileautomati', 'Built ' + app + ' ' + version + '-' + number + ' successfully. Currently available on Crashlytics for download.'
    else
      robot.messageRoom '#publishmobileautomati', 'BUILD FAILED: ' + app + ' with error ' + error

    res.writeHead 204, { 'Content-Length': 0}

    res.end()

# Description
#   Notifies based on the results of xcode builds and controls xcode builds
#
# Dependencies
#   None
#
# Configuration
#   None
#
# Commands:
#   hubot build <bot name> - Start a build for bot named <bot name> UNIMPLEMENTED
#
# Author:
#   bmnick

url = require('url')
querystring = require('querystring')

module.exports = (robot) ->
  robot.router.get "/hubot/xcode-publish-notify", (req, res) ->
    query = querystring.parse(url.parse(req.url).query)
    app = query.app || null
    success = query.success == "true" || false
    version = query.version || null
    number = query.number || null
    error = query.error || null

    if success
      robot.messageRoom '#publishmobileautomati', 'Built ' + app + ' ' + version + '-' + number + ' successfully. Currently available on Crashlytics for download.'
    else
      robot.messageRoom '#publishmobileautomati', 'FAILED while building' + app + ' with error ' + error

    res.writeHead 204, { 'Content-Length': 0}

    res.end()

Update copy for a more natural sentence

Update copy for a more natural sentence


{$} = require 'atom'

module.exports =
  configDefaults:
    enabled: false

  activate: ->
    atom.workspaceView.on 'focusout', ".editor:not(.mini)", (event) =>
      editor = $(event.target).closest('.editor').view()?.getModel()
      @autosave(editor)

    atom.workspaceView.on 'pane:before-item-destroyed', (event, paneItem) =>
      @autosave(paneItem)

    $(window).preempt 'beforeunload', =>
      for pane in atom.workspaceView.getPanes()
        @autosave(paneItem) for paneItem in pane.getItems()

  autosave: (paneItem) ->
    return unless atom.config.get('autosave.enabled')
    return unless paneItem?.getUri?()?
    return unless paneItem?.isModified?()

    paneItem?.save?()

{$} = require 'atom'

module.exports =
  configDefaults:
    enabled: false

  activate: ->
    atom.workspaceView.on 'focusout', ".editor:not(.mini)", (event) =>
      editor = $(event.target).closest('.editor').view()?.getModel()
      @autosave(editor)

    atom.workspaceView.on 'pane:before-item-destroyed', (event, paneItem) =>
      @autosave(paneItem)

    $(window).preempt 'beforeunload', =>
      for pane in atom.workspace.getPanes()
        @autosave(paneItem) for paneItem in pane.getItems()

  autosave: (paneItem) ->
    return unless atom.config.get('autosave.enabled')
    return unless paneItem?.getUri?()?
    return unless paneItem?.isModified?()

    paneItem?.save?()

Access panes on workspace instead of view


'use strict'

module.exports = angular.module('astrifex', [
  'ui.router'
  'md5.svg-star'
  require('../../../tmp/templates').name
  require('../common/index').name
  require('./maker/index').name
])

'use strict'

module.exports = angular.module('astrifex', [
  'ui.router'
  'astrifex.svg-star'
  require('../../../tmp/templates').name
  require('../common/index').name
  require('./maker/index').name
])

Use astrifex.svg-star instead of md5.svg-star


_ = require 'underscore-plus'
{View} = require 'atom'
ImageEditor = require './image-editor'

module.exports =
class ImageEditorStatusView extends View
  @content: ->
    @div class: 'status-image inline-block', =>
      @span class: 'image-size', outlet: 'imageSizeStatus'

  initialize: (@statusBar) ->
    @attach()

    @subscribe atom.workspaceView, 'pane-container:active-pane-item-changed', =>
      @updateImageSize()

  attach: ->
    @statusBar.appendLeft this

  afterAttach: ->
    @updateImageSize()

  getImageSize: (view) ->
    imageWidth = view.originalWidth
    imageHeight = view.originalHeight
    @imageSizeStatus.text("#{imageWidth}px x #{imageHeight}px").show()

  updateImageSize: ->
    editor = atom.workspaceView.getActivePaneItem()
    if editor instanceof ImageEditor
      view = atom.workspaceView.getActiveView()
      if view.loaded
        @getImageSize(view)
      else # wait for image to load before getting originalWidth and originalHeight
        view.image.load =>
          @getImageSize(view)
    else
      @imageSizeStatus.hide()

_ = require 'underscore-plus'
{View} = require 'atom'
ImageEditor = require './image-editor'

module.exports =
class ImageEditorStatusView extends View
  @content: ->
    @div class: 'status-image inline-block', =>
      @span class: 'image-size', outlet: 'imageSizeStatus'

  initialize: (@statusBar) ->
    @attach()

    @subscribe atom.workspaceView, 'pane-container:active-pane-item-changed', =>
      @updateImageSize()

  attach: ->
    @statusBar.appendLeft this

  afterAttach: ->
    @updateImageSize()

  getImageSize: (view) ->
    imageWidth = view.originalWidth
    imageHeight = view.originalHeight
    @imageSizeStatus.text("#{imageWidth}x#{imageHeight}").show()

  updateImageSize: ->
    editor = atom.workspaceView.getActivePaneItem()
    if editor instanceof ImageEditor
      view = atom.workspaceView.getActiveView()
      if view.loaded
        @getImageSize(view)
      else # wait for image to load before getting originalWidth and originalHeight
        view.image.load =>
          @getImageSize(view)
    else
      @imageSizeStatus.hide()

Drop px units and spaces from size label


import contest from "../../lib/contest"
import label from "../../lib/label"
import link from "../../lib/link"
import page from "../../lib/page"
import problem from "../../lib/problem"
import topic from "../../lib/topic"
import {ruen} from "../../lib/util"

export default sparse_tables = () ->
    return {
        topic: topic(
            ruen("Sparse tables, двоичный подъем", "Sparse tables, binary ascent"),
            ruen("Задачи на sparse tables", "Problems on sparse tables"),
        [   problem(113919),
            problem(113550),
        ], "sparse_tables"),
    }

import contest from "../../lib/contest"
import label from "../../lib/label"
import link from "../../lib/link"
import page from "../../lib/page"
import problem from "../../lib/problem"
import topic from "../../lib/topic"
import {ruen} from "../../lib/util"

export default sparse_tables = () ->
    return {
        topic: topic(
            ruen("Sparse tables, двоичный подъем", "Sparse tables, binary ascent"),
            ruen("Задачи на sparse tables", "Problems on sparse tables"),
        [   problem(113919),
        ], "sparse_tables"),
        advancedProblems: [
            problem(113550),
        ]
    }

Move Antimatter task to level 8C

Move Antimatter task to level 8C


'.editor':
  'ctrl-f2': 'bookmarks:view-all'
  'f2': 'bookmarks:jump-to-next-bookmark'
  'shift-f2': 'bookmarks:jump-to-previous-bookmark'

'.platform-darwin .editor':
  'cmd-f2': 'bookmarks:toggle-bookmark'
  'cmd-shift-f2': 'bookmarks:clear-bookmarks'

'.platform-win32 .editor':
  'alt-ctrl-f2': 'bookmarks:toggle-bookmark'
  'ctrl-shift-f2': 'bookmarks:clear-bookmarks'

'.platform-linux .editor':
  'ctrl-shift-f2': 'bookmarks:toggle-bookmark'
  'alt-shift-f2': 'bookmarks:clear-bookmarks'

'atom-text-editor':
  'ctrl-f2': 'bookmarks:view-all'
  'f2': 'bookmarks:jump-to-next-bookmark'
  'shift-f2': 'bookmarks:jump-to-previous-bookmark'

'.platform-darwin atom-text-editor':
  'cmd-f2': 'bookmarks:toggle-bookmark'
  'cmd-shift-f2': 'bookmarks:clear-bookmarks'

'.platform-win32 atom-text-editor':
  'alt-ctrl-f2': 'bookmarks:toggle-bookmark'
  'ctrl-shift-f2': 'bookmarks:clear-bookmarks'

'.platform-linux atom-text-editor':
  'ctrl-shift-f2': 'bookmarks:toggle-bookmark'
  'alt-shift-f2': 'bookmarks:clear-bookmarks'

Fix deprecated selectors in keymap

Fix deprecated selectors in keymap


{elementMatchesSelector} = LocalTime

class LocalTime.PageObserver
  constructor: (@selector, @callback) ->

  start: ->
    unless @started
      @observeWithMutationObserver() or @observeWithMutationEvent()
      @started = true

  observeWithMutationObserver: ->
    if MutationObserver?
      observer = new MutationObserver @processMutations
      observer.observe(document.documentElement, childList: true, subtree: true)
      true

  observeWithMutationEvent: ->
    addEventListener("DOMNodeInserted", @processInsertion, false)
    true

  findSignificantElements: (element) ->
    elements = []
    if element?.nodeType is Node.ELEMENT_NODE
      elements.push(element) if elementMatchesSelector(element, @selector)
      elements.concat(element.querySelectorAll(@selector)...)
    elements

  processMutations: (mutations) =>
    elements = []
    for mutation in mutations
      switch mutation.type
        when "childList"
          for node in mutation.addedNodes
            elements.push(@findSignificantElements(node)...)
    @notify(elements)

  processInsertion: (event) =>
    elements = @findSignificantElements(event.target)
    @notify(elements)

  notify: (elements) ->
    if elements?.length
      @callback?(elements)

{elementMatchesSelector} = LocalTime

class LocalTime.PageObserver
  constructor: (@selector, @callback) ->

  start: ->
    unless @started
      @observeWithMutationObserver() or @observeWithMutationEvent()
      @started = true

  observeWithMutationObserver: ->
    if MutationObserver?
      observer = new MutationObserver @processMutations
      observer.observe(document.documentElement, childList: true, subtree: true)
      true

  observeWithMutationEvent: ->
    addEventListener("DOMNodeInserted", @processInsertion, false)
    true

  findSignificantElements: (element) ->
    elements = []
    if element?.nodeType is Node.ELEMENT_NODE
      elements.push(element) if elementMatchesSelector(element, @selector)
      elements.push(element.querySelectorAll(@selector)...)
    elements

  processMutations: (mutations) =>
    elements = []
    for mutation in mutations
      switch mutation.type
        when "childList"
          for node in mutation.addedNodes
            elements.push(@findSignificantElements(node)...)
    @notify(elements)

  processInsertion: (event) =>
    elements = @findSignificantElements(event.target)
    @notify(elements)

  notify: (elements) ->
    if elements?.length
      @callback?(elements)

Fix adding inner elements to array

Fix adding inner elements to array


async = require 'async'
fs = require 'fs'
VariableScanner = require '../variable-scanner'

class PathScanner
  constructor: (@path) ->
    @scanner = new VariableScanner

  load: (done) ->
    currentChunk = ''
    currentLine = 0
    currentOffset = 0
    lastIndex = 0

    results = []

    readStream = fs.createReadStream(@path)

    readStream.on 'data', (chunk) =>
      currentChunk += chunk.toString()

      index = lastIndex

      while result = @scanner.search(currentChunk, lastIndex)
        result.range[0] += index
        result.range[1] += index

        for v in result
          v.path = @path
          v.range[0] += index
          v.range[1] += index
          v.definitionRange = result.range

        results = results.concat(result)
        {lastIndex} = result

      if result?
        currentChunk = currentChunk[lastIndex..-1]
        lastIndex = 0

    readStream.on 'end', ->
      emit('scan-paths:path-scanned', results)
      done()

module.exports = (paths) ->
  async.each(
    paths,
    (path, next) ->
      new PathScanner(path).load(next)
    @async()
  )

async = require 'async'
fs = require 'fs'
VariableScanner = require '../variable-scanner'

class PathScanner
  constructor: (@path) ->
    @scanner = new VariableScanner

  load: (done) ->
    currentChunk = ''
    currentLine = 0
    currentOffset = 0
    lastIndex = 0
    line = 0
    results = []

    readStream = fs.createReadStream(@path)

    readStream.on 'data', (chunk) =>
      currentChunk += chunk.toString()

      index = lastIndex

      while result = @scanner.search(currentChunk, lastIndex)
        result.range[0] += index
        result.range[1] += index

        for v in result
          v.path = @path
          v.range[0] += index
          v.range[1] += index
          v.definitionRange = result.range
          v.line += line
          lastLine = v.line

        results = results.concat(result)
        {lastIndex} = result

      if result?
        currentChunk = currentChunk[lastIndex..-1]
        line = lastLine
        lastIndex = 0

    readStream.on 'end', ->
      emit('scan-paths:path-scanned', results)
      done()

module.exports = (paths) ->
  async.each(
    paths,
    (path, next) ->
      new PathScanner(path).load(next)
    @async()
  )

Increment results line when scanning using a stream


menu: [
  {
    label: 'View'
    submenu: [
      {
        label: 'Toggle Treeview'
        command: 'tree-view:toggle'
      }
    ]
  }
]

'context-menu':
  '.tree-view':
    'Add File': 'tree-view:add'
    'Rename': 'tree-view:move'
    'Delete': 'tree-view:remove'

Add an example menu item.

Add an example menu item.


#!/usr/bin/env coffee

feathers = require("feathers")
bodyParser = require("body-parser")
path = require("path")
twilio = require("twilio")
config = require("./config")

# Public Directory
publicPath = path.resolve(__dirname, "../app")

# Services
transmissionService = require("./services/transmissionService")
providerService = require("./services/providerService")
twilioService = require("./services/twilioService")
botService = require("./services/botService")

# Create App Server
app = feathers()
# Configure
app.configure(feathers.rest())
.configure(feathers.socketio())
# Enable parsing for POST, PUT and PATCH requests
# in JSON and URL encoded forms
.use(bodyParser.json())
.use(bodyParser.urlencoded(extended: true))
# Services
.use("/api/transmission", transmissionService)
.use("/api/torrents", providerService)
.use("/api/bot", botService)
# Public static content
.use(feathers.static(publicPath))
.post("/api/sms", twilio.webhook(config.twilio.authToken), twilioService.receive)
# Start server listening
.listen config.server.port, ->
  console.log "Listening on http://localhost:" + config.server.port

#!/usr/bin/env coffee

feathers = require("feathers")
bodyParser = require("body-parser")
path = require("path")
twilio = require("twilio")
config = require("./config")

# Public Directory
publicPath = path.resolve(__dirname, "../app")

# Services
transmissionService = require("./services/transmissionService")
providerService = require("./services/providerService")
twilioService = require("./services/twilioService")
botService = require("./services/botService")

# Create App Server
app = feathers()
# Configure
app.configure(feathers.rest())
.configure(feathers.socketio())
# Enable parsing for POST, PUT and PATCH requests
# in JSON and URL encoded forms
.use(bodyParser.json())
.use(bodyParser.urlencoded(extended: true))
# Services
.use("/api/transmission", transmissionService)
.use("/api/torrents", providerService)
.use("/api/bot", botService)
# Public static content
.use(feathers.static(publicPath))
.post("/api/sms", twilio.webhook(config.twilio.authToken, {
  validate: false
}), twilioService.receive)
# Start server listening
.listen config.server.port, ->
  console.log "Listening on http://localhost:" + config.server.port

Disable Twilio validation because it keeps failing


define ['backbone.marionette'], (Marionette) ->
    class Router extends Marionette.AppRouter
        routes:
            'unit/:id': 'renderUnit',
            'unit/?*params': 'renderUnitsWithFilter'

        renderUnit: (id)->
            app.vent.trigger 'unit:render-one', id

        renderUnitsWithFilter: (params) ->
            app.vent.trigger 'units:render-with-filter', params

    Router

define ['backbone.marionette'], (Marionette) ->
    delayTime = 500
    class Router extends Marionette.AppRouter
        routes:
            'unit/:id': 'renderUnit',
            'unit/?*params': 'renderUnitsWithFilter'

        renderUnit: (id)->
            delayed = -> app.vent.trigger 'unit:render-one', id
            _.delay delayed, delayTime

        renderUnitsWithFilter: (params) ->
            delayed = -> app.vent.trigger 'units:render-with-filter', params
            _.delay delayed, delayTime

    Router

Fix issue caused by asynchronous routing delaying a callback function


Crafty.defineScene 'New', ->

  #Crafty.e('2D,DOM,Color').attr(
    #x: 10
    #y: 10
    #w: 20
    #h: 20
  #).color('#0000FF')

  #Crafty.e('2D,Canvas,Color,Fourway').attr(
    #x: 100
    #y: 100
    #w: 40
    #h: 40
  #).color('#FF0000').fourway()

  Crafty.e('2D,WebGL,Color,Fourway,Player').attr(
    x: 100
    y: 100
    w: 40
    h: 40
  ).color('#FF0000').fourway(250)

  #Crafty.e('2D,WebGL,Color,FooBar,Collision').attr(
    #x: 300
    #y: 200
    #w: 40
    #h: 40
    #z: 2
  #).color('#0000FF').onHit('Player', ->
    #@bind('TweenEnd', ->
      #@destroy()
    #)
    #@addComponent('Tween').tween(
      #w: 400
      #h: 400
      #x: 0
      #y: 0
      #alpha: 0.2
      #1000
    #)
  #)

  #Crafty.e('2D,Canvas,Color,GamepadMultiway')
    #.attr(
      #x: 100
      #y: 100
      #w: 40
      #h: 40
    #)
    #.color('#FF0000')
    #.gamepadMultiway(speed: 250)

->

Clean slate for live coding

Clean slate for live coding


display_locale_fields = () ->
  attr    = $('#attr_list a.active').data('attr')
  locales = $('#locale').val()
  show    = $("select[name='show-only']").val()

  $('#attr_fields .panel').hide()

  for locale in locales
    do (locale) ->
      value = $('#attr_fields .panel.' + attr + '.' + locale + ' :input').val().replace /^\s+|\s+$/g, ""

      if show == 'incomplete'
        display = value == ''
      else if show == 'complete'
        display = value != ''
      else
        display = true

      if display
        $('#attr_fields .panel.' + attr + '.' + locale).show()

  if $('#attr_fields .panel:visible').length == 0 and show != 'all'
    $('#attr_fields .no-translations').show()

$ ->
  $('#attr_list a').click ->
    $('#attr_list a').removeClass('active')
    $(this).addClass('active')

    display_locale_fields()
    false

  $('#locale, #supported_locales_').select2({placeholder: Spree.translations['please_choose_language']})

  $('#locale').change ->
    display_locale_fields()

  $("select[name='show-only']").change ->
    display_locale_fields()

display_locale_fields = () ->
  attr    = $('#attr_list a.active').data('attr')
  locale  = $('#locale').val()
  show    = $("select[name='show-only']").val()

  $('#attr_fields .panel').hide()

  value = $('#attr_fields .panel.' + attr + '.' + locale + ' :input').val().replace /^\s+|\s+$/g, ""
  if show == 'incomplete'
    display = value == ''
  else if show == 'complete'
    display = value != ''
  else
    display = true
  if display
    $('#attr_fields .panel.' + attr + '.' + locale).show()

  if $('#attr_fields .panel:visible').length == 0 and show != 'all'
    $('#attr_fields .no-translations').show()

$ ->
  $('#attr_list a').click ->
    $('#attr_list a').removeClass('active')
    $(this).addClass('active')

    display_locale_fields()
    false

  $('#locale, #supported_locales_').select2({placeholder: Spree.translations['please_choose_language']})

  $('#locale').change ->
    display_locale_fields()

  $("select[name='show-only']").change ->
    display_locale_fields()

  if $('#attr_list').is('*')
    display_locale_fields()

Fix JS to have translation pages working


fs   = require 'fs'
path = require 'path'

mkdir = (path, cb) ->
  cb = cb or ->
  mode = 0o777 & (~process.umask())
  fs.mkdir path, mode, (err) ->
    if err?.code is 'ENOENT'
      mkdir path.dirname(path), (err) ->
        mkdir path, (err) ->
          cb null
    cb null

module.exports = (opts) ->
  # Get full path to entry
  opts.entry = path.resolve opts.entry

  # Create bundler with our opts
  bundler = require('./bundle')(opts)

  # Bundle Javascript, output to file if opts.output or stdout
  bundler.bundle (err, content) ->
    if opts.output
      mkdir path.dirname(opts.output), (err) ->
        fs.writeFile opts.output, content, 'utf8', (err) ->
          throw err if err
    else
      console.log content

fs   = require 'fs'
path = require 'path'

mkdir = (path, cb) ->
  cb = cb or ->
  mode = 0o777 & (~process.umask())
  fs.mkdir path, mode, (err) ->
    if err?.code is 'ENOENT'
      mkdir path.dirname(path), (err) ->
        mkdir path, (err) ->
          cb null
    cb null

module.exports = (opts) ->
  # Get full path to entry
  opts.entry = path.resolve opts.entry

  # Create bundler with our opts
  bundler = require('./bundle')(opts)

  # Bundle Javascript, output to file if opts.output or stdout
  bundler.bundle (err, content) ->
    if err
      throw err
      process.exit 1

    if opts.output
      mkdir path.dirname(opts.output), (err) ->
        fs.writeFile opts.output, content, 'utf8', (err) ->
          if err
            throw err
            process.exit 1
    else
      console.log content

Build should fail on any error.

Build should fail on any error.


containers    = $(".ontology-version-state")
final_states  = ["done", "failed"]
poll_time = 3000 # milliseconds

return if _.isEmpty(containers) || !containers.length

update = (container) ->
  updateContainer = (container) ->
    current_state = container.data('state')

    $.getJSON container.data('uri'), (data) ->
      state = data.state

      if state == current_state && !_.contains(final_states, state)
        enqueue(container)
      else
        current_state = state

        # display the new state
        container.find("span").text(state)

        if state == "pending"
          $(".pending_message").show()
        else
          $(".pending_message").hide()

        if _.contains(final_states, state)
          # replace spinner with refresh button
          container.find(".spinner").
            replaceWith($('<a />').
              attr('href', document.location.href).
              attr('class', 'btn btn-info btn-sm').
              append($('<i />').
                attr('class', 'icon-refresh')).
              text('refresh'))
        else
          enqueue(container)

  if _.isUndefined(container)
    containers.each ->
      updateContainer($(this))
  else
    updateContainer(container)

enqueue = (container) ->
  setTimeout (-> update(container)), poll_time

enqueue()

containers    = $(".ontology-version-state")
final_states  = ["done", "failed"]
poll_time = 3000 # milliseconds

return if _.isEmpty(containers) || !containers.length

update = (container) ->
  updateContainer = (container) ->
    current_state = container.data('state')

    $.getJSON container.data('uri'), (data) ->
      state = data.evaluation_state

      if state == current_state && !_.contains(final_states, state)
        enqueue(container)
      else
        current_state = state

        # display the new state
        container.find("span").text(state)

        if state == "pending"
          $(".pending_message").show()
        else
          $(".pending_message").hide()

        if _.contains(final_states, state)
          # replace spinner with refresh button
          container.find(".spinner").
            replaceWith($('<a />').
              attr('href', document.location.href).
              attr('class', 'btn btn-info btn-sm').
              append($('<i />').
                attr('class', 'icon-refresh')).
              text('refresh'))
        else
          enqueue(container)

  if _.isUndefined(container)
    containers.each ->
      updateContainer($(this))
  else
    updateContainer(container)

enqueue = (container) ->
  setTimeout (-> update(container)), poll_time

enqueue()

Read correct field for state update.

Read correct field for state update.


express = require 'express'

app = express()

app.get '/', (request, response) ->
  response.send('Hello World!')

port = process.env.PORT or 5000
app.listen port, ->
  console.log("Listening on " + port)

# Extract rendering/serving portion to own module shared by viewer and cli

cli = require 'cli'

handleIndex = (request, response, next) ->
    console.dir(response)
    response.writeHead 200,
        'Content-Type': 'text/html'
    response.end('Hello World!')

port = process.env.PORT or 5000

cli.createServer([
    handleIndex
]).listen(port)

# Extract rendering/serving portion to own module shared by viewer and cli

# Drop express for just Stack.
# https://github.com/chriso/cli
# https://github.com/creationix/creationix/blob/master/indexer.js
# https://github.com/creationix/stack/wiki/Community-Modules

Use Stack instead of Express

Use Stack instead of Express


{Range}  = require('atom')
fuzzaldrin = require('fuzzaldrin')

module.exports =
class SnippetsProvider
  selector: '*'

  getSuggestions: ({scopeDescriptor, prefix}) ->
    return unless prefix?.length
    scopeSnippets = atom.config.get('snippets', {scope: scopeDescriptor})
    @findSuggestionsForPrefix(scopeSnippets, prefix)

  findSuggestionsForPrefix: (snippets, prefix) ->
    return [] unless snippets?

    for __, snippet of snippets when snippet.prefix.lastIndexOf(prefix, 0) isnt -1
      text: snippet.prefix
      replacementPrefix: prefix
      rightLabel: snippet.name

  onDidInsertSuggestion: ({editor}) ->
    atom.commands.dispatch(atom.views.getView(editor), 'snippets:expand')

{Range}  = require('atom')
fuzzaldrin = require('fuzzaldrin')

module.exports =
class SnippetsProvider
  selector: '*'

  getSuggestions: ({scopeDescriptor, prefix}) ->
    return unless prefix?.length
    scopeSnippets = atom.config.get('snippets', {scope: scopeDescriptor})
    @findSuggestionsForPrefix(scopeSnippets, prefix)

  findSuggestionsForPrefix: (snippets, prefix) ->
    return [] unless snippets?

    for __, snippet of snippets when snippet.prefix.lastIndexOf(prefix, 0) isnt -1
      icon: '<i class="icon-move-right"></i>'
      type: 'snippet'
      text: snippet.prefix
      replacementPrefix: prefix
      rightLabel: snippet.name

  onDidInsertSuggestion: ({editor}) ->
    atom.commands.dispatch(atom.views.getView(editor), 'snippets:expand')

Add metadata for each suggestion

Add metadata for each suggestion


# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$ ->
  $('#search').on 'keyup', ->
    $('.search-bar form').submit()

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$ ->
  delay = (ms, func) -> setTimeout func, ms

  submit_form = ->
    console.log "submitted that damned form"
    $('.search-bar form').submit()

  timeout = null

  $('#search').on 'keyup', ->
    clearTimeout(timeout) if timeout
    timeout = delay 400, -> submit_form()

Add a delay before fetching matching records on search.


fs = require 'fs-plus'
path = require 'path'
season = require 'season'
temp = require('temp').track()
runAtom = require './helpers/start-atom'

describe "Smoke Test", ->
  return unless process.platform is 'darwin' # Fails on win32

  atomHome = temp.mkdirSync('atom-home')

  beforeEach ->
    jasmine.useRealClock()
    season.writeFileSync(path.join(atomHome, 'config.cson'), {
      '*': {
        welcome: {showOnStartup: false},
        core: {telemetryConsent: 'no'}
      }
    })

  it "can open a file in Atom and perform basic operations on it", ->
    tempDirPath = temp.mkdirSync("empty-dir")
    runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) ->
      client
        .treeViewRootDirectories()
        .then ({value}) -> expect(value).toEqual([tempDirPath])
        .waitForExist("atom-text-editor", 5000)
        .then (exists) -> expect(exists).toBe true
        .waitForPaneItemCount(1, 1000)
        .click("atom-text-editor")
        .waitUntil((-> @execute(-> document.activeElement.closest('atom-text-editor'))), 5000)
        .keys("Hello!")
        .execute -> atom.workspace.getActiveTextEditor().getText()
        .then ({value}) -> expect(value).toBe "Hello!"
        .dispatchCommand("editor:delete-line")

fs = require 'fs-plus'
path = require 'path'
season = require 'season'
temp = require('temp').track()
runAtom = require './helpers/start-atom'

describe "Smoke Test", ->
  return unless process.platform is 'darwin' # Fails on win32

  atomHome = temp.mkdirSync('atom-home')

  beforeEach ->
    jasmine.useRealClock()
    season.writeFileSync(path.join(atomHome, 'config.cson'), {
      '*': {
        welcome: {showOnStartup: false},
        core: {
          telemetryConsent: 'no',
          disabledPackages: ['github']
        }
      }
    })

  it "can open a file in Atom and perform basic operations on it", ->
    tempDirPath = temp.mkdirSync("empty-dir")
    runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) ->
      client
        .treeViewRootDirectories()
        .then ({value}) -> expect(value).toEqual([tempDirPath])
        .waitForExist("atom-text-editor", 5000)
        .then (exists) -> expect(exists).toBe true
        .waitForPaneItemCount(1, 1000)
        .click("atom-text-editor")
        .waitUntil((-> @execute(-> document.activeElement.closest('atom-text-editor'))), 5000)
        .keys("Hello!")
        .execute -> atom.workspace.getActiveTextEditor().getText()
        .then ({value}) -> expect(value).toBe "Hello!"
        .dispatchCommand("editor:delete-line")

Disable github package in smoke test – it takes too long to compile


React = require 'react'

LearningGuide = require '../flux/learning-guide'
LoadableItem = require './loadable-item'
Teacher = require './learning-guide/teacher'
Student = require './learning-guide/student'

LearningGuideStudentShell = React.createClass

  contextTypes:
    router: React.PropTypes.func

  render: ->
    {courseId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      store={LearningGuide.Student.store}
      actions={LearningGuide.Student.actions}
      renderItem={-> <Student courseId={courseId} />}
    />

LearningGuideTeacherShell = React.createClass

  contextTypes:
    router: React.PropTypes.func

  render: ->
    {courseId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      store={LearningGuide.Teacher.store}
      actions={LearningGuide.Teacher.actions}
      renderItem={-> <Teacher courseId={courseId} />}
    />

module.exports = {LearningGuideStudentShell, LearningGuideTeacherShell}

React = require 'react'

LearningGuide = require '../flux/learning-guide'
LoadableItem = require './loadable-item'
TeacherComponent = require './learning-guide/teacher'
StudentComponent = require './learning-guide/student'
TeacherStudentComponent = require './learning-guide/teacher-student'
{PerformanceStore, PerformanceActions} = require '../flux/performance'

Student = React.createClass
  displayName: 'LearningGuideStudentShell'

  contextTypes:
    router: React.PropTypes.func

  render: ->
    {courseId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      store={LearningGuide.Student.store}
      actions={LearningGuide.Student.actions}
      renderItem={-> <StudentComponent courseId={courseId} />}
    />

# The teacher student store depends on both the
# performance report store as well as the teacher student learning guide
TeacherStudent = React.createClass
  displayName: 'LearningGuideTeacherStudentShell'

  contextTypes:
    router: React.PropTypes.func

  loadPerformanceReport: ->
    {courseId, roleId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      store={PerformanceStore}
      actions={PerformanceActions}
      renderItem={-> <TeacherStudentComponent courseId={courseId} roleId={roleId}/>}
    />

  render: ->
    {courseId, roleId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      options={{roleId}}
      roleId={roleId} # HACK: force loadableItem to re-render
      store={LearningGuide.TeacherStudent.store}
      actions={LearningGuide.TeacherStudent.actions}
      renderItem={@loadPerformanceReport}
    />

Teacher = React.createClass
  displayName: 'LearningGuideTeacherShell'
  contextTypes:
    router: React.PropTypes.func

  render: ->
    {courseId} = @context.router.getCurrentParams()
    <LoadableItem
      id={courseId}
      store={LearningGuide.Teacher.store}
      actions={LearningGuide.Teacher.actions}
      renderItem={-> <TeacherComponent courseId={courseId} />}
    />

module.exports = {Teacher, TeacherStudent, Student}

Load performance store and use options for learning guide


describe 'PodsList', ->
  subject = null
  beforeEach (done) ->
    subject = new SeedsStore('test')
    expect(subject.clear()).eventually.notify(done)
  it 'counts 0', (done) ->
    expect(subject.countForAll()).eventually.equal(0).notify(done)
  it 'counts n', (done) ->
    subject.update([{name: 1},{name: 2},{name: 3}])
    expect(subject.countForAll()).eventually.equal(3).notify(done)
  it 'readPod', (done) ->
    subject.update([{name: 1}, {name: 2}])
    expect(subject.readPod(1)).eventually.eql([{name: 1}]).notify(done)
  it 'readsFromAll asc', (done) ->
    subject.update([{name: 1}, {name: 2}, {name: 3}, {name: 4}])
    expect(subject.readFromAll('name', true, 1, 2)).eventually
      .eql([{name: 2}, {name: 3}]).notify(done)
  it 'readsFromAll desc', (done) ->
    subject.update([{name: 1}, {name: 2}, {name: 3}, {name: 4}])
    expect(subject.readFromAll('name', false, 1, 2)).eventually
      .eql([{name: 3}, {name: 2}]).notify(done)

Add basic reads from all tests.

Add basic reads from all tests.


# Description:
#   None
#
# Dependencies:
#   "date-utils": ">=1.2.5"
#   "githubot": "0.2.0"
#
# Configuration:
#   HUBOT_GITHUB_TOKEN
#
# Commands:
#   hubot repo show <repo> - shows activity of repository
#
# Author:
#   vquaiato

require('date-utils')

module.exports = (robot) ->
  github = require("githubot")(robot)
  robot.respond /repo show (.*)$/i, (msg) ->
    repo = github.qualified_repo msg.match[1]
    oauth_token = process.env.HUBOT_GITHUB_TOKEN
    url = "https://api.github.com/repos/#{repo}/commits"

    github.get url, (commits) ->
      if commits.message
        msg.send "Achievement unlocked: [NEEDLE IN A HAYSTACK] repository #{commits.message}!"
      else if commits.length == 0
          msg.send "Achievement unlocked: [LIKE A BOSS] no commits found!"
      else
        msg.send "http://github.com/#{repo}"
        send = 5
        for c in commits
          if send
            d = new Date(Date.parse(c.commit.committer.date)).toFormat("DD/MM HH24:MI")
            msg.send "[#{d} -> #{c.commit.committer.name}] #{c.commit.message}"
            send -= 1

# Description:
#   None
#
# Dependencies:
#   "date-utils": ">=1.2.5"
#   "githubot": "0.2.0"
#
# Configuration:
#   HUBOT_GITHUB_TOKEN
#   HUBOT_GITHUB_USER
#
# Commands:
#   hubot repo show <repo> - shows activity of repository
#
# Author:
#   vquaiato

require('date-utils')

module.exports = (robot) ->
  github = require("githubot")(robot)
  robot.respond /repo show (.*)$/i, (msg) ->
    repo = github.qualified_repo msg.match[1]
    url = "https://api.github.com/repos/#{repo}/commits"

    github.get url, (commits) ->
      if commits.message
        msg.send "Achievement unlocked: [NEEDLE IN A HAYSTACK] repository #{commits.message}!"
      else if commits.length == 0
          msg.send "Achievement unlocked: [LIKE A BOSS] no commits found!"
      else
        msg.send "http://github.com/#{repo}"
        send = 5
        for c in commits
          if send
            d = new Date(Date.parse(c.commit.committer.date)).toFormat("DD/MM HH24:MI")
            msg.send "[#{d} -> #{c.commit.committer.name}] #{c.commit.message}"
            send -= 1

Add HUBOT_GITHUB_USER env variable to configuration. Delete unneeded variable 'oauth'.