| var fs = require ('graceful-fs') | 
 | var dz = require ('dezalgo') | 
 | var once = require ('once') | 
 | var path = require ('path') | 
 | var debug = require ('debuglog') ('rds') | 
 |  | 
 | module . exports = readdir | 
 | readdir.sync = readdirSync | 
 |  | 
 | function readdir (dir, cb) { | 
 |   fs . readdir (dir, function (er, kids) { | 
 |     if (er) | 
 |       return cb (er) | 
 |  | 
 |     debug ('dir=%j, kids=%j', dir, kids) | 
 |     readScopes (dir, kids, function (er, data) { | 
 |       if (er) | 
 |         return cb (er) | 
 |  | 
 |       // Sort for bonus consistency points | 
 |       data = data . sort (function (a, b) { | 
 |         return a > b ? 1 : -1 | 
 |       }) | 
 |  | 
 |       return cb (null, data) | 
 |     }) | 
 |   }) | 
 | } | 
 |  | 
 | function readdirSync (dir) { | 
 |   var kids = fs . readdirSync (dir) | 
 |   debug ('dir=%j, kids=%j', dir, kids) | 
 |   var data =  readScopesSync (dir, kids) | 
 |   // Sort for bonus consistency points | 
 |   data = data . sort (function (a, b) { | 
 |     return a > b ? 1 : -1 | 
 |   }) | 
 |  | 
 |   return data | 
 | } | 
 |  | 
 | // Turn [ 'a', '@scope' ] into | 
 | // ['a', '@scope/foo', '@scope/bar'] | 
 | function readScopes (root, kids, cb) { | 
 |   var scopes = kids . filter (function (kid) { | 
 |     return kid . charAt (0) === '@' | 
 |   }) | 
 |  | 
 |   kids = kids . filter (function (kid) { | 
 |     return kid . charAt (0) !== '@' | 
 |   }) | 
 |  | 
 |   debug ('scopes=%j', scopes) | 
 |  | 
 |   if (scopes . length === 0) | 
 |     dz (cb) (null, kids) // prevent maybe-sync zalgo release | 
 |  | 
 |   cb = once (cb) | 
 |   var l = scopes . length | 
 |   scopes . forEach (function (scope) { | 
 |     var scopedir = path . resolve (root, scope) | 
 |     debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) | 
 |     fs . readdir (scopedir, then . bind (null, scope)) | 
 |   }) | 
 |  | 
 |   function then (scope, er, scopekids) { | 
 |     if (er) | 
 |       return cb (er) | 
 |  | 
 |     // XXX: Not sure how old this node bug is. Maybe superstition? | 
 |     scopekids = scopekids . filter (function (scopekid) { | 
 |       return !(scopekid === '.' || scopekid === '..' || !scopekid) | 
 |     }) | 
 |  | 
 |     kids . push . apply (kids, scopekids . map (function (scopekid) { | 
 |       return scope + '/' + scopekid | 
 |     })) | 
 |  | 
 |     debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) | 
 |  | 
 |     if (--l === 0) | 
 |       cb (null, kids) | 
 |   } | 
 | } | 
 |  | 
 | function readScopesSync (root, kids) { | 
 |   var scopes = kids . filter (function (kid) { | 
 |     return kid . charAt (0) === '@' | 
 |   }) | 
 |  | 
 |   kids = kids . filter (function (kid) { | 
 |     return kid . charAt (0) !== '@' | 
 |   }) | 
 |  | 
 |   debug ('scopes=%j', scopes) | 
 |  | 
 |   if (scopes . length === 0) | 
 |     return kids | 
 |  | 
 |   var l = scopes . length | 
 |   scopes . forEach (function (scope) { | 
 |     var scopedir = path . resolve (root, scope) | 
 |     debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) | 
 |     then (scope, fs . readdirSync (scopedir)) | 
 |   }) | 
 |  | 
 |   function then (scope, scopekids) { | 
 |     // XXX: Not sure how old this node bug is. Maybe superstition? | 
 |     scopekids = scopekids . filter (function (scopekid) { | 
 |       return !(scopekid === '.' || scopekid === '..' || !scopekid) | 
 |     }) | 
 |  | 
 |     kids . push . apply (kids, scopekids . map (function (scopekid) { | 
 |       return scope + '/' + scopekid | 
 |     })) | 
 |  | 
 |     debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) | 
 |   } | 
 |  | 
 |   return kids | 
 | } |