Revert " Check node if its real before doing anything"

This reverts commit 987396bd6cada56974eead3fe45501bc2000dbbe.

--- client/Framework/components/tree/treeviewcontroller.coffee
+++ client/Framework/components/tree/treeviewcontroller.coffee
@@ -107,7 +107,7 @@
     @nodes[@getNodeId nodeData] = {}

     if options.putDepthInfo
-      if @nodes[@getNodePId nodeData]?.getData?
+      if @nodes[@getNodePId nodeData]
         nodeData.depth = @nodes[@getNodePId(nodeData)].getData().depth + 1
       else
         nodeData.depth = 0
@@ -160,8 +160,6 @@
   addNode:(nodeData, index)->

     nodeData = @repairIds nodeData
-
-
     return unless nodeData
     @getData().push nodeData
     @addIndexedNode nodeData
@@ -226,12 +224,11 @@
     nodeData = nodeView.getData()
     nodeView.$().attr "draggable","true" if @getOptions().dragdrop
     {id, parentId} = nodeData
-
     @nodes[@getNodeId nodeData] = nodeView
     if @nodes[@getNodePId nodeData]
       @expand @nodes[@getNodePId nodeData] unless @getOptions().addListsCollapsed
       # todo: make decoration with events
-      @nodes[@getNodePId nodeData]?.decorateSubItemsState?()
+      @nodes[@getNodePId nodeData].decorateSubItemsState()
     return unless @listControllers[id]
     @addSubList nodeView, id

@@ -257,7 +254,7 @@

     # if node parent is present
     parentNodeView = @nodes[@getNodePId nodeData]
-    if parentNodeView?.getData?
+    if parentNodeView
       prevNeighbor  = getPreviousNeighbor parentNodeView.getData()
       neighborIndex = @indexedNodes.indexOf prevNeighbor
       @indexedNodes.splice neighborIndex + 1, 0, nodeData
@@ -306,7 +303,7 @@

     o = @getOptions()
     listToBeAdded = @listControllers[id].getView()
-    if nodeView?.$?
+    if nodeView
       nodeView.$().after listToBeAdded.$()
       listToBeAdded.parentIsInDom = yes
       listToBeAdded.propagateEvent KDEventType: 'viewAppended'
@@ -435,10 +432,9 @@

   expand:(nodeView)->

-    if nodeView?.getData?
-      nodeData = nodeView.getData()
-      nodeView.expand()
-      @listControllers[@getNodeId nodeData]?.getView().expand()
+    nodeData = nodeView.getData()
+    nodeView.expand()
+    @listControllers[@getNodeId nodeData]?.getView().expand()

   collapse:(nodeView)->


FinderController: Make storing mountedVM states in appStorage synchronous, no need to be asynchronous since it has race-condition there.

--- client/finder/filetree/controllers/findercontroller.coffee
+++ client/finder/filetree/controllers/findercontroller.coffee
@@ -25,7 +25,7 @@
     TreeControllerClass = options.treeControllerClass or NFinderTreeController
     @treeController     = new TreeControllerClass treeOptions, []

-    @appStorage = KD.getSingleton('appStorageController').storage 'Finder', '1.1.1'
+    @appStorage = KD.getSingleton('appStorageController').storage 'Finder', '1.1.2'

     @watchers = {}

@@ -102,15 +102,14 @@
     return  if KD.isGuest()
     groupSlug  = KD.getSingleton("groupsController").getGroupSlug()
     groupSlug ?= KD.defaultSlug
-    @appStorage.fetchValue "mountedVM", (vms)=>
-      vms or= {}
-      vms[groupSlug] or= []
-      items = vms[groupSlug]
-      if state and vmName not in items
-        items.push vmName
-      else if not state and vmName in items
-        items.splice items.indexOf(vmName), 1
-      @appStorage.setValue "mountedVM", vms
+    vms = @appStorage.getValue("mountedVM") or {}
+    vms[groupSlug] or= []
+    items = vms[groupSlug]
+    if state and vmName not in items
+      items.push vmName
+    else if not state and vmName in items
+      items.splice items.indexOf(vmName), 1
+    @appStorage.setValue "mountedVM", vms

   checkVMState: (err, vm, info)->
     return warn err if err or not info


Shotcuts: Remove Meta-G from Find next shortcut.

--- client/ide/lib/views/shortcutsview/ideshortcutsview.coffee
+++ client/ide/lib/views/shortcutsview/ideshortcutsview.coffee
@@ -70,7 +70,7 @@
       'Save as'                : 'Meta-Shift-S'
       'Save all'               : 'Ctrl-Alt-S'
       'Find'                   : 'Meta-F'
-      'Find next'              : { Others: 'Ctrl-K',         Apple: 'Meta-G'       }
+      'Find next'              : 'Ctrl-K'
       'Find previous'          : { Others: 'Ctrl-Shift-K',   Apple: 'Meta-Shift-G' }
       'Find and replace'       : 'Meta-Shift-F'
       'Preview file'           : 'Ctrl-Alt-P'


removing hash after login

removing hash after login

--- client/src/routes.coffee
+++ client/src/routes.coffee
@@ -1,4 +1,4 @@
-angular.module('application').config [
+angular.module('application').config([
   '$locationProvider'
   '$stateProvider'
   '$urlRouterProvider'
@@ -16,4 +16,22 @@
     .state 'home',
       url: '/'
       templateUrl: '/partials/home.html'
+]).run [
+  '$window'
+
+  ($window) ->
+    return unless S($window.location.href).includes('#')
+
+    if $window.history && $window.history.replaceState
+      return $window.history.replaceState "", document.title, $window.location.pathname
+
+    scroll =
+      top: document.body.scrollTop,
+      left: document.body.scrollLeft
+
+    $window.location.hash = ""
+
+
+    document.body.scrollTop = scroll.top;
+    document.body.scrollLeft = scroll.left;
 ]


Fixed problem when importing settings from SABnzbd

--- cs_app/settings.coffee
+++ cs_app/settings.coffee
@@ -129,6 +129,9 @@
     for field in @configSchema
       if field.inisec? and field.ininame? and @sabConfigData[field.inisec]? and @sabConfigData[field.inisec][field.ininame]?
         convertedValue = @convertField @sabConfigData[field.inisec][field.ininame], field
+        # if it is a path, adjust it
+        if field.type is 'file' or field.type is 'dir'
+          convertedValue = path.resolve (process.env.HOME or process.env.HOMEPATH or process.env.USERPROFILE) + '/.sabnzbd/', convertedValue
         if @validateField convertedValue, field
           @[field.name] = convertedValue
           field.loadedFromSABnzbd = true


me numptie you jane

me numptie you jane

--- src/ui/models/viewstate.coffee
+++ src/ui/models/viewstate.coffee
@@ -17,7 +17,7 @@
     leftSize: tryparse(localStorage.leftSize) ? 200
     size: tryparse(localStorage.size ? "[940, 600]")
     pos: tryparse(localStorage.pos ? "[100, 100]")
-    showConvThumbs: tryparse(localStorage.showConvThumbs) ? true
+    showConvThumbs: tryparse(localStorage.showConvThumbs)

     setState: (state) ->
         return if @state == state


Bit of refactoring and fixes, implemented application part of getPage.

--- cms/System/Kernel.coffee
+++ cms/System/Kernel.coffee
@@ -48,24 +48,26 @@
     throw new NotImplementedError "Kernel.preprocess - Not implemented."

   load: (mname) ->
-    delete require.cache[require.resolve mname]
-    return require mname
+    mloc = "../#{mname}"
+    delete require.cache[require.resolve mloc]
+    return require mloc

   getSiteName: () ->
     "A CoffeeNode CMS site"

   getApp: (name) ->
-    load(name + "/core")
+    appConfig = @load "../#{name}/app"
+    @load "#{name}/#{appConfig.mainClass}"

   getPage: (url, post) ->
     content = ""
     if url == "/"
       content = [200, "\n  \n    <title>#{@getSiteName()} - Home</title>\n  \n  \n
Welcome to #{@getSiteName()}; the software which runs this site is not complete.
\n
If you are the site owner, please check the CoffeeNode CMS GitHub repository for updates. Please use other software while CoffeeNode CMS is in development.
\n  \n"]
-    else if url.match(/\/app\/.+\/.*/)
-      # TODO: Capture app name and page from URL here.
-      throw new NotImplementedError "Applications are not implemented."
+    else if url.match /\/app\/.+\/.*/
+      urlMatchResults = url.match /\/app\/(.+)\/.*/
+      appName = urlMatchResults[1]
       app = @getApp appName
-      content = app.page(page, post)
+      content = app.get(url, post)
     else if fs.existsSync("../../" + url + ".js")
       page = require("../../" + url + ".js")
       content = page.get()


added capture event

added capture event

--- src/plugins/server/portalhistory.coffee
+++ src/plugins/server/portalhistory.coffee
@@ -41,7 +41,10 @@
             response = []

             # sort desc
-            records.sort (a, b) -> b.time - a.time
+            records.sort (a, b) ->
+
+                return b.time - a.time if b.time isnt a.time
+                return a.event - b.event

             # unique
             for rec in records
@@ -61,6 +64,12 @@
             # flip to own faction

             if item.markup.TEXT1.plain is ' captured '
+                records.push
+                    time:   item.time
+                    player: item.markup.PLAYER1
+                    event:  'capture'
+                    portal: item.markup.PORTAL1
+
                 lastCaptureEvent = item
                 return next()


operations ReplayArchive: fix rsm max

operations ReplayArchive: fix rsm max

--- src/local/operations.coffee
+++ src/local/operations.coffee
@@ -828,7 +828,7 @@
             t.walkListenerArchive @req.sender, @req.start, @req.end, (results) =>
                 if sent < max
                     @sendNotification results
-                    sent++
+                    sent += results.length
             , cb2
         , (cb2) =>
             sent = 0


Nothing should happen when clicking an arrow while not signed in

--- core/app/backbone/views/evidence/evidence_vote_view.coffee
+++ core/app/backbone/views/evidence/evidence_vote_view.coffee
@@ -27,9 +27,13 @@
     @ui.relevance.text format_as_short_number(@model.relevance())

   _on_up_vote: ->
+    return unless Factlink.Global.signed_in
+
     mp_track "Factlink: Upvote evidence click"
     @model.clickCurrentUserOpinion 'believes'

   _on_down_vote: ->
+    return unless Factlink.Global.signed_in
+
     mp_track "Factlink: Downvote evidence click"
     @model.clickCurrentUserOpinion 'disbelieves'


Update ru.coffee (#5918)

Update ru.coffee (#5918)

* Update ru.coffee

- Fixed broken section

* Update ru.coffee

* Update ru.coffee


Update zh-HANS.coffee

Update zh-HANS.coffee

"account_profile" Simplified Chinese translation part 1 - 20141208

--- app/locale/zh-HANS.coffee
+++ app/locale/zh-HANS.coffee
@@ -26,14 +26,14 @@
     minutes: "分钟"
     hour: "小时"
     hours: "小时"
-#    day: "day"
-#    days: "days"
-#    week: "week"
-#    weeks: "weeks"
-#    month: "month"
-#    months: "months"
-#    year: "year"
-#    years: "years"
+    day: "天"
+    days: "天"
+    week: "星期"
+    weeks: "星期"
+    month: "月"
+    months: "月"
+    year: "年"
+    years: "年"

   modal:
     close: "关闭"
@@ -87,7 +87,7 @@
     sign_up: "注册"
     log_in: "登录"
     social_signup: "或者，你可以通过Facebook或G+注册："
-#    required: "You need to log in before you can go that way."
+    required: "在继续前你必须先登录"

   home:
     slogan: "通过游戏学习 Javascript"
@@ -129,7 +129,7 @@
     forum_suffix: ""
     send: "反馈意见"
     contact_candidate: "联系参选人"
-#    recruitment_reminder: "Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 15% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns."
+    recruitment_reminder: "用这张表格来联系你希望面试的求职者。但请记住如果成功雇佣，CodeCombat会收取与这位员工第一年工资的15%等值的佣金。佣金需在雇佣此员工时就付清并且在之后的90天内如果此员工离职则可退款。兼职，远程办公员工，合同工以及实习生都可免除此费用。"

   diplomat_suggestion:
     title: "帮助我们翻译 CodeCombat"
@@ -173,11 +173,11 @@
     email_announcements: "通知"
     email_announcements_description: "接收关于 CodeCombat 的邮件。"
     email_notifications: "通知"
-#    email_notifications_summary: "Controls for personalized, automatic email notifications related to your CodeCombat activity."
+    email_notifications_summary: "管理有关你在CodeCombat相关活动的定制的自动通知邮件。"
     email_any_notes: "任何通知"
     email_any_notes_description: "取消接收所有活动提醒邮件"
     email_recruit_notes: "工作机会"
-#    email_recruit_notes_description: "If you play really well, we may contact you about getting you a (better) job."
+    email_recruit_notes_description: "如果你玩的真的很不错，我们可能会联系你并给你提供一个（更好的）工作。"
     contributor_emails: "贡献者通知"
     contribute_prefix: "我们在寻找志同道合的人！请到"
     contribute_page: "贡献页面"
@@ -189,12 +189,12 @@
     job_profile: "工作经历"
     job_profile_approved: "你填写的工作经历将由CodeCombat认证. 雇主将看到这些信息，除非你将它设置为不启用状态或者连续四周没有更新."
     job_profile_explanation: "你好! 填写这些信息, 我们将使用它帮你寻找一份软件开发的工作."
-#    sample_profile: "See a sample profile"
+    sample_profile: "查看工作经历样本"
     view_profile: "浏览个人信息"

   account_profile:
     edit_settings: "编辑设置"
-#    done_editing_settings: "Done Editing"
+    done_editing_settings: "完成编辑"
     profile_for_prefix: "关于他的基本资料："
     profile_for_suffix: ""
     approved: "已认证"
@@ -202,25 +202,25 @@
     looking_for: "寻找"
     last_updated: "最后一次更新："
     contact: "联系"
-#    active: "Looking for interview offers now"
-#    inactive: "Not looking for offers right now"
-#    complete: "complete"
-#    next: "Next"
-#    next_city: "city?"
-#    next_country: "pick your country."
-#    next_name: "name?"
-#    next_short_description: "summarize yourself at a glance."
-#    next_long_description: "describe the work you're looking for."
-#    next_skills: "list at least five skills."
-#    next_work: "list your work experience."
-#    next_education: "recount your educational ordeals."
-#    next_projects: "show off up to three projects you've worked on."
-#    next_links: "add any personal or social links."
-#    next_photo: "add an optional professional photo."
-#    next_active: "mark yourself open to offers to show up in searches."
-#    example_blog: "Your Blog"
-#    example_github: "Your GitHub"
-#    links_header: "Personal Links"
+    active: "正在寻求面试机会"
+    inactive: "目前没有在寻找新的工作机会"
+    complete: "完成"
+    next: "下一项"
+    next_city: "城市？"
+    next_country: "选择你所处的国家"
+    next_name: "名字？"
+    next_short_description: "简短描述下你自己。"
+    next_long_description: "描述一下你希望找到何种工作。"
+    next_skills: "列出至少5项技能。"
+    next_work: "列出你的工作经历。"
+    next_education: "描述一下你的教育经历。"
+    next_projects: "展示你曾经参与过的至多3个项目。"
+    next_links: "添加任何个人网站或社交媒体链接。"
+    next_photo: "添加一张职业的照片（可选）。"
+    next_active: "将自己标记为正在寻求工作机会以使自己的名字出现在搜索结果中。"
+    example_blog: "你的博客"
+    example_github: "你的GitHub"
+    links_header: "个人网站链接"
 #    links_blurb: "Link any other sites or profiles you want to highlight, like your GitHub, your LinkedIn, or your blog."
 #    links_name: "Link Name"
 #    links_name_help: "What are you linking to?"


Fixes #47

Fixes #47

--- app/models/project.coffee
+++ app/models/project.coffee
@@ -27,7 +27,7 @@
   lastFile:( ->
     files = @get "files"
     if !Ember.isEmpty files
-      files.sortBy('createdOn')[0]
+      files.sortBy('createdOn:desc')[0]
   ).property "files.@each"

   hasMultipleFiles:( ->


CANDLES is done

CANDLES is done

--- app/models/subject.coffee
+++ app/models/subject.coffee
@@ -36,7 +36,7 @@
     if Math.random() > 0.5
       if Math.random() > (1/3) then @::surveys.ukidss.id else @::surveys.ferengi.id
     else
-      if Math.random() > (1/3) then @::surveys.candels.id else @::surveys.sloan.id
+      @::surveys.sloan.id

   @next: ->
     if @current


editor.coffee: compute HTML only once

editor.coffee: compute HTML only once

--- client/editor.coffee
+++ client/editor.coffee
@@ -2,9 +2,9 @@
 require './codemirror-apl-mode'
 autocompletion = require './autocompletion'

-module.exports = (e, opts = {}) -> # opts contains callbacks to ide.coffee
+editorHTML = do ->
   b = (cssClasses, description) -> ""
-  ($e = $ e).html """
+  """

       #{[
         # The first two buttons are placed on the right-hand side through CSS.  In a floating window they are hidden.
@@ -49,8 +49,9 @@

   """
-  b = null
-
+
+module.exports = (e, opts) -> # opts contains callbacks to ide.coffee
+  ($e = $ e).html editorHTML
   volatileLine = null # the line number of the empty line inserted when cursor is at eof and you press <down>

   cm = CodeMirror $e.find('.cm')[0],


use remove non-module sourcemaps

use remove non-module sourcemaps

Doesn't play well with es6 modules

--- configs/webpack/base.coffee
+++ configs/webpack/base.coffee
@@ -60,7 +60,7 @@
 # base config, true for all builds no matter what conditions
 BASE_CONFIG =
   cache: true
-  devtool: 'cheap-module-eval-source-map'
+  devtool: 'cheap-source-map'
   resolve:
     extensions: RESOLVABLE_EXTENSIONS
   output:


Fix tool ordering

Fix tool ordering

--- coffee/jquery.coffee
+++ coffee/jquery.coffee
@@ -23,10 +23,8 @@
   opts.watermarkImage ?= null
   unless 'toolClasses' of opts
     opts.toolClasses = [
-        LC.TextWidget,
         LC.PencilWidget, LC.EraserWidget, LC.LineWidget, LC.RectangleWidget,
-        #LC.TextWidget, LC.PanWidget, LC.EyeDropperWidget,
-        LC.PanWidget, LC.EyeDropperWidget,
+        LC.TextWidget, LC.PanWidget, LC.EyeDropperWidget,
     ]

   $el = $(el)


Add os system information

Add os system information

--- coffee/server.coffee
+++ coffee/server.coffee
@@ -56,9 +56,16 @@
   res.json 200, ['turer', 'steder', 'områder', 'grupper', 'aktiviteter', 'bilder']

 app.get '/system', (req, res, next) ->
+  os = require 'os'
   res.json 200,
-    uptime: process.uptime()
-    memory: process.memoryUsage()
+    app:
+      uptime: process.uptime()
+      memory: process.memoryUsage()
+    os:
+      uptime: os.uptime()
+      loadavg: os.loadavg()
+      totalmem: os.totalmem()
+      freemem: os.freemem()

 app.param 'objectid', document.param
 app.all '/:collection/:objectid', (req, res, next) ->


Ensure AuthenticatedRoute method is called.  Should close #7

--- app/routes/project.coffee
+++ app/routes/project.coffee
@@ -4,12 +4,14 @@

 App.ProjectRoute = AuthenticatedRoute.extend
   beforeModel: ->
-    @loadingIndicator = new Spinner().spin()
-    document.querySelector('#app').appendChild @loadingIndicator.el
-
+    @_super arguments...
+    if zooniverse.models.User.current
+      @loadingIndicator = new Spinner().spin()
+      document.querySelector('#app').appendChild @loadingIndicator.el
+
   afterModel: ->
     @loadingIndicator.stop()
-
+
   model: (params) ->
     promises = Ember.RSVP.hash
       project: zooniverse.api.get("/projects/#{ params.name }", with_roles: true)


Catch up to latest changes in AngularJS

Catch up to latest changes in AngularJS

--- app/scripts/controllers/domains.coffee
+++ app/scripts/controllers/domains.coffee
@@ -17,9 +17,7 @@

     @scope.$on '$destroy', @_cleanUp

-    @rootScope = _.find @scope, {$parent: null}
-
-    @_scrollToViolations() if @rootScope.prevHash == '#!/violations'
+    @_scrollToViolations() if @scope.$parent.prevHash == '#!/violations'

   _scrollToElement: (el) =>
     srcollY = el[0].offsetTop + parseInt(el.css('margin-top'), 10) / 2
@@ -30,9 +28,10 @@
   _scrollToViolations: ->
     el = angular.element('#violations')
     if el.length == 1
+      counter = 0
       scrollInterval = @interval(=>
         dy = @_scrollToElement(el)
-        if dy <= 5
+        if dy <= 5 or counter++ > 10
           @interval.cancel(scrollInterval)
       40)


ListViewController: implemented custom scrollviews for listviews

--- src/components/list/listviewcontroller.coffee
+++ src/components/list/listviewcontroller.coffee
@@ -1,8 +1,8 @@
-KDView           = require './../../core/view.coffee'
-KDViewController = require './../../core/viewcontroller.coffee'
-KDScrollView     = require './../scrollview/scrollview.coffee'
-KDListView       = require './../list/listview.coffee'
-KDLoaderView     = require './../loader/loaderview.coffee'
+KDView             = require './../../core/view.coffee'
+KDViewController   = require './../../core/viewcontroller.coffee'
+KDCustomScrollView = require './../scrollview/customscrollview.coffee'
+KDListView         = require './../list/listview.coffee'
+KDLoaderView       = require './../loader/loaderview.coffee'

 module.exports = class KDListViewController extends KDViewController

@@ -42,9 +42,10 @@
       @setListView listView = new KDListView viewOptions

     if options.scrollView
-      @scrollView = new KDScrollView
+      @customScrollView = new KDCustomScrollView
         lazyLoadThreshold : options.lazyLoadThreshold
         ownScrollBars     : options.ownScrollBars
+      @scrollView = @customScrollView.wrapper

     options.view = if options.wrapper
     then new KDView cssClass : "listview-wrapper"
@@ -65,21 +66,29 @@
     if options.keyNav
       listView.on 'KeyDownOnList', (event)=> @keyDownPerformed listView, event

-  loadView:(mainView)->
-
-    options = @getOptions()
-    if options.scrollView
-      mainView.addSubView @scrollView
+  loadView: (mainView) ->
+
+    { scrollView
+      startWithLazyLoader
+      noItemFoundWidget
+    } = @getOptions()
+
+    {windowController} = KD.singletons
+
+    if scrollView
+      mainView.addSubView @customScrollView
       @scrollView.addSubView @getListView()
-      if options.startWithLazyLoader
-        @showLazyLoader no
+      @showLazyLoader no  if startWithLazyLoader
+
       @scrollView.on 'LazyLoadThresholdReached', @bound "showLazyLoader"

-    if options.noItemFoundWidget
-      @putNoItemView()
-
-    @instantiateListItems(@getData()?.items or [])
-    KD.getSingleton("windowController").on "ReceivedMouseUpElsewhere", (event)=> @mouseUpHappened event
+    @putNoItemView()  if noItemFoundWidget
+
+    @instantiateListItems @getData()?.items or []
+
+    windowController.on "ReceivedMouseUpElsewhere", @bound 'mouseUpHappened'
+
+

   instantiateListItems:(items)->
     newItems = for itemData in items


change scroll state only as needed

change scroll state only as needed

--- src/components/task-teacher-review/index.cjsx
+++ src/components/task-teacher-review/index.cjsx
@@ -82,16 +82,18 @@
     @goToStep(@state.scrollState.key)() if @state.scrollState?.key?

   componentDidUpdate: (prevProps, prevState) ->
-    didScrollStateChange = not (prevState.scrollState.scrollPoint is @getScrollStateByScroll(@state.scrollTop).scrollPoint)
+    didScrollStateChange = not (prevState.scrollState.key is @getScrollStateByScroll(@state.scrollTop).key)
     didCurrentStepChange = not (@state.currentStep is prevState.scrollState?.key)

-    @setScrollState() if didScrollStateChange
-    @scrollToKey(@state.currentStep) if didCurrentStepChange and not didScrollStateChange
+    if didCurrentStepChange and not didScrollStateChange
+      @scrollToKey(@state.currentStep)
+    else if didScrollStateChange
+      @setScrollState()

   scrollToKey: (stepKey) ->
     scrollState = @getScrollStateByKey(stepKey)

-    window.scrollTo(0, (scrollState.scrollPoint - @state.scrollTopBuffer + 1))
+    window.scrollTo(0, (scrollState.scrollPoint - @state.scrollTopBuffer + 2))

   # Curried for React
   goToStep: (stepKey) ->


fixed opening of followers, following and likes subview in own profile. however these views do not seem to work properly, gonna check

--- client/landing/app/Applications/Members.kdapplication/ContentDisplays/ownprofileview.coffee
+++ client/landing/app/Applications/Members.kdapplication/ContentDisplays/ownprofileview.coffee
@@ -26,6 +26,7 @@
         href      : '#'
       pistachio   : "{{#(counts.followers)}} Followers"
       click       : (event)->
+        event.preventDefault()
         return if memberData.counts.followers is 0
         KD.getSingleton("appManager").tell "Members", "createFolloweeContentDisplay", memberData, 'followers'
     , memberData
@@ -36,6 +37,7 @@
         href      : '#'
       pistachio   : "{{#(counts.following)}} Following"
       click       : (event)->
+        event.preventDefault()
         return if memberData.counts.following is 0
         KD.getSingleton("appManager").tell "Members", "createFolloweeContentDisplay", memberData, 'following'
     , memberData
@@ -46,6 +48,7 @@
         href      : '#'
       pistachio   : "{{#(counts.likes) or 0}} Likes"
       click       : (event)->
+        event.preventDefault()
         return if memberData.counts.following is 0
         KD.getSingleton("appManager").tell "Members", "createLikedContentDisplay", memberData
     , memberData


should take care of #703

should take care of #703

--- resource/lib/collections.coffee
+++ resource/lib/collections.coffee
@@ -15,25 +15,21 @@
         raw.push(collection)
     debug('Collections: fetched', raw.length, 'collections from Zotero')

-  debug('Collections: found', raw.length, 'collections:', raw)
-
   collections = {}
   for collection in raw
-    debug('found collection', collection.fields.name, 'with parent', collection.fields.parentKey)
     collections[collection.primary.key] = {
       key: collection.primary.key
       name: collection.fields.name
       collections: []
       items: (item.key for item in (collection.descendents || []) when item.type == 'item')
       parent: collection.fields.parentKey
-      root: !collection.fields.parentKey
     }

   for key, collection of collections
-    if collection.parent && !collections[collection.parent]
-      debug(collection.name, '/', key, 'has non-existing parent', {parent: collection.parent})
-
-    collections[collection.parent].collections.push(collection) if collection.parent
+    if collection.parent && collections[collection.parent]
+      collections[collection.parent].collections.push(collection)
+    else
+      collection.root = true
     delete collection.parent
   debug('got collections:', collections)


Sets lang attribute to html element by default

--- detectr.coffee
+++ detectr.coffee
@@ -127,6 +127,9 @@
         language = navigator.language or navigator.systemLanguage
         language.split('-')[0] if language?

+    # Sets language attribute to browser language by default
+    document.documentElement.setAttribute('lang', detectr.Browser.language())
+
     detectr.Display or=
       width: -> window.innerWidth
       height: -> window.innerHeight


embedly fixes

embedly fixes

--- core/utils.coffee
+++ core/utils.coffee
@@ -107,10 +107,19 @@
     s = t
     s

-  proxifyUrl:(url="")->
+  proxifyUrl:(url="", options={})->
+
+    options.width   or= -1
+    options.height  or= -1
+
     if url is ""
-    then "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
-    else "#{location.protocol}//#{location.host}/-/imageProxy?url=#{encodeURIComponent(url)}"
+      return "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
+
+    if options.width or options.height
+      endpoint = "/resize"
+    if options.crop
+      endpoint = "/crop"
+    return "https://i.embed.ly/1/display#{endpoint or ''}?grow=false&width=#{options.width}&height=#{options.height}&key=#{KD.config.embedly.apiKey}&url=#{encodeURIComponent url}"

   applyMarkdown: (text)->


Workspace: Fixed #559 MR reviews.

Workspace: Fixed #559 MR reviews.

--- core/utils.coffee
+++ core/utils.coffee
@@ -823,7 +823,7 @@
       defaultValue : options.inputDefaultValue or ""

     form.addSubView labelFinder = new KDLabelView
-      title : "Select a folder:"
+      title : options.finderLabel or "Select a folder:"

     dialog.show()
     input.setFocus()


adds matching (mispelled) event for comparison to commercial filtering

--- apps/browse/client.coffee
+++ apps/browse/client.coffee
@@ -1,12 +1,18 @@
+_ = require 'underscore'
 scrollFrame = require 'scroll-frame'
 { setupFilter } = require '../../components/filter2/index.coffee'
 aggregationParams = require './aggregations.coffee'
 sd = require('sharify').data

 module.exports.init = ->
-  setupFilter
+  { params } = setupFilter
     filterRoot: '/browse/artworks'
     el: $ '#browse-filter'
     aggregations: aggregationParams

   scrollFrame '#browse-filter a' unless sd.EIGEN
+
+  params.on 'change:for_sale change:price_range change:dimension_range change:medium', ->
+    analytics.track 'Commericial filter: params changed',
+      current: _.omit params.attributes, 'aggregations'
+      changed: _.omit params.changedAttributes(), 'aggregations'


ongoing stream work

ongoing stream work

--- test/gerber-parser_test.coffee
+++ test/gerber-parser_test.coffee
@@ -218,13 +218,15 @@
         p.write param 'ADD12P,5X4X0X0.6', 3
         p.write param 'ADD13P,5X4X0X0.6X0.5', 4

-  #
-  #   describe 'with aperture macros', ->
-  #
-  #     it 'should parse an aperture macro with modifiers', ->
-  #       expect( p.parseCommand param 'ADD10CIRC,1X0.5' ).to.eql {
-  #         tool: { D10: { macro: 'CIRC', mods: [ 1, 0.5 ] } }
-  #       }
+
+    describe 'with aperture macros', ->
+      it 'should parse an aperture macro with modifiers', ->
+        p.once 'readable', ->
+          data = p.read()
+          expect(data.tool).to.eql {D10: {macro: 'CIRC', mods: [1, 0.5]}}
+
+        p.write param 'ADD10CIRC,1X0.5', 1
+
   #
   #     it 'should parse a macro with no modifiers', ->
   #       expect( p.parseCommand param 'ADD11RECT' ).to.eql {


add Ad onclick

add Ad onclick

--- public/js/map.coffee
+++ public/js/map.coffee
@@ -66,11 +66,14 @@

-	# // map.on('click', function(e) {
-	# // 	ad = {
-	# // 	};
-	# //     alert(e.latlng); // e is an event object (MouseEvent in this case)
-	# // });
+	map.on 'click', (e) ->
+		ad =
+			location: e.latlng
+			radius: 500
+			text: 'Novy Ad'
+
+		displayAd ad
+


Return early in JS if last batch

Return early in JS if last batch

--- app/assets/javascripts/admin/product_import/controllers/import_form_controller.js.coffee
+++ app/assets/javascripts/admin/product_import/controllers/import_form_controller.js.coffee
@@ -60,18 +60,20 @@
   $scope.processBatch = (step, batchIndex, batchCount) ->
     start = (batchIndex * $scope.batchSize) + 1
     end = (batchIndex + 1) * $scope.batchSize
-    withNextBatch = batchIndex + 1 < batchCount
+    isLastBatch = batchCount == batchIndex + 1

     promise = if step == 'import'
       $scope.processImport(start, end)
     else if step == 'save'
       $scope.processSave(start, end)

+    return if isLastBatch
+
     processNextBatch = ->
       $scope.processBatch(step, batchIndex + 1, batchCount)

     # Process next batch whether or not processing of the current batch succeeds.
-    promise.then(processNextBatch, processNextBatch) if withNextBatch
+    promise.then(processNextBatch, processNextBatch)

   $scope.processImport = (start, end) ->
     $http(


Update old comment

Update old comment

--- backbone.tableview.coffee
+++ backbone.tableview.coffee
@@ -187,7 +187,7 @@
         filter.init = (filter.set or _.identity) @data[name] or filter.init or ""
         return filter

-    # Update collection only if event was trigger by an enter
+    # Update collection with search query
     updateSearch: (e) =>
         @setData @search.query or "q", e.currentTarget.value


remove old test case

remove old test case

--- test/test-pandoc-filter.coffee
+++ test/test-pandoc-filter.coffee
@@ -1,80 +0,0 @@
-should       = require 'should'
-fs           = require 'fs'
-path         = require 'path'
-HOMEDIR      = path.join(__dirname,'..')
-LIB_COV      = path.join(HOMEDIR,'lib-cov')
-LIB_DIR      = if fs.existsSync(LIB_COV) then LIB_COV else path.join(HOMEDIR,'lib')
-PandocFilter  = require(path.join(LIB_DIR,'pandoc-filter'))
-
-describe 'PandocFilter',->
-
-  # it 'can be used to insert headers',(done)->
-  #   original = [{"docTitle":[{"Str":"Sample"},"Space",{"Str":"Pandoc"},"Space",{"Str":"Markdown"},"Space",{"Str":"File"}],"docAuthors":[[{"Str":"Rod"},"Space",{"Str":"Waldhoff"}]],"docDate":[{"Str":"October"},"Space",{"Str":"2013"}]},[{"Para":[{"Str":"This"},"Space",{"Str":"is"},"Space",{"Str":"a"},"Space",{"Str":"simple"},"Space",{"Str":"markdown"},"Space",{"Str":"file"},{"Str":"."}]},{"Para":[{"Str":"Lorem"},"Space",{"Str":"ipsum"},"Space",{"Str":"dolor"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},{"Str":","},"Space",{"Str":"consectetuer"},"Space",{"Str":"adipiscing"},"Space",{"Str":"elit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"hendrerit"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"pretium"},"Space",{"Str":"posuere"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"quam"},"Space",{"Str":"nisl"},{"Str":","},"Space",{"Str":"tincidunt"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"mattis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"convallis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Cum"},"Space",{"Str":"sociis"},"Space",{"Str":"natoque"},"Space",{"Str":"penatibus"},"Space",{"Str":"et"},"Space",{"Str":"magnis"},"Space",{"Str":"dis"},"Space",{"Str":"parturient"},"Space",{"Str":"montes"},{"Str":","},"Space",{"Str":"nascetur"},"Space",{"Str":"ridiculus"},"Space",{"Str":"mus"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"vitae"},"Space",{"Str":"dolor"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tristique"},"Space",{"Str":"diam"},"Space",{"Str":"non"},"Space",{"Str":"turpis"},{"Str":"."},"Space",{"Str":"Cras"},"Space",{"Str":"placerat"},"Space",{"Str":"accumsan"},"Space",{"Str":"nulla"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"rutrum"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"vestibulum"},"Space",{"Str":"accumsan"},"Space",{"Str":"nisl"},{"Str":"."}]},{"Para":[{"Str":"Pellentesque"},"Space",{"Str":"dapibus"},"Space",{"Str":"suscipit"},"Space",{"Str":"ligula"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"posuere"},"Space",{"Str":"augue"},"Space",{"Str":"in"},"Space",{"Str":"quam"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"tortor"},"Space",{"Str":"sodales"},"Space",{"Str":"tellus"},"Space",{"Str":"ultricies"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Suspendisse"},"Space",{"Str":"potenti"},{"Str":"."},"Space",{"Str":"Aenean"},"Space",{"Str":"in"},"Space",{"Str":"sem"},"Space",{"Str":"ac"},"Space",{"Str":"leo"},"Space",{"Str":"mollis"},"Space",{"Str":"blandit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"neque"},"Space",{"Str":"quam"},{"Str":","},"Space",{"Str":"dignissim"},"Space",{"Str":"in"},{"Str":","},"Space",{"Str":"mollis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"sagittis"},"Space",{"Str":"eu"},{"Str":","},"Space",{"Str":"wisi"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"laoreet"},"Space",{"Str":"quam"},"Space",{"Str":"sed"},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"at"},"Space",{"Str":"dui"},"Space",{"Str":"in"},"Space",{"Str":"ligula"},"Space",{"Str":"mollis"},"Space",{"Str":"ultricies"},{"Str":"."},"Space",{"Str":"Integer"},"Space",{"Str":"placerat"},"Space",{"Str":"tristique"},"Space",{"Str":"nisl"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"augue"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Vestibulum"},"Space",{"Str":"convallis"},{"Str":","},"Space",{"Str":"lorem"},"Space",{"Str":"a"},"Space",{"Str":"tempus"},"Space",{"Str":"semper"},{"Str":","},"Space",{"Str":"dui"},"Space",{"Str":"dui"},"Space",{"Str":"euismod"},"Space",{"Str":"elit"},{"Str":","},"Space",{"Str":"vitae"},"Space",{"Str":"placerat"},"Space",{"Str":"urna"},"Space",{"Str":"tortor"},"Space",{"Str":"vitae"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"libero"},"Space",{"Str":"mauris"},{"Str":","},"Space",{"Str":"consequat"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"varius"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"dictum"},"Space",{"Str":"id"},{"Str":","},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"mollis"},"Space",{"Str":"tincidunt"},"Space",{"Str":"felis"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"feugiat"},"Space",{"Str":"tellus"},"Space",{"Str":"ut"},"Space",{"Str":"neque"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"risus"},"Space",{"Str":"a"},"Space",{"Str":"rhoncus"},"Space",{"Str":"fermentum"},{"Str":","},"Space",{"Str":"tellus"},"Space",{"Str":"tellus"},"Space",{"Str":"lacinia"},"Space",{"Str":"purus"},{"Str":","},"Space",{"Str":"et"},"Space",{"Str":"dictum"},"Space",{"Str":"nunc"},"Space",{"Str":"justo"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"elit"},{"Str":"."}]},{"Para":[{"Str":"Nullam"},"Space",{"Str":"eu"},"Space",{"Str":"ante"},"Space",{"Str":"vel"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"dignissim"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"suscipit"},{"Str":","},"Space",{"Str":"wisi"},"Space",{"Str":"nec"},"Space",{"Str":"facilisis"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"est"},"Space",{"Str":"dui"},"Space",{"Str":"fermentum"},"Space",{"Str":"leo"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"tempor"},"Space",{"Str":"ligula"},"Space",{"Str":"erat"},"Space",{"Str":"quis"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"porta"},"Space",{"Str":"vulputate"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"rutrum"},"Space",{"Str":"turpis"},"Space",{"Str":"sed"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"aliquet"},{"Str":","},"Space",{"Str":"augue"},"Space",{"Str":"nec"},"Space",{"Str":"adipiscing"},"Space",{"Str":"interdum"},{"Str":","},"Space",{"Str":"lacus"},"Space",{"Str":"tellus"},"Space",{"Str":"malesuada"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"varius"},"Space",{"Str":"mi"},"Space",{"Str":"purus"},"Space",{"Str":"non"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"condimentum"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"ut"},"Space",{"Str":"suscipit"},"Space",{"Str":"hendrerit"},{"Str":","},"Space",{"Str":"ipsum"},"Space",{"Str":"augue"},"Space",{"Str":"ornare"},"Space",{"Str":"nulla"},{"Str":","},"Space",{"Str":"non"},"Space",{"Str":"luctus"},"Space",{"Str":"diam"},"Space",{"Str":"neque"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"urna"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"vulputate"},"Space",{"Str":"vestibulum"},"Space",{"Str":"lorem"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"sagittis"},{"Str":","},"Space",{"Str":"libero"},"Space",{"Str":"non"},"Space",{"Str":"molestie"},"Space",{"Str":"mollis"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"orci"},"Space",{"Str":"ultrices"},"Space",{"Str":"dolor"},{"Str":","},"Space",{"Str":"at"},"Space",{"Str":"vulputate"},"Space",{"Str":"neque"},"Space",{"Str":"nulla"},"Space",{"Str":"lacinia"},"Space",{"Str":"eros"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"id"},"Space",{"Str":"ligula"},"Space",{"Str":"quis"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"tempor"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"lacinia"},"Space",{"Str":"pulvinar"},"Space",{"Str":"nibh"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"a"},"Space",{"Str":"sapien"},{"Str":"."}]},{"Para":[{"Str":"Aliquam"},"Space",{"Str":"erat"},"Space",{"Str":"volutpat"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"eleifend"},"Space",{"Str":"leo"},"Space",{"Str":"vitae"},"Space",{"Str":"magna"},{"Str":"."},"Space",{"Str":"In"},"Space",{"Str":"id"},"Space",{"Str":"erat"},"Space",{"Str":"non"},"Space",{"Str":"orci"},"Space",{"Str":"commodo"},"Space",{"Str":"lobortis"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"neque"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"cursus"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"gravida"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"lobortis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"diam"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"fermentum"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tempus"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"ac"},"Space",{"Str":"felis"},"Space",{"Str":"vel"},"Space",{"Str":"velit"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"at"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"neque"},"Space",{"Str":"nec"},"Space",{"Str":"dui"},"Space",{"Str":"dignissim"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Vivamus"},"Space",{"Str":"id"},"Space",{"Str":"enim"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"neque"},"Space",{"Str":"orci"},{"Str":","},"Space",{"Str":"porta"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"aliquet"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"semper"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"massa"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},"Space",{"Str":"tortor"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"euismod"},"Space",{"Str":"tellus"},"Space",{"Str":"id"},"Space",{"Str":"erat"},{"Str":"."}]}]]
-  #   filtered = [{"docTitle":[{"Str":"Sample"},"Space",{"Str":"Pandoc"},"Space",{"Str":"Markdown"},"Space",{"Str":"File"}],"docAuthors":[[{"Str":"Rod"},"Space",{"Str":"Waldhoff"}]],"docDate":[{"Str":"October"},"Space",{"Str":"2013"}]},[{"Header":[1,[{"Str":"A Heading before a paragraph with 12 words."}]]},{"Para":[{"Str":"This"},"Space",{"Str":"is"},"Space",{"Str":"a"},"Space",{"Str":"simple"},"Space",{"Str":"markdown"},"Space",{"Str":"file"},{"Str":"."}]},{"Header":[1,[{"Str":"A Heading before a paragraph with 132 words."}]]},{"Para":[{"Str":"Lorem"},"Space",{"Str":"ipsum"},"Space",{"Str":"dolor"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},{"Str":","},"Space",{"Str":"consectetuer"},"Space",{"Str":"adipiscing"},"Space",{"Str":"elit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"hendrerit"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"pretium"},"Space",{"Str":"posuere"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"quam"},"Space",{"Str":"nisl"},{"Str":","},"Space",{"Str":"tincidunt"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"mattis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"convallis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Cum"},"Space",{"Str":"sociis"},"Space",{"Str":"natoque"},"Space",{"Str":"penatibus"},"Space",{"Str":"et"},"Space",{"Str":"magnis"},"Space",{"Str":"dis"},"Space",{"Str":"parturient"},"Space",{"Str":"montes"},{"Str":","},"Space",{"Str":"nascetur"},"Space",{"Str":"ridiculus"},"Space",{"Str":"mus"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"vitae"},"Space",{"Str":"dolor"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tristique"},"Space",{"Str":"diam"},"Space",{"Str":"non"},"Space",{"Str":"turpis"},{"Str":"."},"Space",{"Str":"Cras"},"Space",{"Str":"placerat"},"Space",{"Str":"accumsan"},"Space",{"Str":"nulla"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"rutrum"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"vestibulum"},"Space",{"Str":"accumsan"},"Space",{"Str":"nisl"},{"Str":"."}]},{"Header":[1,[{"Str":"A Heading before a paragraph with 248 words."}]]},{"Para":[{"Str":"Pellentesque"},"Space",{"Str":"dapibus"},"Space",{"Str":"suscipit"},"Space",{"Str":"ligula"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"posuere"},"Space",{"Str":"augue"},"Space",{"Str":"in"},"Space",{"Str":"quam"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"tortor"},"Space",{"Str":"sodales"},"Space",{"Str":"tellus"},"Space",{"Str":"ultricies"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Suspendisse"},"Space",{"Str":"potenti"},{"Str":"."},"Space",{"Str":"Aenean"},"Space",{"Str":"in"},"Space",{"Str":"sem"},"Space",{"Str":"ac"},"Space",{"Str":"leo"},"Space",{"Str":"mollis"},"Space",{"Str":"blandit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"neque"},"Space",{"Str":"quam"},{"Str":","},"Space",{"Str":"dignissim"},"Space",{"Str":"in"},{"Str":","},"Space",{"Str":"mollis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"sagittis"},"Space",{"Str":"eu"},{"Str":","},"Space",{"Str":"wisi"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"laoreet"},"Space",{"Str":"quam"},"Space",{"Str":"sed"},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"at"},"Space",{"Str":"dui"},"Space",{"Str":"in"},"Space",{"Str":"ligula"},"Space",{"Str":"mollis"},"Space",{"Str":"ultricies"},{"Str":"."},"Space",{"Str":"Integer"},"Space",{"Str":"placerat"},"Space",{"Str":"tristique"},"Space",{"Str":"nisl"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"augue"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Vestibulum"},"Space",{"Str":"convallis"},{"Str":","},"Space",{"Str":"lorem"},"Space",{"Str":"a"},"Space",{"Str":"tempus"},"Space",{"Str":"semper"},{"Str":","},"Space",{"Str":"dui"},"Space",{"Str":"dui"},"Space",{"Str":"euismod"},"Space",{"Str":"elit"},{"Str":","},"Space",{"Str":"vitae"},"Space",{"Str":"placerat"},"Space",{"Str":"urna"},"Space",{"Str":"tortor"},"Space",{"Str":"vitae"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"libero"},"Space",{"Str":"mauris"},{"Str":","},"Space",{"Str":"consequat"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"varius"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"dictum"},"Space",{"Str":"id"},{"Str":","},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"mollis"},"Space",{"Str":"tincidunt"},"Space",{"Str":"felis"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"feugiat"},"Space",{"Str":"tellus"},"Space",{"Str":"ut"},"Space",{"Str":"neque"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"risus"},"Space",{"Str":"a"},"Space",{"Str":"rhoncus"},"Space",{"Str":"fermentum"},{"Str":","},"Space",{"Str":"tellus"},"Space",{"Str":"tellus"},"Space",{"Str":"lacinia"},"Space",{"Str":"purus"},{"Str":","},"Space",{"Str":"et"},"Space",{"Str":"dictum"},"Space",{"Str":"nunc"},"Space",{"Str":"justo"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"elit"},{"Str":"."}]},{"Header":[1,[{"Str":"A Heading before a paragraph with 230 words."}]]},{"Para":[{"Str":"Nullam"},"Space",{"Str":"eu"},"Space",{"Str":"ante"},"Space",{"Str":"vel"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"dignissim"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"suscipit"},{"Str":","},"Space",{"Str":"wisi"},"Space",{"Str":"nec"},"Space",{"Str":"facilisis"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"est"},"Space",{"Str":"dui"},"Space",{"Str":"fermentum"},"Space",{"Str":"leo"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"tempor"},"Space",{"Str":"ligula"},"Space",{"Str":"erat"},"Space",{"Str":"quis"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"porta"},"Space",{"Str":"vulputate"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"rutrum"},"Space",{"Str":"turpis"},"Space",{"Str":"sed"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"aliquet"},{"Str":","},"Space",{"Str":"augue"},"Space",{"Str":"nec"},"Space",{"Str":"adipiscing"},"Space",{"Str":"interdum"},{"Str":","},"Space",{"Str":"lacus"},"Space",{"Str":"tellus"},"Space",{"Str":"malesuada"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"varius"},"Space",{"Str":"mi"},"Space",{"Str":"purus"},"Space",{"Str":"non"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"condimentum"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"ut"},"Space",{"Str":"suscipit"},"Space",{"Str":"hendrerit"},{"Str":","},"Space",{"Str":"ipsum"},"Space",{"Str":"augue"},"Space",{"Str":"ornare"},"Space",{"Str":"nulla"},{"Str":","},"Space",{"Str":"non"},"Space",{"Str":"luctus"},"Space",{"Str":"diam"},"Space",{"Str":"neque"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"urna"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"vulputate"},"Space",{"Str":"vestibulum"},"Space",{"Str":"lorem"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"sagittis"},{"Str":","},"Space",{"Str":"libero"},"Space",{"Str":"non"},"Space",{"Str":"molestie"},"Space",{"Str":"mollis"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"orci"},"Space",{"Str":"ultrices"},"Space",{"Str":"dolor"},{"Str":","},"Space",{"Str":"at"},"Space",{"Str":"vulputate"},"Space",{"Str":"neque"},"Space",{"Str":"nulla"},"Space",{"Str":"lacinia"},"Space",{"Str":"eros"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"id"},"Space",{"Str":"ligula"},"Space",{"Str":"quis"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"tempor"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"lacinia"},"Space",{"Str":"pulvinar"},"Space",{"Str":"nibh"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"a"},"Space",{"Str":"sapien"},{"Str":"."}]},{"Header":[1,[{"Str":"A Heading before a paragraph with 170 words."}]]},{"Para":[{"Str":"Aliquam"},"Space",{"Str":"erat"},"Space",{"Str":"volutpat"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"eleifend"},"Space",{"Str":"leo"},"Space",{"Str":"vitae"},"Space",{"Str":"magna"},{"Str":"."},"Space",{"Str":"In"},"Space",{"Str":"id"},"Space",{"Str":"erat"},"Space",{"Str":"non"},"Space",{"Str":"orci"},"Space",{"Str":"commodo"},"Space",{"Str":"lobortis"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"neque"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"cursus"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"gravida"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"lobortis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"diam"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"fermentum"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tempus"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"ac"},"Space",{"Str":"felis"},"Space",{"Str":"vel"},"Space",{"Str":"velit"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"at"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"neque"},"Space",{"Str":"nec"},"Space",{"Str":"dui"},"Space",{"Str":"dignissim"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Vivamus"},"Space",{"Str":"id"},"Space",{"Str":"enim"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"neque"},"Space",{"Str":"orci"},{"Str":","},"Space",{"Str":"porta"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"aliquet"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"semper"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"massa"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},"Space",{"Str":"tortor"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"euismod"},"Space",{"Str":"tellus"},"Space",{"Str":"id"},"Space",{"Str":"erat"},{"Str":"."}]}]]
-  #   expected = JSON.stringify(filtered)
-  #   filter = new PandocFilter (key,value,context)->
-  #     if Array.isArray(value)
-  #       new_array = []
-  #       for elt in value
-  #         if elt.Para?
-  #           new_array.push( { "Header":[1,[{"Str":"A Heading before a paragraph with #{elt.Para.length} words."}]] } )
-  #         new_array.push elt
-  #       return new_array
-  #     else
-  #       return value
-  #   result = filter.map(original)
-  #   found = JSON.stringify(result)
-  #   found.should.equal(expected)
-  #   done()
-
-  # it 'can be used to delete headers',(done)->
-  #   original = [{"docTitle":[],"docAuthors":[],"docDate":[]},[{"Header":[1,[{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"A"},{"Str":"."}]},{"Header":[2,[{"Str":"Sub"},{"Str":"-"},{"Str":"Heading"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"heading"},{"Str":"."}]},{"Header":[3,[{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"A"}]},{"Header":[3,[{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"B"}]},{"Header":[1,[{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"B"},{"Str":"."}]}]]
-  #   original_str = JSON.stringify(original)
-  #   filtered = [{"docTitle":[],"docAuthors":[],"docDate":[]},[{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"A"},{"Str":"."}]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"heading"},{"Str":"."}]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"A"}]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"B"}]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"B"},{"Str":"."}]}]]
-  #   expected = JSON.stringify(filtered)
-  #   filter = new PandocFilter (key,value)->
-  #     if value?.Header?
-  #       return null
-  #     else
-  #       return value
-  #   result = filter.for_each(original)
-  #   found = JSON.stringify(result)
-  #   found.should.equal(expected)
-  #   done()
-
-  # it 'performs an identity transformation by default',(done)->
-  #   lorem_file = [{"docTitle":[{"Str":"Sample"},"Space",{"Str":"Pandoc"},"Space",{"Str":"Markdown"},"Space",{"Str":"File"}],"docAuthors":[[{"Str":"Rod"},"Space",{"Str":"Waldhoff"}]],"docDate":[{"Str":"October"},"Space",{"Str":"2013"}]},[{"Header":[1,[{"Str":"Sample"},"Space",{"Str":"Markdown"},"Space",{"Str":"File"}]]},{"Para":[{"Str":"This"},"Space",{"Str":"is"},"Space",{"Str":"a"},"Space",{"Str":"simple"},"Space",{"Str":"markdown"},"Space",{"Str":"file"},{"Str":"."}]},{"Para":[{"Str":"Lorem"},"Space",{"Str":"ipsum"},"Space",{"Str":"dolor"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},{"Str":","},"Space",{"Str":"consectetuer"},"Space",{"Str":"adipiscing"},"Space",{"Str":"elit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"hendrerit"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"pretium"},"Space",{"Str":"posuere"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"quam"},"Space",{"Str":"nisl"},{"Str":","},"Space",{"Str":"tincidunt"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"mattis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"convallis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Cum"},"Space",{"Str":"sociis"},"Space",{"Str":"natoque"},"Space",{"Str":"penatibus"},"Space",{"Str":"et"},"Space",{"Str":"magnis"},"Space",{"Str":"dis"},"Space",{"Str":"parturient"},"Space",{"Str":"montes"},{"Str":","},"Space",{"Str":"nascetur"},"Space",{"Str":"ridiculus"},"Space",{"Str":"mus"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"vitae"},"Space",{"Str":"dolor"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tristique"},"Space",{"Str":"diam"},"Space",{"Str":"non"},"Space",{"Str":"turpis"},{"Str":"."},"Space",{"Str":"Cras"},"Space",{"Str":"placerat"},"Space",{"Str":"accumsan"},"Space",{"Str":"nulla"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"rutrum"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"vestibulum"},"Space",{"Str":"accumsan"},"Space",{"Str":"nisl"},{"Str":"."}]},{"Para":[{"Str":"Pellentesque"},"Space",{"Str":"dapibus"},"Space",{"Str":"suscipit"},"Space",{"Str":"ligula"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"posuere"},"Space",{"Str":"augue"},"Space",{"Str":"in"},"Space",{"Str":"quam"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"tortor"},"Space",{"Str":"sodales"},"Space",{"Str":"tellus"},"Space",{"Str":"ultricies"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Suspendisse"},"Space",{"Str":"potenti"},{"Str":"."},"Space",{"Str":"Aenean"},"Space",{"Str":"in"},"Space",{"Str":"sem"},"Space",{"Str":"ac"},"Space",{"Str":"leo"},"Space",{"Str":"mollis"},"Space",{"Str":"blandit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"neque"},"Space",{"Str":"quam"},{"Str":","},"Space",{"Str":"dignissim"},"Space",{"Str":"in"},{"Str":","},"Space",{"Str":"mollis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"sagittis"},"Space",{"Str":"eu"},{"Str":","},"Space",{"Str":"wisi"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"laoreet"},"Space",{"Str":"quam"},"Space",{"Str":"sed"},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"at"},"Space",{"Str":"dui"},"Space",{"Str":"in"},"Space",{"Str":"ligula"},"Space",{"Str":"mollis"},"Space",{"Str":"ultricies"},{"Str":"."},"Space",{"Str":"Integer"},"Space",{"Str":"placerat"},"Space",{"Str":"tristique"},"Space",{"Str":"nisl"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"augue"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Vestibulum"},"Space",{"Str":"convallis"},{"Str":","},"Space",{"Str":"lorem"},"Space",{"Str":"a"},"Space",{"Str":"tempus"},"Space",{"Str":"semper"},{"Str":","},"Space",{"Str":"dui"},"Space",{"Str":"dui"},"Space",{"Str":"euismod"},"Space",{"Str":"elit"},{"Str":","},"Space",{"Str":"vitae"},"Space",{"Str":"placerat"},"Space",{"Str":"urna"},"Space",{"Str":"tortor"},"Space",{"Str":"vitae"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"libero"},"Space",{"Str":"mauris"},{"Str":","},"Space",{"Str":"consequat"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"varius"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"dictum"},"Space",{"Str":"id"},{"Str":","},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"mollis"},"Space",{"Str":"tincidunt"},"Space",{"Str":"felis"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"feugiat"},"Space",{"Str":"tellus"},"Space",{"Str":"ut"},"Space",{"Str":"neque"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"risus"},"Space",{"Str":"a"},"Space",{"Str":"rhoncus"},"Space",{"Str":"fermentum"},{"Str":","},"Space",{"Str":"tellus"},"Space",{"Str":"tellus"},"Space",{"Str":"lacinia"},"Space",{"Str":"purus"},{"Str":","},"Space",{"Str":"et"},"Space",{"Str":"dictum"},"Space",{"Str":"nunc"},"Space",{"Str":"justo"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"elit"},{"Str":"."}]},{"Para":[{"Str":"Nullam"},"Space",{"Str":"eu"},"Space",{"Str":"ante"},"Space",{"Str":"vel"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"dignissim"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"suscipit"},{"Str":","},"Space",{"Str":"wisi"},"Space",{"Str":"nec"},"Space",{"Str":"facilisis"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"est"},"Space",{"Str":"dui"},"Space",{"Str":"fermentum"},"Space",{"Str":"leo"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"tempor"},"Space",{"Str":"ligula"},"Space",{"Str":"erat"},"Space",{"Str":"quis"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"porta"},"Space",{"Str":"vulputate"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"rutrum"},"Space",{"Str":"turpis"},"Space",{"Str":"sed"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"aliquet"},{"Str":","},"Space",{"Str":"augue"},"Space",{"Str":"nec"},"Space",{"Str":"adipiscing"},"Space",{"Str":"interdum"},{"Str":","},"Space",{"Str":"lacus"},"Space",{"Str":"tellus"},"Space",{"Str":"malesuada"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"varius"},"Space",{"Str":"mi"},"Space",{"Str":"purus"},"Space",{"Str":"non"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"condimentum"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"ut"},"Space",{"Str":"suscipit"},"Space",{"Str":"hendrerit"},{"Str":","},"Space",{"Str":"ipsum"},"Space",{"Str":"augue"},"Space",{"Str":"ornare"},"Space",{"Str":"nulla"},{"Str":","},"Space",{"Str":"non"},"Space",{"Str":"luctus"},"Space",{"Str":"diam"},"Space",{"Str":"neque"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"urna"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"vulputate"},"Space",{"Str":"vestibulum"},"Space",{"Str":"lorem"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"sagittis"},{"Str":","},"Space",{"Str":"libero"},"Space",{"Str":"non"},"Space",{"Str":"molestie"},"Space",{"Str":"mollis"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"orci"},"Space",{"Str":"ultrices"},"Space",{"Str":"dolor"},{"Str":","},"Space",{"Str":"at"},"Space",{"Str":"vulputate"},"Space",{"Str":"neque"},"Space",{"Str":"nulla"},"Space",{"Str":"lacinia"},"Space",{"Str":"eros"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"id"},"Space",{"Str":"ligula"},"Space",{"Str":"quis"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"tempor"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"lacinia"},"Space",{"Str":"pulvinar"},"Space",{"Str":"nibh"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"a"},"Space",{"Str":"sapien"},{"Str":"."}]},{"Para":[{"Str":"Aliquam"},"Space",{"Str":"erat"},"Space",{"Str":"volutpat"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"eleifend"},"Space",{"Str":"leo"},"Space",{"Str":"vitae"},"Space",{"Str":"magna"},{"Str":"."},"Space",{"Str":"In"},"Space",{"Str":"id"},"Space",{"Str":"erat"},"Space",{"Str":"non"},"Space",{"Str":"orci"},"Space",{"Str":"commodo"},"Space",{"Str":"lobortis"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"neque"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"cursus"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"gravida"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"lobortis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"diam"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"fermentum"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tempus"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"ac"},"Space",{"Str":"felis"},"Space",{"Str":"vel"},"Space",{"Str":"velit"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"at"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"neque"},"Space",{"Str":"nec"},"Space",{"Str":"dui"},"Space",{"Str":"dignissim"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Vivamus"},"Space",{"Str":"id"},"Space",{"Str":"enim"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"neque"},"Space",{"Str":"orci"},{"Str":","},"Space",{"Str":"porta"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"aliquet"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"semper"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"massa"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},"Space",{"Str":"tortor"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"euismod"},"Space",{"Str":"tellus"},"Space",{"Str":"id"},"Space",{"Str":"erat"},{"Str":"."}]}]]
-  #   expected = JSON.stringify(lorem_file)
-  #   filter = new PandocFilter()
-  #   result = filter.for_each(lorem_file)
-  #   found = JSON.stringify(result)
-  #   found.should.equal(expected)
-  #   done()
-
-  # it 'can be used to transform strings',(done)->
-  #   original = [{"docTitle":[{"Str":"SAMPLE"},"Space",{"Str":"PANDOC"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"FILE"}],"docAuthors":[[{"Str":"ROD"},"Space",{"Str":"WALDHOFF"}]],"docDate":[{"Str":"OCTOBER"},"Space",{"Str":"2013"}]},[{"Header":[1,[{"Str":"SAMPLE"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"FILE"}]]},{"Para":[{"Str":"THIS"},"Space",{"Str":"IS"},"Space",{"Str":"A"},"Space",{"Str":"SIMPLE"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"file"},{"Str":"."}]},{"Para":[{"Str":"Lorem"},"Space",{"Str":"ipsum"},"Space",{"Str":"dolor"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},{"Str":","},"Space",{"Str":"consectetuer"},"Space",{"Str":"adipiscing"},"Space",{"Str":"elit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"hendrerit"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"pretium"},"Space",{"Str":"posuere"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"quam"},"Space",{"Str":"nisl"},{"Str":","},"Space",{"Str":"tincidunt"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"mattis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"convallis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Cum"},"Space",{"Str":"sociis"},"Space",{"Str":"natoque"},"Space",{"Str":"penatibus"},"Space",{"Str":"et"},"Space",{"Str":"magnis"},"Space",{"Str":"dis"},"Space",{"Str":"parturient"},"Space",{"Str":"montes"},{"Str":","},"Space",{"Str":"nascetur"},"Space",{"Str":"ridiculus"},"Space",{"Str":"mus"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"vitae"},"Space",{"Str":"dolor"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tristique"},"Space",{"Str":"diam"},"Space",{"Str":"non"},"Space",{"Str":"turpis"},{"Str":"."},"Space",{"Str":"Cras"},"Space",{"Str":"placerat"},"Space",{"Str":"accumsan"},"Space",{"Str":"nulla"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"rutrum"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"vestibulum"},"Space",{"Str":"accumsan"},"Space",{"Str":"nisl"},{"Str":"."}]},{"Para":[{"Str":"Pellentesque"},"Space",{"Str":"dapibus"},"Space",{"Str":"suscipit"},"Space",{"Str":"ligula"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"posuere"},"Space",{"Str":"augue"},"Space",{"Str":"in"},"Space",{"Str":"quam"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"tortor"},"Space",{"Str":"sodales"},"Space",{"Str":"tellus"},"Space",{"Str":"ultricies"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Suspendisse"},"Space",{"Str":"potenti"},{"Str":"."},"Space",{"Str":"Aenean"},"Space",{"Str":"in"},"Space",{"Str":"sem"},"Space",{"Str":"ac"},"Space",{"Str":"leo"},"Space",{"Str":"mollis"},"Space",{"Str":"blandit"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"neque"},"Space",{"Str":"quam"},{"Str":","},"Space",{"Str":"dignissim"},"Space",{"Str":"in"},{"Str":","},"Space",{"Str":"mollis"},"Space",{"Str":"nec"},{"Str":","},"Space",{"Str":"sagittis"},"Space",{"Str":"eu"},{"Str":","},"Space",{"Str":"wisi"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"laoreet"},"Space",{"Str":"quam"},"Space",{"Str":"sed"},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"at"},"Space",{"Str":"dui"},"Space",{"Str":"in"},"Space",{"Str":"ligula"},"Space",{"Str":"mollis"},"Space",{"Str":"ultricies"},{"Str":"."},"Space",{"Str":"Integer"},"Space",{"Str":"placerat"},"Space",{"Str":"tristique"},"Space",{"Str":"nisl"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"augue"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"commodo"},{"Str":"."},"Space",{"Str":"Vestibulum"},"Space",{"Str":"convallis"},{"Str":","},"Space",{"Str":"lorem"},"Space",{"Str":"a"},"Space",{"Str":"tempus"},"Space",{"Str":"semper"},{"Str":","},"Space",{"Str":"dui"},"Space",{"Str":"dui"},"Space",{"Str":"euismod"},"Space",{"Str":"elit"},{"Str":","},"Space",{"Str":"vitae"},"Space",{"Str":"placerat"},"Space",{"Str":"urna"},"Space",{"Str":"tortor"},"Space",{"Str":"vitae"},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"libero"},"Space",{"Str":"mauris"},{"Str":","},"Space",{"Str":"consequat"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"varius"},"Space",{"Str":"et"},{"Str":","},"Space",{"Str":"dictum"},"Space",{"Str":"id"},{"Str":","},"Space",{"Str":"arcu"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"mollis"},"Space",{"Str":"tincidunt"},"Space",{"Str":"felis"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"feugiat"},"Space",{"Str":"tellus"},"Space",{"Str":"ut"},"Space",{"Str":"neque"},{"Str":"."},"Space",{"Str":"Nulla"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"risus"},"Space",{"Str":"a"},"Space",{"Str":"rhoncus"},"Space",{"Str":"fermentum"},{"Str":","},"Space",{"Str":"tellus"},"Space",{"Str":"tellus"},"Space",{"Str":"lacinia"},"Space",{"Str":"purus"},{"Str":","},"Space",{"Str":"et"},"Space",{"Str":"dictum"},"Space",{"Str":"nunc"},"Space",{"Str":"justo"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"elit"},{"Str":"."}]},{"Para":[{"Str":"Nullam"},"Space",{"Str":"eu"},"Space",{"Str":"ante"},"Space",{"Str":"vel"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"dignissim"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"suscipit"},{"Str":","},"Space",{"Str":"wisi"},"Space",{"Str":"nec"},"Space",{"Str":"facilisis"},"Space",{"Str":"facilisis"},{"Str":","},"Space",{"Str":"est"},"Space",{"Str":"dui"},"Space",{"Str":"fermentum"},"Space",{"Str":"leo"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"tempor"},"Space",{"Str":"ligula"},"Space",{"Str":"erat"},"Space",{"Str":"quis"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"porta"},"Space",{"Str":"vulputate"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"rutrum"},"Space",{"Str":"turpis"},"Space",{"Str":"sed"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Aliquam"},"Space",{"Str":"posuere"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"aliquet"},{"Str":","},"Space",{"Str":"augue"},"Space",{"Str":"nec"},"Space",{"Str":"adipiscing"},"Space",{"Str":"interdum"},{"Str":","},"Space",{"Str":"lacus"},"Space",{"Str":"tellus"},"Space",{"Str":"malesuada"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"quis"},"Space",{"Str":"varius"},"Space",{"Str":"mi"},"Space",{"Str":"purus"},"Space",{"Str":"non"},"Space",{"Str":"odio"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"condimentum"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"ut"},"Space",{"Str":"suscipit"},"Space",{"Str":"hendrerit"},{"Str":","},"Space",{"Str":"ipsum"},"Space",{"Str":"augue"},"Space",{"Str":"ornare"},"Space",{"Str":"nulla"},{"Str":","},"Space",{"Str":"non"},"Space",{"Str":"luctus"},"Space",{"Str":"diam"},"Space",{"Str":"neque"},"Space",{"Str":"sit"},"Space",{"Str":"amet"},"Space",{"Str":"urna"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"vulputate"},"Space",{"Str":"vestibulum"},"Space",{"Str":"lorem"},{"Str":"."},"Space",{"Str":"Fusce"},"Space",{"Str":"sagittis"},{"Str":","},"Space",{"Str":"libero"},"Space",{"Str":"non"},"Space",{"Str":"molestie"},"Space",{"Str":"mollis"},{"Str":","},"Space",{"Str":"magna"},"Space",{"Str":"orci"},"Space",{"Str":"ultrices"},"Space",{"Str":"dolor"},{"Str":","},"Space",{"Str":"at"},"Space",{"Str":"vulputate"},"Space",{"Str":"neque"},"Space",{"Str":"nulla"},"Space",{"Str":"lacinia"},"Space",{"Str":"eros"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"id"},"Space",{"Str":"ligula"},"Space",{"Str":"quis"},"Space",{"Str":"est"},"Space",{"Str":"convallis"},"Space",{"Str":"tempor"},{"Str":"."},"Space",{"Str":"Curabitur"},"Space",{"Str":"lacinia"},"Space",{"Str":"pulvinar"},"Space",{"Str":"nibh"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"a"},"Space",{"Str":"sapien"},{"Str":"."}]},{"Para":[{"Str":"Aliquam"},"Space",{"Str":"erat"},"Space",{"Str":"volutpat"},{"Str":"."},"Space",{"Str":"Nunc"},"Space",{"Str":"eleifend"},"Space",{"Str":"leo"},"Space",{"Str":"vitae"},"Space",{"Str":"magna"},{"Str":"."},"Space",{"Str":"In"},"Space",{"Str":"id"},"Space",{"Str":"erat"},"Space",{"Str":"non"},"Space",{"Str":"orci"},"Space",{"Str":"commodo"},"Space",{"Str":"lobortis"},{"Str":"."},"Space",{"Str":"Proin"},"Space",{"Str":"neque"},"Space",{"Str":"massa"},{"Str":","},"Space",{"Str":"cursus"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"gravida"},"Space",{"Str":"ut"},{"Str":","},"Space",{"Str":"lobortis"},"Space",{"Str":"eget"},{"Str":","},"Space",{"Str":"lacus"},{"Str":"."},"Space",{"Str":"Sed"},"Space",{"Str":"diam"},{"Str":"."},"Space",{"Str":"Praesent"},"Space",{"Str":"fermentum"},"Space",{"Str":"tempor"},"Space",{"Str":"tellus"},{"Str":"."},"Space",{"Str":"Nullam"},"Space",{"Str":"tempus"},{"Str":"."},"Space",{"Str":"Mauris"},"Space",{"Str":"ac"},"Space",{"Str":"felis"},"Space",{"Str":"vel"},"Space",{"Str":"velit"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},{"Str":"."},"Space",{"Str":"Donec"},"Space",{"Str":"at"},"Space",{"Str":"pede"},{"Str":"."},"Space",{"Str":"Etiam"},"Space",{"Str":"vel"},"Space",{"Str":"neque"},"Space",{"Str":"nec"},"Space",{"Str":"dui"},"Space",{"Str":"dignissim"},"Space",{"Str":"bibendum"},{"Str":"."},"Space",{"Str":"Vivamus"},"Space",{"Str":"id"},"Space",{"Str":"enim"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"neque"},"Space",{"Str":"orci"},{"Str":","},"Space",{"Str":"porta"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"aliquet"},"Space",{"Str":"quis"},{"Str":","},"Space",{"Str":"semper"},"Space",{"Str":"a"},{"Str":","},"Space",{"Str":"massa"},{"Str":"."},"Space",{"Str":"Phasellus"},"Space",{"Str":"purus"},{"Str":"."},"Space",{"Str":"Pellentesque"},"Space",{"Str":"tristique"},"Space",{"Str":"imperdiet"},"Space",{"Str":"tortor"},{"Str":"."},"Space",{"Str":"Nam"},"Space",{"Str":"euismod"},"Space",{"Str":"tellus"},"Space",{"Str":"id"},"Space",{"Str":"erat"},{"Str":"."}]}]]
-  #   upcased = [{"docTitle":[{"Str":"SAMPLE"},"Space",{"Str":"PANDOC"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"FILE"}],"docAuthors":[[{"Str":"ROD"},"Space",{"Str":"WALDHOFF"}]],"docDate":[{"Str":"OCTOBER"},"Space",{"Str":"2013"}]},[{"Header":[1,[{"Str":"SAMPLE"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"FILE"}]]},{"Para":[{"Str":"THIS"},"Space",{"Str":"IS"},"Space",{"Str":"A"},"Space",{"Str":"SIMPLE"},"Space",{"Str":"MARKDOWN"},"Space",{"Str":"FILE"},{"Str":"."}]},{"Para":[{"Str":"LOREM"},"Space",{"Str":"IPSUM"},"Space",{"Str":"DOLOR"},"Space",{"Str":"SIT"},"Space",{"Str":"AMET"},{"Str":","},"Space",{"Str":"CONSECTETUER"},"Space",{"Str":"ADIPISCING"},"Space",{"Str":"ELIT"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"HENDRERIT"},"Space",{"Str":"TEMPOR"},"Space",{"Str":"TELLUS"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"PRETIUM"},"Space",{"Str":"POSUERE"},"Space",{"Str":"TELLUS"},{"Str":"."},"Space",{"Str":"PROIN"},"Space",{"Str":"QUAM"},"Space",{"Str":"NISL"},{"Str":","},"Space",{"Str":"TINCIDUNT"},"Space",{"Str":"ET"},{"Str":","},"Space",{"Str":"MATTIS"},"Space",{"Str":"EGET"},{"Str":","},"Space",{"Str":"CONVALLIS"},"Space",{"Str":"NEC"},{"Str":","},"Space",{"Str":"PURUS"},{"Str":"."},"Space",{"Str":"CUM"},"Space",{"Str":"SOCIIS"},"Space",{"Str":"NATOQUE"},"Space",{"Str":"PENATIBUS"},"Space",{"Str":"ET"},"Space",{"Str":"MAGNIS"},"Space",{"Str":"DIS"},"Space",{"Str":"PARTURIENT"},"Space",{"Str":"MONTES"},{"Str":","},"Space",{"Str":"NASCETUR"},"Space",{"Str":"RIDICULUS"},"Space",{"Str":"MUS"},{"Str":"."},"Space",{"Str":"NULLA"},"Space",{"Str":"POSUERE"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"VITAE"},"Space",{"Str":"DOLOR"},{"Str":"."},"Space",{"Str":"NULLAM"},"Space",{"Str":"TRISTIQUE"},"Space",{"Str":"DIAM"},"Space",{"Str":"NON"},"Space",{"Str":"TURPIS"},{"Str":"."},"Space",{"Str":"CRAS"},"Space",{"Str":"PLACERAT"},"Space",{"Str":"ACCUMSAN"},"Space",{"Str":"NULLA"},{"Str":"."},"Space",{"Str":"NULLAM"},"Space",{"Str":"RUTRUM"},{"Str":"."},"Space",{"Str":"NAM"},"Space",{"Str":"VESTIBULUM"},"Space",{"Str":"ACCUMSAN"},"Space",{"Str":"NISL"},{"Str":"."}]},{"Para":[{"Str":"PELLENTESQUE"},"Space",{"Str":"DAPIBUS"},"Space",{"Str":"SUSCIPIT"},"Space",{"Str":"LIGULA"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"POSUERE"},"Space",{"Str":"AUGUE"},"Space",{"Str":"IN"},"Space",{"Str":"QUAM"},{"Str":"."},"Space",{"Str":"ETIAM"},"Space",{"Str":"VEL"},"Space",{"Str":"TORTOR"},"Space",{"Str":"SODALES"},"Space",{"Str":"TELLUS"},"Space",{"Str":"ULTRICIES"},"Space",{"Str":"COMMODO"},{"Str":"."},"Space",{"Str":"SUSPENDISSE"},"Space",{"Str":"POTENTI"},{"Str":"."},"Space",{"Str":"AENEAN"},"Space",{"Str":"IN"},"Space",{"Str":"SEM"},"Space",{"Str":"AC"},"Space",{"Str":"LEO"},"Space",{"Str":"MOLLIS"},"Space",{"Str":"BLANDIT"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"NEQUE"},"Space",{"Str":"QUAM"},{"Str":","},"Space",{"Str":"DIGNISSIM"},"Space",{"Str":"IN"},{"Str":","},"Space",{"Str":"MOLLIS"},"Space",{"Str":"NEC"},{"Str":","},"Space",{"Str":"SAGITTIS"},"Space",{"Str":"EU"},{"Str":","},"Space",{"Str":"WISI"},{"Str":"."},"Space",{"Str":"PHASELLUS"},"Space",{"Str":"LACUS"},{"Str":"."},"Space",{"Str":"ETIAM"},"Space",{"Str":"LAOREET"},"Space",{"Str":"QUAM"},"Space",{"Str":"SED"},"Space",{"Str":"ARCU"},{"Str":"."},"Space",{"Str":"PHASELLUS"},"Space",{"Str":"AT"},"Space",{"Str":"DUI"},"Space",{"Str":"IN"},"Space",{"Str":"LIGULA"},"Space",{"Str":"MOLLIS"},"Space",{"Str":"ULTRICIES"},{"Str":"."},"Space",{"Str":"INTEGER"},"Space",{"Str":"PLACERAT"},"Space",{"Str":"TRISTIQUE"},"Space",{"Str":"NISL"},{"Str":"."},"Space",{"Str":"PRAESENT"},"Space",{"Str":"AUGUE"},{"Str":"."},"Space",{"Str":"FUSCE"},"Space",{"Str":"COMMODO"},{"Str":"."},"Space",{"Str":"VESTIBULUM"},"Space",{"Str":"CONVALLIS"},{"Str":","},"Space",{"Str":"LOREM"},"Space",{"Str":"A"},"Space",{"Str":"TEMPUS"},"Space",{"Str":"SEMPER"},{"Str":","},"Space",{"Str":"DUI"},"Space",{"Str":"DUI"},"Space",{"Str":"EUISMOD"},"Space",{"Str":"ELIT"},{"Str":","},"Space",{"Str":"VITAE"},"Space",{"Str":"PLACERAT"},"Space",{"Str":"URNA"},"Space",{"Str":"TORTOR"},"Space",{"Str":"VITAE"},"Space",{"Str":"LACUS"},{"Str":"."},"Space",{"Str":"NULLAM"},"Space",{"Str":"LIBERO"},"Space",{"Str":"MAURIS"},{"Str":","},"Space",{"Str":"CONSEQUAT"},"Space",{"Str":"QUIS"},{"Str":","},"Space",{"Str":"VARIUS"},"Space",{"Str":"ET"},{"Str":","},"Space",{"Str":"DICTUM"},"Space",{"Str":"ID"},{"Str":","},"Space",{"Str":"ARCU"},{"Str":"."},"Space",{"Str":"MAURIS"},"Space",{"Str":"MOLLIS"},"Space",{"Str":"TINCIDUNT"},"Space",{"Str":"FELIS"},{"Str":"."},"Space",{"Str":"ALIQUAM"},"Space",{"Str":"FEUGIAT"},"Space",{"Str":"TELLUS"},"Space",{"Str":"UT"},"Space",{"Str":"NEQUE"},{"Str":"."},"Space",{"Str":"NULLA"},"Space",{"Str":"FACILISIS"},{"Str":","},"Space",{"Str":"RISUS"},"Space",{"Str":"A"},"Space",{"Str":"RHONCUS"},"Space",{"Str":"FERMENTUM"},{"Str":","},"Space",{"Str":"TELLUS"},"Space",{"Str":"TELLUS"},"Space",{"Str":"LACINIA"},"Space",{"Str":"PURUS"},{"Str":","},"Space",{"Str":"ET"},"Space",{"Str":"DICTUM"},"Space",{"Str":"NUNC"},"Space",{"Str":"JUSTO"},"Space",{"Str":"SIT"},"Space",{"Str":"AMET"},"Space",{"Str":"ELIT"},{"Str":"."}]},{"Para":[{"Str":"NULLAM"},"Space",{"Str":"EU"},"Space",{"Str":"ANTE"},"Space",{"Str":"VEL"},"Space",{"Str":"EST"},"Space",{"Str":"CONVALLIS"},"Space",{"Str":"DIGNISSIM"},{"Str":"."},"Space",{"Str":"FUSCE"},"Space",{"Str":"SUSCIPIT"},{"Str":","},"Space",{"Str":"WISI"},"Space",{"Str":"NEC"},"Space",{"Str":"FACILISIS"},"Space",{"Str":"FACILISIS"},{"Str":","},"Space",{"Str":"EST"},"Space",{"Str":"DUI"},"Space",{"Str":"FERMENTUM"},"Space",{"Str":"LEO"},{"Str":","},"Space",{"Str":"QUIS"},"Space",{"Str":"TEMPOR"},"Space",{"Str":"LIGULA"},"Space",{"Str":"ERAT"},"Space",{"Str":"QUIS"},"Space",{"Str":"ODIO"},{"Str":"."},"Space",{"Str":"NUNC"},"Space",{"Str":"PORTA"},"Space",{"Str":"VULPUTATE"},"Space",{"Str":"TELLUS"},{"Str":"."},"Space",{"Str":"NUNC"},"Space",{"Str":"RUTRUM"},"Space",{"Str":"TURPIS"},"Space",{"Str":"SED"},"Space",{"Str":"PEDE"},{"Str":"."},"Space",{"Str":"SED"},"Space",{"Str":"BIBENDUM"},{"Str":"."},"Space",{"Str":"ALIQUAM"},"Space",{"Str":"POSUERE"},{"Str":"."},"Space",{"Str":"NUNC"},"Space",{"Str":"ALIQUET"},{"Str":","},"Space",{"Str":"AUGUE"},"Space",{"Str":"NEC"},"Space",{"Str":"ADIPISCING"},"Space",{"Str":"INTERDUM"},{"Str":","},"Space",{"Str":"LACUS"},"Space",{"Str":"TELLUS"},"Space",{"Str":"MALESUADA"},"Space",{"Str":"MASSA"},{"Str":","},"Space",{"Str":"QUIS"},"Space",{"Str":"VARIUS"},"Space",{"Str":"MI"},"Space",{"Str":"PURUS"},"Space",{"Str":"NON"},"Space",{"Str":"ODIO"},{"Str":"."},"Space",{"Str":"PELLENTESQUE"},"Space",{"Str":"CONDIMENTUM"},{"Str":","},"Space",{"Str":"MAGNA"},"Space",{"Str":"UT"},"Space",{"Str":"SUSCIPIT"},"Space",{"Str":"HENDRERIT"},{"Str":","},"Space",{"Str":"IPSUM"},"Space",{"Str":"AUGUE"},"Space",{"Str":"ORNARE"},"Space",{"Str":"NULLA"},{"Str":","},"Space",{"Str":"NON"},"Space",{"Str":"LUCTUS"},"Space",{"Str":"DIAM"},"Space",{"Str":"NEQUE"},"Space",{"Str":"SIT"},"Space",{"Str":"AMET"},"Space",{"Str":"URNA"},{"Str":"."},"Space",{"Str":"CURABITUR"},"Space",{"Str":"VULPUTATE"},"Space",{"Str":"VESTIBULUM"},"Space",{"Str":"LOREM"},{"Str":"."},"Space",{"Str":"FUSCE"},"Space",{"Str":"SAGITTIS"},{"Str":","},"Space",{"Str":"LIBERO"},"Space",{"Str":"NON"},"Space",{"Str":"MOLESTIE"},"Space",{"Str":"MOLLIS"},{"Str":","},"Space",{"Str":"MAGNA"},"Space",{"Str":"ORCI"},"Space",{"Str":"ULTRICES"},"Space",{"Str":"DOLOR"},{"Str":","},"Space",{"Str":"AT"},"Space",{"Str":"VULPUTATE"},"Space",{"Str":"NEQUE"},"Space",{"Str":"NULLA"},"Space",{"Str":"LACINIA"},"Space",{"Str":"EROS"},{"Str":"."},"Space",{"Str":"SED"},"Space",{"Str":"ID"},"Space",{"Str":"LIGULA"},"Space",{"Str":"QUIS"},"Space",{"Str":"EST"},"Space",{"Str":"CONVALLIS"},"Space",{"Str":"TEMPOR"},{"Str":"."},"Space",{"Str":"CURABITUR"},"Space",{"Str":"LACINIA"},"Space",{"Str":"PULVINAR"},"Space",{"Str":"NIBH"},{"Str":"."},"Space",{"Str":"NAM"},"Space",{"Str":"A"},"Space",{"Str":"SAPIEN"},{"Str":"."}]},{"Para":[{"Str":"ALIQUAM"},"Space",{"Str":"ERAT"},"Space",{"Str":"VOLUTPAT"},{"Str":"."},"Space",{"Str":"NUNC"},"Space",{"Str":"ELEIFEND"},"Space",{"Str":"LEO"},"Space",{"Str":"VITAE"},"Space",{"Str":"MAGNA"},{"Str":"."},"Space",{"Str":"IN"},"Space",{"Str":"ID"},"Space",{"Str":"ERAT"},"Space",{"Str":"NON"},"Space",{"Str":"ORCI"},"Space",{"Str":"COMMODO"},"Space",{"Str":"LOBORTIS"},{"Str":"."},"Space",{"Str":"PROIN"},"Space",{"Str":"NEQUE"},"Space",{"Str":"MASSA"},{"Str":","},"Space",{"Str":"CURSUS"},"Space",{"Str":"UT"},{"Str":","},"Space",{"Str":"GRAVIDA"},"Space",{"Str":"UT"},{"Str":","},"Space",{"Str":"LOBORTIS"},"Space",{"Str":"EGET"},{"Str":","},"Space",{"Str":"LACUS"},{"Str":"."},"Space",{"Str":"SED"},"Space",{"Str":"DIAM"},{"Str":"."},"Space",{"Str":"PRAESENT"},"Space",{"Str":"FERMENTUM"},"Space",{"Str":"TEMPOR"},"Space",{"Str":"TELLUS"},{"Str":"."},"Space",{"Str":"NULLAM"},"Space",{"Str":"TEMPUS"},{"Str":"."},"Space",{"Str":"MAURIS"},"Space",{"Str":"AC"},"Space",{"Str":"FELIS"},"Space",{"Str":"VEL"},"Space",{"Str":"VELIT"},"Space",{"Str":"TRISTIQUE"},"Space",{"Str":"IMPERDIET"},{"Str":"."},"Space",{"Str":"DONEC"},"Space",{"Str":"AT"},"Space",{"Str":"PEDE"},{"Str":"."},"Space",{"Str":"ETIAM"},"Space",{"Str":"VEL"},"Space",{"Str":"NEQUE"},"Space",{"Str":"NEC"},"Space",{"Str":"DUI"},"Space",{"Str":"DIGNISSIM"},"Space",{"Str":"BIBENDUM"},{"Str":"."},"Space",{"Str":"VIVAMUS"},"Space",{"Str":"ID"},"Space",{"Str":"ENIM"},{"Str":"."},"Space",{"Str":"PHASELLUS"},"Space",{"Str":"NEQUE"},"Space",{"Str":"ORCI"},{"Str":","},"Space",{"Str":"PORTA"},"Space",{"Str":"A"},{"Str":","},"Space",{"Str":"ALIQUET"},"Space",{"Str":"QUIS"},{"Str":","},"Space",{"Str":"SEMPER"},"Space",{"Str":"A"},{"Str":","},"Space",{"Str":"MASSA"},{"Str":"."},"Space",{"Str":"PHASELLUS"},"Space",{"Str":"PURUS"},{"Str":"."},"Space",{"Str":"PELLENTESQUE"},"Space",{"Str":"TRISTIQUE"},"Space",{"Str":"IMPERDIET"},"Space",{"Str":"TORTOR"},{"Str":"."},"Space",{"Str":"NAM"},"Space",{"Str":"EUISMOD"},"Space",{"Str":"TELLUS"},"Space",{"Str":"ID"},"Space",{"Str":"ERAT"},{"Str":"."}]}]]
-  #   expected = JSON.stringify(upcased)
-  #   filter = new PandocFilter (key,value)->
-  #     if key is 'Str'
-  #       return value.toUpperCase()
-  #     else
-  #       return value
-  #   result = filter.for_each(original)
-  #   found = JSON.stringify(result)
-  #   found.should.equal(expected)
-  #   done()
-
-  # it 'can be used to number headers',(done)->
-  #   original = [{"docTitle":[],"docAuthors":[],"docDate":[]},[{"Header":[1,[{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"A"},{"Str":"."}]},{"Header":[2,[{"Str":"Sub"},{"Str":"-"},{"Str":"Heading"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"heading"},{"Str":"."}]},{"Header":[3,[{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"A"}]},{"Header":[3,[{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"B"}]},{"Header":[1,[{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"B"},{"Str":"."}]}]]
-  #   numbered = [{"docTitle":[],"docAuthors":[],"docDate":[]},[{"Header":[1,[{"Str":"[1]"},"Space",{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"A"},{"Str":"."}]},{"Header":[2,[{"Str":"[2]"},"Space",{"Str":"Sub"},{"Str":"-"},{"Str":"Heading"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"heading"},{"Str":"."}]},{"Header":[3,[{"Str":"[3]"},"Space",{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"A"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"A"}]},{"Header":[3,[{"Str":"[4]"},"Space",{"Str":"Sub"},{"Str":"-"},{"Str":"Sub"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"sub"},{"Str":"-"},{"Str":"sub"},{"Str":"-"},{"Str":"heading"},"Space",{"Str":"B"}]},{"Header":[1,[{"Str":"[5]"},"Space",{"Str":"Top"},"Space",{"Str":"Heading"},"Space",{"Str":"B"}]]},{"Para":[{"Str":"Text"},"Space",{"Str":"after"},"Space",{"Str":"top"},"Space",{"Str":"heading"},"Space",{"Str":"B"},{"Str":"."}]}]]
-  #   expected = JSON.stringify(numbered)
-  #   header_count = 0
-  #   filter = new PandocFilter (key,value)->
-  #     if key is 'Header'
-  #       value[1] = [ {Str:"[#{++header_count}]"}, "Space" ].concat(value[1])
-  #     return value
-  #   result = filter.for_each(original)
-  #   found = JSON.stringify(result)
-  #   found.should.equal(expected)
-  #   done()


adding in some tests for setting dates for builder

--- test/components/task-plan/builder.spec.coffee
+++ test/components/task-plan/builder.spec.coffee
@@ -1,4 +1,5 @@
 _ = require 'underscore'
+moment = require 'moment'

 Builder = require '../../../src/components/task-plan/builder'
 {TaskPlanActions, TaskPlanStore} = require '../../../src/flux/task-plan'
@@ -7,9 +8,14 @@

 {CourseListingActions, CourseListingStore} = require '../../../src/flux/course-listing'
 {CourseStore} = require '../../../src/flux/course'
+{TimeStore} = require '../../../src/flux/time'
+TutorDateFormat = TimeStore.getFormat()

 yesterday = (new Date(Date.now() - 1000 * 3600 * 24)).toString()
 tomorrow = (new Date(Date.now() + 1000 * 3600 * 24)).toString()
+dayAfter = (new Date(Date.now() + 1000 * 3600 * 48)).toString()
+
+getDateString = (value) -> moment(value).format(TutorDateFormat)

 COURSES = require '../../../api/user/courses.json'
 NEW_READING = ExtendBasePlan({id: "_CREATING_1", settings: {page_ids: []}})
@@ -65,3 +71,34 @@
       element.setAllPeriods()
       dueAt = TaskPlanStore.getDueAt(NEW_READING.id)
       expect(dueAt).to.be.falsy
+
+  it 'can update open date', ->
+    helper(NEW_READING).then ({dom, element}) ->
+      element.setOpensAt(dayAfter)
+      opensAt = TaskPlanStore.getOpensAt(NEW_READING.id)
+      expect(getDateString(opensAt)).to.be.equal(getDateString(dayAfter))
+
+  it 'can update due date', ->
+    helper(NEW_READING).then ({dom, element}) ->
+      element.setDueAt(dayAfter)
+      opensAt = TaskPlanStore.getDueAt(NEW_READING.id)
+      expect(getDateString(opensAt)).to.be.equal(getDateString(dayAfter))
+
+  it 'can update open date for individual period', ->
+    periodId = COURSES[0].periods[0].id
+    helper(NEW_READING).then ({dom, element}) ->
+      element.setOpensAt(dayAfter)
+      opensAt = TaskPlanStore.getOpensAt(NEW_READING.id)
+      expect(getDateString(opensAt)).to.be.falsy
+      opensAt = TaskPlanStore.getOpensAt(NEW_READING.id, periodId)
+      expect(getDateString(opensAt)).to.be.equal(getDateString(dayAfter))
+
+  it 'can update due date for individual period', ->
+    periodId = COURSES[0].periods[0].id
+    helper(NEW_READING).then ({dom, element}) ->
+      element.setDueAt(tomorrow)
+      dueAt = TaskPlanStore.getDueAt(NEW_READING.id)
+      expect(getDateString(dueAt)).to.be.falsy
+      dueAt = TaskPlanStore.getDueAt(NEW_READING.id, periodId)
+      expect(getDateString(dueAt)).to.be.equal(getDateString(tomorrow))
+


fix raw image download

fix raw image download

--- server/controllers/photo.coffee
+++ server/controllers/photo.coffee
@@ -219,7 +219,7 @@
     else if req.photo.binary?.raw then 'raw'
     else if req.photo.binary?.file then 'file'
     else 'file'
-    doPipe req, 'file', true, res, next
+    doPipe req, which, true, res, next

 module.exports.update = (req, res) ->
     req.photo.updateAttributes req.body, (err) ->


remove image with it doesn't exist

remove image with it doesn't exist

--- app/modules/profile/profile-timeline-attachment/profile-timeline-attachment.directive.coffee
+++ app/modules/profile/profile-timeline-attachment/profile-timeline-attachment.directive.coffee
@@ -18,6 +18,8 @@
         el.html(templateHtml)
         $compile(el.contents())(scope)

+        el.find("img").error () -> @.remove()
+
     return {
         link: link
         scope: {


Added end_with_newline setting

Added end_with_newline setting

--- lib/config.coffee
+++ lib/config.coffee
@@ -7,6 +7,9 @@
   indent_with_tabs:
     type: 'boolean'
     default: false
+  end_with_newline:
+    type: 'boolean'
+    default: true
   max_preserve_newlines:
     type: 'integer'
     default: 4


Show stack of dependencies for loose ends

--- lib/doctor.coffee
+++ lib/doctor.coffee
@@ -46,7 +46,9 @@
   # aren't part of cycles.
   report_loose_ends: ->
     return unless @loose_ends.length
-    console.log "Loose ends: #{@loose_ends.join(', ')}"
+    console.log "Loose ends:"
+    for node in @loose_ends
+      console.log "  #{node}: #{@_loose_ends[node].join ','}"

   # Reset the doctor's diagnosis for another run.
   clear: ->
@@ -68,12 +70,12 @@
       @scan next
     unless nexts.length
       unless @state[node] == 'done'
-        @add_loose_end node
+        @add_loose_end node, stack[0..-1]
     @stack.pop()

-  add_loose_end: (node) ->
+  add_loose_end: (node, stack) ->
     return if @_loose_ends[node]
-    @_loose_ends[node] = true
+    @_loose_ends[node] = stack
     @loose_ends.push node

   # Convert the input form of dependencies to a more straightforward version.


Sorted modules.

Sorted modules.

--- lib/engine.coffee
+++ lib/engine.coffee
@@ -1,9 +1,9 @@
-bootstrap = require './bootstrap'
 files = require './files'
+tasks = require './tasks'
 packages = require './packages'
 services = require './services'
 commands = require './commands'
-tasks = require './tasks'
+bootstrap = require './bootstrap'

 # ---


Update unsupported notification to use new Atom API

--- lib/format.coffee
+++ lib/format.coffee
@@ -2,6 +2,7 @@
  Package dependencies
 ###
 jsbeautify = (require 'js-beautify').js_beautify
+path = require 'path'

 packgeConfig = require './config'
 Observer = require './observer'
@@ -149,9 +150,7 @@
         # @editorCloseSubscriptions = new Observer()

   displayUnsupportedLanguageNotification: (language) ->
-    notification = new FileTypeNotSupportedView(language)
-    atom.views.getView(atom.workspace).append(notification)
-    destroyer = () ->
-      notification.detach()
-
-    setTimeout destroyer, 1500
+   title = editor.getTitle()
+    ext = path.extname title
+    message = ext.length > 0 ? ext : title
+    atom.notifications.addWarning("Formatting '#{message}' files is not yet supported.", { dismissable: true });


adds a shaOne custom binding

adds a shaOne custom binding

--- js/libs/custom-bindings.coffee
+++ js/libs/custom-bindings.coffee
@@ -111,6 +111,12 @@
     f = (value) -> "0#{value}"
     transformContent(f, el, valueAccessor())

+ko.bindingHandlers.shaOne =
+  update: (el, valueAccessor) =>
+    f = (value) -> value.slice(0,7)
+    transformContent(f, el, valueAccessor())
+    $(el).attr("title", valueAccessor())
+
 # Specify a haml template that depends on an observable
 # Example: %div{data-bind: "haml: {template: myObservable, args: {}}"}
 #   Renders the HAML.myObservable() template and will re-render when the


Change DateInput to be a controlled input

--- lib/inputs.coffee
+++ lib/inputs.coffee
@@ -107,35 +107,30 @@
   displayName: "DateInput"
   mixins: [Input]

-  getInitialState: ->
-    date = new Date()
-    return {
-      value: @props.value
-      currentYear: date.getFullYear()
-    }
+  componentDidMount: ->
+    @currentYear = (new Date()).getFullYear()
+
+  getDate: ->
+    new Date @props.value

   onMonthChange: (e) ->
     month = parseInt e.target.value
-    date = @state.value
+    date = @getDate()
     # Ensure that the day is valid with the selected month.
     # Correct the day if it is invalid.
-    year = @state.value.getFullYear()
+    year = date.getFullYear()
     date.setDate Math.min date.getDate(), daysInMonth month + 1, year
     date.setMonth month
-    @setDate date
+    @props.onChange date

   onDayChange: (e) ->
-    date = @state.value
-    date.setDate parseInt e.target.value
-    @setDate date
+    date = @getDate()
+    @props.value.setDate parseInt e.target.value
+    @props.onChange @props.value

   onYearChange: (e) ->
-    date = @state.value
+    date = @getDate()
     date.setFullYear parseInt e.target.value
-    @setDate date
-
-  setDate: (date) ->
-    @setState {value: date}
     @props.onChange date

   renderMonthSelector: ->
@@ -145,26 +140,26 @@

     return select
       className: "input-date-month"
-      value: @state.value.getMonth()
+      value: @props.value.getMonth()
       onChange: @onMonthChange
     , months

   renderDaySelector: ->
-    fullYear = @state.value.getFullYear()
-    days = [1..daysInMonth(@state.value.getMonth() + 1, fullYear)]
+    fullYear = @props.value.getFullYear()
+    days = [1..daysInMonth(@props.value.getMonth() + 1, fullYear)]
     dayOptions = _.map days, (day) -> option value: day, key: day, day
     return select
       className: "input-date-day"
-      value: @state.value.getDate()
+      value: @props.value.getDate()
       onChange: @onDayChange
     , dayOptions

   renderYearSelector: ->
-    years = _.map [@state.currentYear..1900], (year) ->
+    years = _.map [@currentYear..1900], (year) ->
       option value: year, key: year, year
     return select
       className: "input-date-year"
-      value: @state.value.getFullYear()
+      value: @props.value.getFullYear()
       onChange: @onYearChange
     , years


Check this.usernames for existence

Check this.usernames for existence

--- packages/rocketchat-statistics/server/functions/get.coffee
+++ packages/rocketchat-statistics/server/functions/get.coffee
@@ -27,15 +27,15 @@

 	m = ->
 		emit 1,
-			sum: this.usernames.length or 0
-			min: this.usernames.length or 0
-			max: this.usernames.length or 0
+			sum: this.usernames?.length or 0
+			min: this.usernames?.length or 0
+			max: this.usernames?.length or 0
 			count: 1

 		emit this.t,
-			sum: this.usernames.length or 0
-			min: this.usernames.length or 0
-			max: this.usernames.length or 0
+			sum: this.usernames?.length or 0
+			min: this.usernames?.length or 0
+			max: this.usernames?.length or 0
 			count: 1

 	r = (k, v) ->


Try using writeSync and closeSync

Try using writeSync and closeSync

--- lib/legacy.coffee
+++ lib/legacy.coffee
@@ -54,14 +54,13 @@
         temp.open(tmpOptions, (err, info) ->
           return reject(err) if err

-          fs.write(info.fd, textEditor.getText())
-          fs.close(info.fd, (err) ->
-            return reject(err) if err
-            linter.lintFile(info.path, (results) ->
-              fs.unlink(info.path)
+          fs.writeSync(info.fd, textEditor.getText())
+          fs.closeSync(info.fd)

-              resolve(transform(filePath, textEditor, results))
-            )
+          linter.lintFile(info.path, (results) ->
+            fs.unlink(info.path)
+
+            resolve(transform(filePath, textEditor, results))
           )
         )
       )