diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee
index 201643e88e..bfcd55855d 100644
--- a/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee
+++ b/services/web/app/coffee/Features/Authentication/AuthenticationManager.coffee
@@ -1,8 +1,11 @@
+Settings = require "settings-sharelatex"
User = require("../../models/User").User
{db, ObjectId} = require("../../infrastructure/mongojs")
crypto = require 'crypto'
bcrypt = require 'bcrypt'
+BCRYPT_ROUNDS = Settings?.security?.bcryptRounds or 12
+
module.exports = AuthenticationManager =
authenticate: (query, password, callback = (error, user) ->) ->
# Using Mongoose for legacy reasons here. The returned User instance
@@ -15,7 +18,9 @@ module.exports = AuthenticationManager =
bcrypt.compare password, user.hashedPassword, (error, match) ->
return callback(error) if error?
if match
- callback null, user
+ AuthenticationManager.checkRounds user, user.hashedPassword, password, (err) ->
+ return callback(err) if err?
+ callback null, user
else
callback null, null
else
@@ -24,7 +29,7 @@ module.exports = AuthenticationManager =
callback null, null
setUserPassword: (user_id, password, callback = (error) ->) ->
- bcrypt.genSalt 7, (error, salt) ->
+ bcrypt.genSalt BCRYPT_ROUNDS, (error, salt) ->
return callback(error) if error?
bcrypt.hash password, salt, (error, hash) ->
return callback(error) if error?
@@ -35,3 +40,10 @@ module.exports = AuthenticationManager =
$unset: password: true
}, callback)
+ checkRounds: (user, hashedPassword, password, callback = (error) ->) ->
+ # check current number of rounds and rehash if necessary
+ currentRounds = bcrypt.getRounds hashedPassword
+ if currentRounds < BCRYPT_ROUNDS
+ AuthenticationManager.setUserPassword user._id, password, callback
+ else
+ callback()
diff --git a/services/web/app/coffee/Features/Email/EmailBuilder.coffee b/services/web/app/coffee/Features/Email/EmailBuilder.coffee
index e14b9e4582..4bcf0c671d 100644
--- a/services/web/app/coffee/Features/Email/EmailBuilder.coffee
+++ b/services/web/app/coffee/Features/Email/EmailBuilder.coffee
@@ -3,6 +3,8 @@ PersonalEmailLayout = require("./Layouts/PersonalEmailLayout")
NotificationEmailLayout = require("./Layouts/NotificationEmailLayout")
settings = require("settings-sharelatex")
+
+
templates = {}
templates.registered =
@@ -114,6 +116,8 @@ module.exports =
template = templates[templateName]
opts.siteUrl = settings.siteUrl
opts.body = template.compiledTemplate(opts)
+ if settings.email?.templates?.customFooter?
+ opts.body += settings.email?.templates?.customFooter
return {
subject : template.subject(opts)
html: template.layout(opts)
diff --git a/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee b/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee
index d3e2cb3cb9..a7cf6a4672 100644
--- a/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee
+++ b/services/web/app/coffee/Features/Notifications/NotificationsHandler.coffee
@@ -6,7 +6,7 @@ oneSecond = 1000
makeRequest = (opts, callback)->
if !settings.apis.notifications?.url?
- return callback()
+ return callback(null, statusCode:200)
else
request(opts, callback)
@@ -18,7 +18,7 @@ module.exports =
json: true
timeout: oneSecond
method: "GET"
- request opts, (err, res, unreadNotifications)->
+ makeRequest opts, (err, res, unreadNotifications)->
statusCode = if res? then res.statusCode else 500
if err? or statusCode != 200
e = new Error("something went wrong getting notifications, #{err}, #{statusCode}")
@@ -40,7 +40,7 @@ module.exports =
templateKey:templateKey
}
logger.log opts:opts, "creating notification for user"
- request opts, callback
+ makeRequest opts, callback
markAsReadWithKey: (user_id, key, callback)->
opts =
@@ -51,7 +51,7 @@ module.exports =
key:key
}
logger.log user_id:user_id, key:key, "sending mark notification as read with key to notifications api"
- request opts, callback
+ makeRequest opts, callback
markAsRead: (user_id, notification_id, callback)->
@@ -60,4 +60,4 @@ module.exports =
uri: "#{settings.apis.notifications?.url}/user/#{user_id}/notification/#{notification_id}"
timeout:oneSecond
logger.log user_id:user_id, notification_id:notification_id, "sending mark notification as read to notifications api"
- request opts, callback
+ makeRequest opts, callback
diff --git a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee b/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee
index 680905ca6c..059c5fb02c 100644
--- a/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee
+++ b/services/web/app/coffee/Features/Subscription/RecurlyWrapper.coffee
@@ -4,11 +4,201 @@ request = require 'request'
Settings = require "settings-sharelatex"
xml2js = require "xml2js"
logger = require("logger-sharelatex")
+Async = require('async')
module.exports = RecurlyWrapper =
apiUrl : "https://api.recurly.com/v2"
- createSubscription: (user, subscriptionDetails, recurly_token_id, callback)->
+ _addressToXml: (address) ->
+ allowedKeys = ['address1', 'address2', 'city', 'country', 'state', 'zip', 'postal_code']
+ resultString = "\n"
+ for k, v of address
+ if k == 'postal_code'
+ k = 'zip'
+ if v and (k in allowedKeys)
+ resultString += "<#{k}#{if k == 'address2' then ' nil="nil"' else ''}>#{v || ''}#{k}>\n"
+ resultString += "\n"
+ return resultString
+
+ _paypal:
+ checkAccountExists: (cache, next) ->
+ user = cache.user
+ recurly_token_id = cache.recurly_token_id
+ subscriptionDetails = cache.subscriptionDetails
+ logger.log {user_id: user._id, recurly_token_id}, "checking if recurly account exists for user"
+ RecurlyWrapper.apiRequest({
+ url: "accounts/#{user._id}"
+ method: "GET"
+ }, (error, response, responseBody) ->
+ if error
+ if response.statusCode == 404 # actually not an error in this case, just no existing account
+ cache.userExists = false
+ return next(null, cache)
+ logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while checking account"
+ return next(error)
+ logger.log {user_id: user._id, recurly_token_id}, "user appears to exist in recurly"
+ RecurlyWrapper._parseAccountXml responseBody, (err, account) ->
+ if err
+ logger.error {err, user_id: user._id, recurly_token_id}, "error parsing account"
+ return next(err)
+ cache.userExists = true
+ cache.account = account
+ return next(null, cache)
+ )
+ createAccount: (cache, next) ->
+ user = cache.user
+ recurly_token_id = cache.recurly_token_id
+ subscriptionDetails = cache.subscriptionDetails
+ address = subscriptionDetails.address
+ if !address
+ return next(new Error('no address in subscriptionDetails at createAccount stage'))
+ if cache.userExists
+ logger.log {user_id: user._id, recurly_token_id}, "user already exists in recurly"
+ return next(null, cache)
+ logger.log {user_id: user._id, recurly_token_id}, "creating user in recurly"
+ requestBody = """
+
+ #{user._id}
+ #{user.email}
+ #{user.first_name}
+ #{user.last_name}
+
+ #{address.address1}
+ #{address.address2}
+ #{address.city || ''}
+ #{address.state || ''}
+ #{address.zip || ''}
+ #{address.country}
+
+
+ """
+ RecurlyWrapper.apiRequest({
+ url : "accounts"
+ method : "POST"
+ body : requestBody
+ }, (error, response, responseBody) =>
+ if error
+ logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating account"
+ return next(error)
+ RecurlyWrapper._parseAccountXml responseBody, (err, account) ->
+ if err
+ logger.error {err, user_id: user._id, recurly_token_id}, "error creating account"
+ return next(err)
+ cache.account = account
+ return next(null, cache)
+ )
+ createBillingInfo: (cache, next) ->
+ user = cache.user
+ recurly_token_id = cache.recurly_token_id
+ subscriptionDetails = cache.subscriptionDetails
+ logger.log {user_id: user._id, recurly_token_id}, "creating billing info in recurly"
+ accountCode = cache?.account?.account_code
+ if !accountCode
+ return next(new Error('no account code at createBillingInfo stage'))
+ requestBody = """
+
+ #{recurly_token_id}
+
+ """
+ RecurlyWrapper.apiRequest({
+ url: "accounts/#{accountCode}/billing_info"
+ method: "POST"
+ body: requestBody
+ }, (error, response, responseBody) =>
+ if error
+ logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating billing info"
+ return next(error)
+ RecurlyWrapper._parseBillingInfoXml responseBody, (err, billingInfo) ->
+ if err
+ logger.error {err, user_id: user._id, accountCode, recurly_token_id}, "error creating billing info"
+ return next(err)
+ cache.billingInfo = billingInfo
+ return next(null, cache)
+ )
+
+ setAddress: (cache, next) ->
+ user = cache.user
+ recurly_token_id = cache.recurly_token_id
+ subscriptionDetails = cache.subscriptionDetails
+ logger.log {user_id: user._id, recurly_token_id}, "setting billing address in recurly"
+ accountCode = cache?.account?.account_code
+ if !accountCode
+ return next(new Error('no account code at setAddress stage'))
+ address = subscriptionDetails.address
+ if !address
+ return next(new Error('no address in subscriptionDetails at setAddress stage'))
+ requestBody = RecurlyWrapper._addressToXml(address)
+ RecurlyWrapper.apiRequest({
+ url: "accounts/#{accountCode}/billing_info"
+ method: "PUT"
+ body: requestBody
+ }, (error, response, responseBody) =>
+ if error
+ logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while setting address"
+ return next(error)
+ RecurlyWrapper._parseBillingInfoXml responseBody, (err, billingInfo) ->
+ if err
+ logger.error {err, user_id: user._id, recurly_token_id}, "error updating billing info"
+ return next(err)
+ cache.billingInfo = billingInfo
+ return next(null, cache)
+ )
+ createSubscription: (cache, next) ->
+ user = cache.user
+ recurly_token_id = cache.recurly_token_id
+ subscriptionDetails = cache.subscriptionDetails
+ logger.log {user_id: user._id, recurly_token_id}, "creating subscription in recurly"
+ requestBody = """
+
+ #{subscriptionDetails.plan_code}
+ #{subscriptionDetails.currencyCode}
+ #{subscriptionDetails.coupon_code}
+
+ #{user._id}
+
+
+ """ # TODO: check account details and billing
+ RecurlyWrapper.apiRequest({
+ url : "subscriptions"
+ method : "POST"
+ body : requestBody
+ }, (error, response, responseBody) =>
+ if error
+ logger.error {error, user_id: user._id, recurly_token_id}, "error response from recurly while creating subscription"
+ return next(error)
+ RecurlyWrapper._parseSubscriptionXml responseBody, (err, subscription) ->
+ if err
+ logger.error {err, user_id: user._id, recurly_token_id}, "error creating subscription"
+ return next(err)
+ cache.subscription = subscription
+ return next(null, cache)
+ )
+
+ _createPaypalSubscription: (user, subscriptionDetails, recurly_token_id, callback) ->
+ logger.log {user_id: user._id, recurly_token_id}, "starting process of creating paypal subscription"
+ # We use `async.waterfall` to run each of these actions in sequence
+ # passing a `cache` object along the way. The cache is initialized
+ # with required data, and `async.apply` to pass the cache to the first function
+ cache = {user, recurly_token_id, subscriptionDetails}
+ Async.waterfall([
+ Async.apply(RecurlyWrapper._paypal.checkAccountExists, cache),
+ RecurlyWrapper._paypal.createAccount,
+ RecurlyWrapper._paypal.createBillingInfo,
+ RecurlyWrapper._paypal.setAddress,
+ RecurlyWrapper._paypal.createSubscription,
+ ], (err, result) ->
+ if err
+ logger.error {err, user_id: user._id, recurly_token_id}, "error in paypal subscription creation process"
+ return callback(err)
+ if !result.subscription
+ err = new Error('no subscription object in result')
+ logger.error {err, user_id: user._id, recurly_token_id}, "error in paypal subscription creation process"
+ return callback(err)
+ logger.log {user_id: user._id, recurly_token_id}, "done creating paypal subscription for user"
+ callback(null, result.subscription)
+ )
+
+ _createCreditCardSubscription: (user, subscriptionDetails, recurly_token_id, callback) ->
requestBody = """
#{subscriptionDetails.plan_code}
@@ -25,17 +215,23 @@ module.exports = RecurlyWrapper =
"""
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url : "subscriptions"
method : "POST"
body : requestBody
}, (error, response, responseBody) =>
return callback(error) if error?
- @_parseSubscriptionXml responseBody, callback
- )
+ RecurlyWrapper._parseSubscriptionXml responseBody, callback
+ )
+
+ createSubscription: (user, subscriptionDetails, recurly_token_id, callback)->
+ isPaypal = subscriptionDetails.isPaypal
+ logger.log {user_id: user._id, isPaypal, recurly_token_id}, "setting up subscription in recurly"
+ fn = if isPaypal then RecurlyWrapper._createPaypalSubscription else RecurlyWrapper._createCreditCardSubscription
+ fn user, subscriptionDetails, recurly_token_id, callback
apiRequest : (options, callback) ->
- options.url = @apiUrl + "/" + options.url
+ options.url = RecurlyWrapper.apiUrl + "/" + options.url
options.headers =
"Authorization" : "Basic " + new Buffer(Settings.apis.recurly.apiKey).toString("base64")
"Accept" : "application/xml"
@@ -60,7 +256,7 @@ module.exports = RecurlyWrapper =
newAttributes[key] = value
else
newAttributes[newKey] = value
-
+
return newAttributes
crypto.randomBytes 32, (error, buffer) ->
@@ -74,14 +270,14 @@ module.exports = RecurlyWrapper =
signature = "#{signed}|#{unsignedQuery}"
callback null, signature
-
+
getSubscriptions: (accountId, callback)->
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "accounts/#{accountId}/subscriptions"
}, (error, response, body) =>
return callback(error) if error?
- @_parseXml body, callback
+ RecurlyWrapper._parseXml body, callback
)
@@ -94,11 +290,11 @@ module.exports = RecurlyWrapper =
else
url = "subscriptions/#{subscriptionId}"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: url
}, (error, response, body) =>
return callback(error) if error?
- @_parseSubscriptionXml body, (error, recurlySubscription) =>
+ RecurlyWrapper._parseSubscriptionXml body, (error, recurlySubscription) =>
return callback(error) if error?
if options.includeAccount
if recurlySubscription.account? and recurlySubscription.account.url?
@@ -106,7 +302,7 @@ module.exports = RecurlyWrapper =
else
return callback "I don't understand the response from Recurly"
- @getAccount accountId, (error, account) ->
+ RecurlyWrapper.getAccount accountId, (error, account) ->
return callback(error) if error?
recurlySubscription.account = account
callback null, recurlySubscription
@@ -124,9 +320,9 @@ module.exports = RecurlyWrapper =
per_page:200
if cursor?
opts.qs.cursor = cursor
- @apiRequest opts, (error, response, body) =>
+ RecurlyWrapper.apiRequest opts, (error, response, body) =>
return callback(error) if error?
- @_parseXml body, (err, data)->
+ RecurlyWrapper._parseXml body, (err, data)->
if err?
logger.err err:err, "could not get accoutns"
callback(err)
@@ -142,19 +338,19 @@ module.exports = RecurlyWrapper =
getAccount: (accountId, callback) ->
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "accounts/#{accountId}"
}, (error, response, body) =>
return callback(error) if error?
- @_parseAccountXml body, callback
+ RecurlyWrapper._parseAccountXml body, callback
)
getBillingInfo: (accountId, callback)->
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "accounts/#{accountId}/billing_info"
}, (error, response, body) =>
return callback(error) if error?
- @_parseXml body, callback
+ RecurlyWrapper._parseXml body, callback
)
@@ -166,13 +362,13 @@ module.exports = RecurlyWrapper =
#{options.timeframe}
"""
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url : "subscriptions/#{subscriptionId}"
method : "put"
body : requestBody
}, (error, response, responseBody) =>
return callback(error) if error?
- @_parseSubscriptionXml responseBody, callback
+ RecurlyWrapper._parseSubscriptionXml responseBody, callback
)
createFixedAmmountCoupon: (coupon_code, name, currencyCode, discount_in_cents, plan_code, callback)->
@@ -191,7 +387,7 @@ module.exports = RecurlyWrapper =
"""
logger.log coupon_code:coupon_code, requestBody:requestBody, "creating coupon"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url : "coupons"
method : "post"
body : requestBody
@@ -203,16 +399,16 @@ module.exports = RecurlyWrapper =
lookupCoupon: (coupon_code, callback)->
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "coupons/#{coupon_code}"
}, (error, response, body) =>
return callback(error) if error?
- @_parseXml body, callback
+ RecurlyWrapper._parseXml body, callback
)
cancelSubscription: (subscriptionId, callback) ->
logger.log subscriptionId:subscriptionId, "telling recurly to cancel subscription"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "subscriptions/#{subscriptionId}/cancel",
method: "put"
}, (error, response, body) ->
@@ -221,13 +417,13 @@ module.exports = RecurlyWrapper =
reactivateSubscription: (subscriptionId, callback) ->
logger.log subscriptionId:subscriptionId, "telling recurly to reactivating subscription"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url: "subscriptions/#{subscriptionId}/reactivate",
method: "put"
}, (error, response, body) ->
callback(error)
)
-
+
redeemCoupon: (account_code, coupon_code, callback)->
requestBody = """
@@ -237,7 +433,7 @@ module.exports = RecurlyWrapper =
"""
logger.log account_code:account_code, coupon_code:coupon_code, requestBody:requestBody, "redeeming coupon for user"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url : "coupons/#{coupon_code}/redeem"
method : "post"
body : requestBody
@@ -251,7 +447,7 @@ module.exports = RecurlyWrapper =
next_renewal_date = new Date()
next_renewal_date.setDate(next_renewal_date.getDate() + daysUntilExpire)
logger.log subscriptionId:subscriptionId, daysUntilExpire:daysUntilExpire, "Exending Free trial for user"
- @apiRequest({
+ RecurlyWrapper.apiRequest({
url : "/subscriptions/#{subscriptionId}/postpone?next_renewal_date=#{next_renewal_date}&bulk=false"
method : "put"
}, (error, response, responseBody) =>
@@ -261,7 +457,7 @@ module.exports = RecurlyWrapper =
)
_parseSubscriptionXml: (xml, callback) ->
- @_parseXml xml, (error, data) ->
+ RecurlyWrapper._parseXml xml, (error, data) ->
return callback(error) if error?
if data? and data.subscription?
recurlySubscription = data.subscription
@@ -270,7 +466,7 @@ module.exports = RecurlyWrapper =
callback null, recurlySubscription
_parseAccountXml: (xml, callback) ->
- @_parseXml xml, (error, data) ->
+ RecurlyWrapper._parseXml xml, (error, data) ->
return callback(error) if error?
if data? and data.account?
account = data.account
@@ -278,6 +474,15 @@ module.exports = RecurlyWrapper =
return callback "I don't understand the response from Recurly"
callback null, account
+ _parseBillingInfoXml: (xml, callback) ->
+ RecurlyWrapper._parseXml xml, (error, data) ->
+ return callback(error) if error?
+ if data? and data.billing_info?
+ billingInfo = data.billing_info
+ else
+ return callback "I don't understand the response from Recurly"
+ callback null, billingInfo
+
_parseXml: (xml, callback) ->
convertDataTypes = (data) ->
if data? and data["$"]?
@@ -299,7 +504,7 @@ module.exports = RecurlyWrapper =
else
array.push(convertDataTypes(value))
data = array
-
+
if data instanceof Array
data = (convertDataTypes(entry) for entry in data)
else if typeof data == "object"
@@ -315,6 +520,3 @@ module.exports = RecurlyWrapper =
return callback(error) if error?
result = convertDataTypes(data)
callback null, result
-
-
-
diff --git a/services/web/app/coffee/Features/Wiki/WikiController.coffee b/services/web/app/coffee/Features/Wiki/WikiController.coffee
deleted file mode 100644
index e4f85a6c9f..0000000000
--- a/services/web/app/coffee/Features/Wiki/WikiController.coffee
+++ /dev/null
@@ -1,88 +0,0 @@
-request = require("request")
-settings = require("settings-sharelatex")
-logger = require("logger-sharelatex")
-ErrorController = require "../Errors/ErrorController"
-_ = require("underscore")
-AuthenticationController = require("../Authentication/AuthenticationController")
-async = require("async")
-other_lngs = ["es"]
-
-module.exports = WikiController =
-
-
- _checkIfLoginIsNeeded: (req, res, next)->
- if settings.apis.wiki.requireLogin
- AuthenticationController.requireLogin()(req, res, next)
- else
- next()
-
- getPage: (req, res, next) ->
- WikiController._checkIfLoginIsNeeded req, res, ->
-
- page = req.url.replace(/^\/learn/, "").replace(/^\//, "")
- if page == ""
- page = "Main_Page"
-
- logger.log page: page, "getting page from wiki"
- if _.include(other_lngs, req.lng)
- lngPage = "#{page}_#{req.lng}"
- else
- lngPage = page
- jobs =
- contents: (cb)->
- WikiController._getPageContent "Contents", cb
- pageData: (cb)->
- WikiController._getPageContent lngPage, cb
- async.parallel jobs, (error, results)->
- return next(error) if error?
- {pageData, contents} = results
- if pageData.content?.length > 280
- if _.include(other_lngs, req.lng)
- pageData.title = pageData.title.slice(0, pageData.title.length - (req.lng.length+1) )
-
- if pageData.title?.toLowerCase()?.indexOf("kb") == 0
- pageData.title = pageData.title.slice(3)
-
- if pageData.title?.toLowerCase()?.indexOf("errors") == 0
- pageData.title = pageData.title.slice(7)
-
- WikiController._renderPage(pageData, contents, res)
- else
- WikiController._getPageContent page, (error, pageData) ->
- return next(error) if error?
- WikiController._renderPage(pageData, contents, res)
-
-
-
-
- _getPageContent: (page, callback = (error, data = { content: "", title: "" }) ->) ->
- request {
- url: "#{settings.apis.wiki.url}/learn-scripts/api.php"
- qs: {
- page: decodeURI(page)
- action: "parse"
- format: "json"
- }
- }, (err, response, data)->
- return callback(err) if err?
- try
- data = JSON.parse(data)
- catch err
- logger.err err:err, data:data, "error parsing data from wiki"
- result =
- content: data?.parse?.text?['*']
- title: data?.parse?.title
- callback null, result
-
-
- _renderPage: (page, contents, res)->
- if page.title == "Main Page"
- title = "Documentation"
- else
- title = page.title
-
- res.render "wiki/page", {
- page: page
- contents: contents
- title: title
- }
\ No newline at end of file
diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee
index 7fc890ebd7..40792ed540 100644
--- a/services/web/app/coffee/router.coffee
+++ b/services/web/app/coffee/router.coffee
@@ -30,7 +30,6 @@ PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter")
ChatController = require("./Features/Chat/ChatController")
BlogController = require("./Features/Blog/BlogController")
-WikiController = require("./Features/Wiki/WikiController")
Modules = require "./infrastructure/Modules"
RateLimiterMiddlewear = require('./Features/Security/RateLimiterMiddlewear')
RealTimeProxyRouter = require('./Features/RealTimeProxy/RealTimeProxyRouter')
@@ -204,13 +203,6 @@ module.exports = class Router
webRouter.get "/project/:Project_id/messages", AuthorizationMiddlewear.ensureUserCanReadProject, ChatController.getMessages
webRouter.post "/project/:Project_id/messages", AuthorizationMiddlewear.ensureUserCanReadProject, ChatController.sendMessage
- webRouter.get /learn(\/.*)?/, RateLimiterMiddlewear.rateLimit({
- endpointName: "wiki"
- params: []
- maxRequests: 60
- timeInterval: 60
- }), WikiController.getPage
-
webRouter.post "/project/:Project_id/references/index", AuthorizationMiddlewear.ensureUserCanReadProject, ReferencesController.index
webRouter.post "/project/:Project_id/references/indexAll", AuthorizationMiddlewear.ensureUserCanReadProject, ReferencesController.indexAll
diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade
index e666724b09..bcb69597eb 100644
--- a/services/web/app/views/project/editor.jade
+++ b/services/web/app/views/project/editor.jade
@@ -97,6 +97,7 @@ block content
window.csrfToken = "!{csrfToken}";
window.anonymous = #{anonymous};
window.maxDocLength = #{maxDocLength};
+ window.wikiEnabled = #{!!(settings.apis.wiki && settings.apis.wiki.url)};
window.requirejs = {
"paths" : {
"mathjax": "/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML",
diff --git a/services/web/app/views/project/editor/pdf.jade b/services/web/app/views/project/editor/pdf.jade
index 75ff03020d..091831a22d 100644
--- a/services/web/app/views/project/editor/pdf.jade
+++ b/services/web/app/views/project/editor/pdf.jade
@@ -103,6 +103,8 @@ div.full-size.pdf(ng-controller="PdfController")
ng-init="feedbackSent = false;"
)
span.line-no
+ i.fa.fa-link(aria-hidden="true")
+ |
span(ng-show="entry.file") {{ entry.file }}
span(ng-show="entry.line") , line {{ entry.line }}
p.entry-message(ng-show="entry.message") {{ entry.message }}
@@ -112,9 +114,11 @@ div.full-size.pdf(ng-controller="PdfController")
)
figure.card-hint-icon-container
i.fa.fa-lightbulb-o(aria-hidden="true")
- p.card-hint-text(ng-show="entry.humanReadableHint", ng-bind-html="entry.humanReadableHint")
- .card-hint-actions
- .card-hint-ext-link
+ p.card-hint-text(
+ ng-show="entry.humanReadableHint",
+ ng-bind-html="wikiEnabled ? entry.humanReadableHint : stripHTMLFromString(entry.humanReadableHint)")
+ .card-hint-actions.clearfix
+ .card-hint-ext-link(ng-if="wikiEnabled")
a(ng-href="{{ entry.extraInfoURL }}", target="_blank")
i.fa.fa-external-link
| #{translate("log_hint_extra_info")}
diff --git a/services/web/app/views/wiki/page.jade b/services/web/app/views/wiki/page.jade
deleted file mode 100644
index 6a6bea2202..0000000000
--- a/services/web/app/views/wiki/page.jade
+++ /dev/null
@@ -1,68 +0,0 @@
-extends ../layout
-
-block content
- .content.content-alt(ng-cloak)
- .container.wiki
- .row.template-page-header
- .col-md-8(ng-cloak)
-
- .row
- .col-xs-3.contents(ng-non-bindable)
- | !{contents.content}
-
- .col-xs-9.page
- - if(typeof(settings.algolia) != "undefined" && typeof(settings.algolia.indexes) != "undefined" && typeof(settings.algolia.indexes.wiki) != "undefined")
- span(ng-controller="SearchWikiController")
- .row
- form.project-search.form-horizontal.col-md-9(role="form")
- .form-group.has-feedback.has-feedback-left.col-md-12
- input.form-control.col-md-12(type='text', ng-model='searchQueryText', ng-keyup='search()', placeholder="Search help library....")
- i.fa.fa-search.form-control-feedback-left
- i.fa.fa-times.form-control-feedback(
- ng-click="clearSearchText()",
- style="cursor: pointer;",
- ng-show="searchQueryText.length > 0"
- )
- .col-md-3.text-right
- a.btn.btn-primary(ng-click="showMissingTemplateModal()") #{translate("suggest_new_doc")}
-
- .row
- .col-md-12(ng-cloak)
- a(ng-href='{{hit.url}}',ng-repeat='hit in hits').search-result.card.card-thin
- span(ng-bind-html='hit.name')
- div.search-result-content(ng-show="hit.content != ''", ng-bind-html='hit.content')
-
- .card.row-spaced(ng-non-bindable)
- .page-header
- h1 #{title}
-
- | !{page.content}
-
-
-
-
- script(type="text/ng-template", id="missingWikiPageModal")
- .modal-header
- button.close(
- type="button"
- data-dismiss="modal"
- ng-click="close()"
- ) ×
- h3 #{translate("suggest_new_doc")}
- .modal-body.contact-us-modal
- span(ng-show="sent == false")
- label.desc
- | #{translate("email")} (#{translate("optional")})
- .form-group
- input.field.text.medium.span8.form-control(ng-model="form.email", ng-init="form.email = '#{getUserEmail()}'", type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
- label.desc
- | #{translate("suggestion")}
- .form-group
- textarea.field.text.medium.span8.form-control(ng-model="form.message",type='text', value='', maxlength='255', tabindex='4', onkeyup='')
- span(ng-show="sent")
- p #{translate("request_sent_thank_you")}
- .modal-footer
- button.btn.btn-default(ng-click="close()")
- span #{translate("dismiss")}
- button.btn-success.btn(type='submit', ng-disabled="sending", ng-click="contactUs()") #{translate("contact_us")}
-
diff --git a/services/web/config/settings.defaults.coffee b/services/web/config/settings.defaults.coffee
index b784088f4b..25b240c08d 100644
--- a/services/web/config/settings.defaults.coffee
+++ b/services/web/config/settings.defaults.coffee
@@ -137,6 +137,7 @@ module.exports = settings =
# --------
security:
sessionSecret: sessionSecret
+ bcryptRounds: 12 # number of rounds used to hash user passwords (raised to power 2)
httpAuthUsers: httpAuthUsers
diff --git a/services/web/npm-shrinkwrap.json b/services/web/npm-shrinkwrap.json
new file mode 100644
index 0000000000..f9d99d0cc8
--- /dev/null
+++ b/services/web/npm-shrinkwrap.json
@@ -0,0 +1,4602 @@
+{
+ "name": "web-sharelatex",
+ "version": "0.1.4",
+ "dependencies": {
+ "archiver": {
+ "version": "0.9.0",
+ "from": "archiver@0.9.0",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-0.9.0.tgz",
+ "dependencies": {
+ "buffer-crc32": {
+ "version": "0.2.5",
+ "from": "buffer-crc32@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.5.tgz"
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "from": "readable-stream@>=1.0.24 <1.1.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "tar-stream": {
+ "version": "0.3.3",
+ "from": "tar-stream@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-0.3.3.tgz",
+ "dependencies": {
+ "bl": {
+ "version": "0.6.0",
+ "from": "bl@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-0.6.0.tgz"
+ },
+ "end-of-stream": {
+ "version": "0.1.5",
+ "from": "end-of-stream@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
+ "dependencies": {
+ "once": {
+ "version": "1.3.3",
+ "from": "once@>=1.3.0 <1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "zip-stream": {
+ "version": "0.3.7",
+ "from": "zip-stream@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-0.3.7.tgz",
+ "dependencies": {
+ "crc32-stream": {
+ "version": "0.2.0",
+ "from": "crc32-stream@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-0.2.0.tgz"
+ },
+ "debug": {
+ "version": "1.0.4",
+ "from": "debug@>=1.0.2 <1.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.4.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2",
+ "from": "ms@0.6.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz"
+ }
+ }
+ },
+ "deflate-crc32-stream": {
+ "version": "0.1.2",
+ "from": "deflate-crc32-stream@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/deflate-crc32-stream/-/deflate-crc32-stream-0.1.2.tgz"
+ }
+ }
+ },
+ "lazystream": {
+ "version": "0.1.0",
+ "from": "lazystream@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-0.1.0.tgz"
+ },
+ "file-utils": {
+ "version": "0.1.5",
+ "from": "file-utils@>=0.1.5 <0.2.0",
+ "resolved": "https://registry.npmjs.org/file-utils/-/file-utils-0.1.5.tgz",
+ "dependencies": {
+ "lodash": {
+ "version": "2.1.0",
+ "from": "lodash@>=2.1.0 <2.2.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.1.0.tgz"
+ },
+ "iconv-lite": {
+ "version": "0.2.11",
+ "from": "iconv-lite@>=0.2.11 <0.3.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz"
+ },
+ "glob": {
+ "version": "3.2.11",
+ "from": "glob@>=3.2.6 <3.3.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "0.3.0",
+ "from": "minimatch@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "from": "minimatch@>=0.2.12 <0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ },
+ "findup-sync": {
+ "version": "0.1.3",
+ "from": "findup-sync@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
+ "dependencies": {
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.1 <2.5.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
+ }
+ }
+ },
+ "isbinaryfile": {
+ "version": "0.1.9",
+ "from": "isbinaryfile@>=0.1.9 <0.2.0",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-0.1.9.tgz"
+ }
+ }
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.0 <2.5.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
+ }
+ }
+ },
+ "async": {
+ "version": "0.6.2",
+ "from": "async@0.6.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.6.2.tgz"
+ },
+ "base64-stream": {
+ "version": "0.1.3",
+ "from": "base64-stream@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-0.1.3.tgz",
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.1.4",
+ "from": "readable-stream@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz",
+ "dependencies": {
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ },
+ "basic-auth-connect": {
+ "version": "1.0.0",
+ "from": "basic-auth-connect@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz"
+ },
+ "bcrypt": {
+ "version": "0.8.3",
+ "from": "bcrypt@0.8.3",
+ "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.8.3.tgz",
+ "dependencies": {
+ "bindings": {
+ "version": "1.2.1",
+ "from": "bindings@1.2.1",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
+ },
+ "nan": {
+ "version": "1.8.4",
+ "from": "nan@1.8.4",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
+ }
+ }
+ },
+ "body-parser": {
+ "version": "1.15.2",
+ "from": "body-parser@>=1.13.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.15.2.tgz",
+ "dependencies": {
+ "bytes": {
+ "version": "2.4.0",
+ "from": "bytes@2.4.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz"
+ },
+ "content-type": {
+ "version": "1.0.2",
+ "from": "content-type@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "depd": {
+ "version": "1.1.0",
+ "from": "depd@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
+ },
+ "http-errors": {
+ "version": "1.5.0",
+ "from": "http-errors@>=1.5.0 <1.6.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.0.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "setprototypeof": {
+ "version": "1.0.1",
+ "from": "setprototypeof@1.0.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.1.tgz"
+ },
+ "statuses": {
+ "version": "1.3.0",
+ "from": "statuses@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.0.tgz"
+ }
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.13",
+ "from": "iconv-lite@>=0.4.13 <0.5.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz"
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "from": "on-finished@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.1",
+ "from": "ee-first@1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
+ }
+ }
+ },
+ "qs": {
+ "version": "6.2.0",
+ "from": "qs@6.2.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz"
+ },
+ "raw-body": {
+ "version": "2.1.7",
+ "from": "raw-body@>=2.1.7 <2.2.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
+ "dependencies": {
+ "unpipe": {
+ "version": "1.0.0",
+ "from": "unpipe@1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
+ }
+ }
+ },
+ "type-is": {
+ "version": "1.6.13",
+ "from": "type-is@>=1.6.13 <1.7.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.13.tgz",
+ "dependencies": {
+ "media-typer": {
+ "version": "0.3.0",
+ "from": "media-typer@0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
+ },
+ "mime-types": {
+ "version": "2.1.11",
+ "from": "mime-types@>=2.1.11 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.23.0",
+ "from": "mime-db@>=1.23.0 <1.24.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "bufferedstream": {
+ "version": "1.6.0",
+ "from": "bufferedstream@1.6.0",
+ "resolved": "https://registry.npmjs.org/bufferedstream/-/bufferedstream-1.6.0.tgz"
+ },
+ "connect-redis": {
+ "version": "2.3.0",
+ "from": "connect-redis@2.3.0",
+ "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-2.3.0.tgz",
+ "dependencies": {
+ "debug": {
+ "version": "1.0.4",
+ "from": "debug@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.4.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2",
+ "from": "ms@0.6.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz"
+ }
+ }
+ },
+ "redis": {
+ "version": "0.12.1",
+ "from": "redis@>=0.12.1 <0.13.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-0.12.1.tgz"
+ }
+ }
+ },
+ "contentful": {
+ "version": "3.4.1",
+ "from": "contentful@>=3.3.14 <4.0.0",
+ "resolved": "https://registry.npmjs.org/contentful/-/contentful-3.4.1.tgz",
+ "dependencies": {
+ "babel-runtime": {
+ "version": "6.9.2",
+ "from": "babel-runtime@>=6.3.19 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.9.2.tgz",
+ "dependencies": {
+ "core-js": {
+ "version": "2.4.0",
+ "from": "core-js@>=2.4.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.0.tgz"
+ },
+ "regenerator-runtime": {
+ "version": "0.9.5",
+ "from": "regenerator-runtime@>=0.9.5 <0.10.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.5.tgz"
+ }
+ }
+ },
+ "contentful-sdk-core": {
+ "version": "2.3.0",
+ "from": "contentful-sdk-core@>=2.3.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/contentful-sdk-core/-/contentful-sdk-core-2.3.0.tgz",
+ "dependencies": {
+ "babel-plugin-rewire": {
+ "version": "1.0.0-rc-4",
+ "from": "babel-plugin-rewire@>=1.0.0-rc-3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-rewire/-/babel-plugin-rewire-1.0.0-rc-4.tgz"
+ },
+ "follow-redirects": {
+ "version": "0.0.7",
+ "from": "follow-redirects@0.0.7",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz",
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "stream-consume": {
+ "version": "0.1.0",
+ "from": "stream-consume@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz"
+ }
+ }
+ },
+ "qs": {
+ "version": "6.2.0",
+ "from": "qs@>=6.1.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz"
+ },
+ "babel-core": {
+ "version": "6.10.4",
+ "from": "babel-core@>=6.0.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.10.4.tgz",
+ "dependencies": {
+ "babel-code-frame": {
+ "version": "6.11.0",
+ "from": "babel-code-frame@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.11.0.tgz",
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "from": "chalk@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.2.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ }
+ }
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "from": "esutils@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"
+ },
+ "js-tokens": {
+ "version": "2.0.0",
+ "from": "js-tokens@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz"
+ }
+ }
+ },
+ "babel-generator": {
+ "version": "6.11.0",
+ "from": "babel-generator@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.11.0.tgz",
+ "dependencies": {
+ "detect-indent": {
+ "version": "3.0.1",
+ "from": "detect-indent@>=3.0.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz",
+ "dependencies": {
+ "get-stdin": {
+ "version": "4.0.1",
+ "from": "get-stdin@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
+ },
+ "repeating": {
+ "version": "1.1.3",
+ "from": "repeating@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz",
+ "dependencies": {
+ "is-finite": {
+ "version": "1.0.1",
+ "from": "is-finite@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz",
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "from": "number-is-nan@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "babel-helpers": {
+ "version": "6.8.0",
+ "from": "babel-helpers@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.8.0.tgz"
+ },
+ "babel-messages": {
+ "version": "6.8.0",
+ "from": "babel-messages@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz"
+ },
+ "babel-register": {
+ "version": "6.9.0",
+ "from": "babel-register@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.9.0.tgz",
+ "dependencies": {
+ "core-js": {
+ "version": "2.4.0",
+ "from": "core-js@>=2.4.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.0.tgz"
+ },
+ "home-or-tmp": {
+ "version": "1.0.0",
+ "from": "home-or-tmp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz",
+ "dependencies": {
+ "os-tmpdir": {
+ "version": "1.0.1",
+ "from": "os-tmpdir@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz"
+ },
+ "user-home": {
+ "version": "1.1.1",
+ "from": "user-home@>=1.1.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz"
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.1 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "source-map-support": {
+ "version": "0.2.10",
+ "from": "source-map-support@>=0.2.10 <0.3.0",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz",
+ "dependencies": {
+ "source-map": {
+ "version": "0.1.32",
+ "from": "source-map@0.1.32",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz",
+ "dependencies": {
+ "amdefine": {
+ "version": "1.0.0",
+ "from": "amdefine@>=0.0.4",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "babel-traverse": {
+ "version": "6.10.4",
+ "from": "babel-traverse@>=6.10.4 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.10.4.tgz",
+ "dependencies": {
+ "globals": {
+ "version": "8.18.0",
+ "from": "globals@>=8.3.0 <9.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz"
+ },
+ "invariant": {
+ "version": "2.2.1",
+ "from": "invariant@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz",
+ "dependencies": {
+ "loose-envify": {
+ "version": "1.2.0",
+ "from": "loose-envify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz",
+ "dependencies": {
+ "js-tokens": {
+ "version": "1.0.3",
+ "from": "js-tokens@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "babylon": {
+ "version": "6.8.2",
+ "from": "babylon@>=6.7.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.8.2.tgz"
+ },
+ "convert-source-map": {
+ "version": "1.2.0",
+ "from": "convert-source-map@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.2.0.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.1.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "json5": {
+ "version": "0.4.0",
+ "from": "json5@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "path-exists": {
+ "version": "1.0.0",
+ "from": "path-exists@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz"
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
+ },
+ "private": {
+ "version": "0.1.6",
+ "from": "private@>=0.1.6 <0.2.0",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz"
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "from": "shebang-regex@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"
+ },
+ "slash": {
+ "version": "1.0.0",
+ "from": "slash@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz"
+ },
+ "source-map": {
+ "version": "0.5.6",
+ "from": "source-map@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz"
+ }
+ }
+ },
+ "babel-template": {
+ "version": "6.9.0",
+ "from": "babel-template@>=6.2.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.9.0.tgz",
+ "dependencies": {
+ "babylon": {
+ "version": "6.8.2",
+ "from": "babylon@>=6.7.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.8.2.tgz"
+ },
+ "babel-traverse": {
+ "version": "6.10.4",
+ "from": "babel-traverse@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.10.4.tgz",
+ "dependencies": {
+ "babel-code-frame": {
+ "version": "6.11.0",
+ "from": "babel-code-frame@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.11.0.tgz",
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "from": "chalk@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.2.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ }
+ }
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "from": "esutils@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"
+ },
+ "js-tokens": {
+ "version": "2.0.0",
+ "from": "js-tokens@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz"
+ }
+ }
+ },
+ "babel-messages": {
+ "version": "6.8.0",
+ "from": "babel-messages@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "globals": {
+ "version": "8.18.0",
+ "from": "globals@>=8.3.0 <9.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz"
+ },
+ "invariant": {
+ "version": "2.2.1",
+ "from": "invariant@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz",
+ "dependencies": {
+ "loose-envify": {
+ "version": "1.2.0",
+ "from": "loose-envify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz",
+ "dependencies": {
+ "js-tokens": {
+ "version": "1.0.3",
+ "from": "js-tokens@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.11.1",
+ "from": "babel-types@>=6.2.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.11.1.tgz",
+ "dependencies": {
+ "babel-traverse": {
+ "version": "6.10.4",
+ "from": "babel-traverse@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.10.4.tgz",
+ "dependencies": {
+ "babel-code-frame": {
+ "version": "6.11.0",
+ "from": "babel-code-frame@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.11.0.tgz",
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "from": "chalk@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.2.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "2.0.0",
+ "from": "js-tokens@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz"
+ }
+ }
+ },
+ "babel-messages": {
+ "version": "6.8.0",
+ "from": "babel-messages@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz"
+ },
+ "babylon": {
+ "version": "6.8.2",
+ "from": "babylon@>=6.7.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.8.2.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "globals": {
+ "version": "8.18.0",
+ "from": "globals@>=8.3.0 <9.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz"
+ },
+ "invariant": {
+ "version": "2.2.1",
+ "from": "invariant@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz",
+ "dependencies": {
+ "loose-envify": {
+ "version": "1.2.0",
+ "from": "loose-envify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz",
+ "dependencies": {
+ "js-tokens": {
+ "version": "1.0.3",
+ "from": "js-tokens@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "from": "esutils@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"
+ },
+ "to-fast-properties": {
+ "version": "1.0.2",
+ "from": "to-fast-properties@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "from": "json-stringify-safe@>=5.0.1 <6.0.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
+ }
+ }
+ },
+ "cookie": {
+ "version": "0.2.4",
+ "from": "cookie@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.2.4.tgz"
+ },
+ "cookie-parser": {
+ "version": "1.3.5",
+ "from": "cookie-parser@1.3.5",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
+ "dependencies": {
+ "cookie": {
+ "version": "0.1.3",
+ "from": "cookie@0.1.3",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz"
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "from": "cookie-signature@1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
+ }
+ }
+ },
+ "csurf": {
+ "version": "1.9.0",
+ "from": "csurf@>=1.8.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.9.0.tgz",
+ "dependencies": {
+ "cookie": {
+ "version": "0.3.1",
+ "from": "cookie@0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "from": "cookie-signature@1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
+ },
+ "csrf": {
+ "version": "3.0.3",
+ "from": "csrf@>=3.0.3 <3.1.0",
+ "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.0.3.tgz",
+ "dependencies": {
+ "base64-url": {
+ "version": "1.2.2",
+ "from": "base64-url@1.2.2",
+ "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-1.2.2.tgz"
+ },
+ "rndm": {
+ "version": "1.2.0",
+ "from": "rndm@1.2.0",
+ "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz"
+ },
+ "tsscmp": {
+ "version": "1.0.5",
+ "from": "tsscmp@1.0.5",
+ "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz"
+ },
+ "uid-safe": {
+ "version": "2.1.1",
+ "from": "uid-safe@2.1.1",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.1.tgz",
+ "dependencies": {
+ "random-bytes": {
+ "version": "1.0.0",
+ "from": "random-bytes@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "http-errors": {
+ "version": "1.5.0",
+ "from": "http-errors@>=1.5.0 <1.6.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.0.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "setprototypeof": {
+ "version": "1.0.1",
+ "from": "setprototypeof@1.0.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.1.tgz"
+ },
+ "statuses": {
+ "version": "1.3.0",
+ "from": "statuses@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "dateformat": {
+ "version": "1.0.4-1.2.3",
+ "from": "dateformat@1.0.4-1.2.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.4-1.2.3.tgz"
+ },
+ "express": {
+ "version": "4.13.0",
+ "from": "express@4.13.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.13.0.tgz",
+ "dependencies": {
+ "accepts": {
+ "version": "1.2.13",
+ "from": "accepts@>=1.2.9 <1.3.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz",
+ "dependencies": {
+ "mime-types": {
+ "version": "2.1.11",
+ "from": "mime-types@>=2.1.6 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.23.0",
+ "from": "mime-db@>=1.23.0 <1.24.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.5.3",
+ "from": "negotiator@0.5.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz"
+ }
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.0",
+ "from": "array-flatten@1.1.0",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.0.tgz"
+ },
+ "content-disposition": {
+ "version": "0.5.0",
+ "from": "content-disposition@0.5.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz"
+ },
+ "content-type": {
+ "version": "1.0.2",
+ "from": "content-type@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz"
+ },
+ "cookie": {
+ "version": "0.1.3",
+ "from": "cookie@0.1.3",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz"
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "from": "cookie-signature@1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "depd": {
+ "version": "1.0.1",
+ "from": "depd@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz"
+ },
+ "escape-html": {
+ "version": "1.0.2",
+ "from": "escape-html@1.0.2",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz"
+ },
+ "etag": {
+ "version": "1.7.0",
+ "from": "etag@>=1.7.0 <1.8.0",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz"
+ },
+ "finalhandler": {
+ "version": "0.4.0",
+ "from": "finalhandler@0.4.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz",
+ "dependencies": {
+ "unpipe": {
+ "version": "1.0.0",
+ "from": "unpipe@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
+ }
+ }
+ },
+ "fresh": {
+ "version": "0.3.0",
+ "from": "fresh@0.3.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz"
+ },
+ "merge-descriptors": {
+ "version": "1.0.0",
+ "from": "merge-descriptors@1.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz"
+ },
+ "methods": {
+ "version": "1.1.2",
+ "from": "methods@>=1.1.1 <1.2.0",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "from": "on-finished@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.1",
+ "from": "ee-first@1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
+ }
+ }
+ },
+ "parseurl": {
+ "version": "1.3.1",
+ "from": "parseurl@>=1.3.0 <1.4.0",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz"
+ },
+ "path-to-regexp": {
+ "version": "0.1.6",
+ "from": "path-to-regexp@0.1.6",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.6.tgz"
+ },
+ "proxy-addr": {
+ "version": "1.0.10",
+ "from": "proxy-addr@>=1.0.8 <1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz",
+ "dependencies": {
+ "forwarded": {
+ "version": "0.1.0",
+ "from": "forwarded@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz"
+ },
+ "ipaddr.js": {
+ "version": "1.0.5",
+ "from": "ipaddr.js@1.0.5",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz"
+ }
+ }
+ },
+ "qs": {
+ "version": "2.4.2",
+ "from": "qs@2.4.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz"
+ },
+ "range-parser": {
+ "version": "1.0.3",
+ "from": "range-parser@>=1.0.2 <1.1.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz"
+ },
+ "send": {
+ "version": "0.13.0",
+ "from": "send@0.13.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.13.0.tgz",
+ "dependencies": {
+ "destroy": {
+ "version": "1.0.3",
+ "from": "destroy@1.0.3",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz"
+ },
+ "http-errors": {
+ "version": "1.3.1",
+ "from": "http-errors@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "mime": {
+ "version": "1.3.4",
+ "from": "mime@1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ },
+ "statuses": {
+ "version": "1.2.1",
+ "from": "statuses@>=1.2.1 <1.3.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz"
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.10.3",
+ "from": "serve-static@>=1.10.0 <1.11.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz",
+ "dependencies": {
+ "escape-html": {
+ "version": "1.0.3",
+ "from": "escape-html@>=1.0.3 <1.1.0",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
+ },
+ "send": {
+ "version": "0.13.2",
+ "from": "send@0.13.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz",
+ "dependencies": {
+ "depd": {
+ "version": "1.1.0",
+ "from": "depd@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "from": "destroy@>=1.0.4 <1.1.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz"
+ },
+ "http-errors": {
+ "version": "1.3.1",
+ "from": "http-errors@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "mime": {
+ "version": "1.3.4",
+ "from": "mime@1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ },
+ "statuses": {
+ "version": "1.2.1",
+ "from": "statuses@>=1.2.1 <1.3.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "type-is": {
+ "version": "1.6.13",
+ "from": "type-is@>=1.6.3 <1.7.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.13.tgz",
+ "dependencies": {
+ "media-typer": {
+ "version": "0.3.0",
+ "from": "media-typer@0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
+ },
+ "mime-types": {
+ "version": "2.1.11",
+ "from": "mime-types@>=2.1.11 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.23.0",
+ "from": "mime-db@>=1.23.0 <1.24.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "vary": {
+ "version": "1.0.1",
+ "from": "vary@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz"
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "from": "utils-merge@1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz"
+ }
+ }
+ },
+ "express-session": {
+ "version": "1.11.3",
+ "from": "express-session@1.11.3",
+ "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.11.3.tgz",
+ "dependencies": {
+ "cookie": {
+ "version": "0.1.3",
+ "from": "cookie@0.1.3",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz"
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "from": "cookie-signature@1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
+ },
+ "crc": {
+ "version": "3.3.0",
+ "from": "crc@3.3.0",
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.3.0.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "depd": {
+ "version": "1.0.1",
+ "from": "depd@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz"
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "from": "on-headers@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz"
+ },
+ "parseurl": {
+ "version": "1.3.1",
+ "from": "parseurl@>=1.3.0 <1.4.0",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz"
+ },
+ "uid-safe": {
+ "version": "2.0.0",
+ "from": "uid-safe@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.0.0.tgz",
+ "dependencies": {
+ "base64-url": {
+ "version": "1.2.1",
+ "from": "base64-url@1.2.1",
+ "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-1.2.1.tgz"
+ }
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "from": "utils-merge@1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz"
+ }
+ }
+ },
+ "grunt": {
+ "version": "0.4.5",
+ "from": "grunt@>=0.4.5 <0.5.0",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz",
+ "dependencies": {
+ "async": {
+ "version": "0.1.22",
+ "from": "async@>=0.1.22 <0.2.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz"
+ },
+ "coffee-script": {
+ "version": "1.3.3",
+ "from": "coffee-script@>=1.3.3 <1.4.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz"
+ },
+ "colors": {
+ "version": "0.6.2",
+ "from": "colors@>=0.6.2 <0.7.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz"
+ },
+ "dateformat": {
+ "version": "1.0.2-1.2.3",
+ "from": "dateformat@1.0.2-1.2.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz"
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "from": "eventemitter2@>=0.4.13 <0.5.0",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz"
+ },
+ "findup-sync": {
+ "version": "0.1.3",
+ "from": "findup-sync@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "3.2.11",
+ "from": "glob@>=3.2.9 <3.3.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "0.3.0",
+ "from": "minimatch@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.1 <2.5.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
+ }
+ }
+ },
+ "glob": {
+ "version": "3.1.21",
+ "from": "glob@>=3.1.21 <3.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
+ "dependencies": {
+ "graceful-fs": {
+ "version": "1.2.3",
+ "from": "graceful-fs@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz"
+ },
+ "inherits": {
+ "version": "1.0.2",
+ "from": "inherits@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz"
+ }
+ }
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "from": "hooker@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz"
+ },
+ "iconv-lite": {
+ "version": "0.2.11",
+ "from": "iconv-lite@>=0.2.11 <0.3.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz"
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "from": "minimatch@>=0.2.9 <0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ },
+ "nopt": {
+ "version": "1.0.10",
+ "from": "nopt@>=1.0.10 <1.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "from": "abbrev@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
+ }
+ }
+ },
+ "rimraf": {
+ "version": "2.2.8",
+ "from": "rimraf@>=2.2.8 <2.3.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
+ },
+ "lodash": {
+ "version": "0.9.2",
+ "from": "lodash@>=0.9.2 <0.10.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz"
+ },
+ "underscore.string": {
+ "version": "2.2.1",
+ "from": "underscore.string@>=2.2.1 <2.3.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz"
+ },
+ "which": {
+ "version": "1.0.9",
+ "from": "which@>=1.0.5 <1.1.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz"
+ },
+ "js-yaml": {
+ "version": "2.0.5",
+ "from": "js-yaml@>=2.0.5 <2.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz",
+ "dependencies": {
+ "argparse": {
+ "version": "0.1.16",
+ "from": "argparse@>=0.1.11 <0.2.0",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
+ "dependencies": {
+ "underscore": {
+ "version": "1.7.0",
+ "from": "underscore@>=1.7.0 <1.8.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz"
+ },
+ "underscore.string": {
+ "version": "2.4.0",
+ "from": "underscore.string@>=2.4.0 <2.5.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz"
+ }
+ }
+ },
+ "esprima": {
+ "version": "1.0.4",
+ "from": "esprima@>=1.0.2 <1.1.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz"
+ }
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "from": "exit@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "from": "getobject@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz"
+ },
+ "grunt-legacy-util": {
+ "version": "0.2.0",
+ "from": "grunt-legacy-util@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz"
+ },
+ "grunt-legacy-log": {
+ "version": "0.1.3",
+ "from": "grunt-legacy-log@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz",
+ "dependencies": {
+ "grunt-legacy-log-utils": {
+ "version": "0.1.1",
+ "from": "grunt-legacy-log-utils@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz"
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.1 <2.5.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
+ },
+ "underscore.string": {
+ "version": "2.3.3",
+ "from": "underscore.string@>=2.3.3 <2.4.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz"
+ }
+ }
+ }
+ }
+ },
+ "heapdump": {
+ "version": "0.3.7",
+ "from": "heapdump@>=0.3.7 <0.4.0",
+ "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.7.tgz"
+ },
+ "http-proxy": {
+ "version": "1.14.0",
+ "from": "http-proxy@>=1.8.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.14.0.tgz",
+ "dependencies": {
+ "eventemitter3": {
+ "version": "1.2.0",
+ "from": "eventemitter3@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz"
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "from": "requires-port@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
+ }
+ }
+ },
+ "jade": {
+ "version": "1.3.1",
+ "from": "jade@>=1.3.1 <1.4.0",
+ "resolved": "https://registry.npmjs.org/jade/-/jade-1.3.1.tgz",
+ "dependencies": {
+ "commander": {
+ "version": "2.1.0",
+ "from": "commander@2.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz"
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ },
+ "transformers": {
+ "version": "2.1.0",
+ "from": "transformers@2.1.0",
+ "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz",
+ "dependencies": {
+ "promise": {
+ "version": "2.0.0",
+ "from": "promise@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz",
+ "dependencies": {
+ "is-promise": {
+ "version": "1.0.1",
+ "from": "is-promise@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz"
+ }
+ }
+ },
+ "css": {
+ "version": "1.0.8",
+ "from": "css@>=1.0.8 <1.1.0",
+ "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz",
+ "dependencies": {
+ "css-parse": {
+ "version": "1.0.4",
+ "from": "css-parse@1.0.4",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz"
+ },
+ "css-stringify": {
+ "version": "1.0.5",
+ "from": "css-stringify@1.0.5",
+ "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz"
+ }
+ }
+ },
+ "uglify-js": {
+ "version": "2.2.5",
+ "from": "uglify-js@>=2.2.5 <2.3.0",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.2.5.tgz",
+ "dependencies": {
+ "source-map": {
+ "version": "0.1.43",
+ "from": "source-map@>=0.1.7 <0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "dependencies": {
+ "amdefine": {
+ "version": "1.0.0",
+ "from": "amdefine@>=0.0.4",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
+ }
+ }
+ },
+ "optimist": {
+ "version": "0.3.7",
+ "from": "optimist@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.3",
+ "from": "wordwrap@>=0.0.2 <0.1.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "character-parser": {
+ "version": "1.2.0",
+ "from": "character-parser@1.2.0",
+ "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.0.tgz"
+ },
+ "monocle": {
+ "version": "1.1.51",
+ "from": "monocle@1.1.51",
+ "resolved": "https://registry.npmjs.org/monocle/-/monocle-1.1.51.tgz",
+ "dependencies": {
+ "readdirp": {
+ "version": "0.2.5",
+ "from": "readdirp@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-0.2.5.tgz",
+ "dependencies": {
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=0.2.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "with": {
+ "version": "3.0.1",
+ "from": "with@>=3.0.0 <3.1.0",
+ "resolved": "https://registry.npmjs.org/with/-/with-3.0.1.tgz",
+ "dependencies": {
+ "uglify-js": {
+ "version": "2.4.24",
+ "from": "uglify-js@>=2.4.12 <2.5.0",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz",
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "from": "async@>=0.2.6 <0.3.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
+ },
+ "source-map": {
+ "version": "0.1.34",
+ "from": "source-map@0.1.34",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz",
+ "dependencies": {
+ "amdefine": {
+ "version": "1.0.0",
+ "from": "amdefine@>=0.0.4",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "from": "uglify-to-browserify@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
+ },
+ "yargs": {
+ "version": "3.5.4",
+ "from": "yargs@>=3.5.4 <3.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz",
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "from": "camelcase@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "from": "decamelize@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "from": "window-size@0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "from": "wordwrap@0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "constantinople": {
+ "version": "2.0.1",
+ "from": "constantinople@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-2.0.1.tgz",
+ "dependencies": {
+ "uglify-js": {
+ "version": "2.4.24",
+ "from": "uglify-js@>=2.4.12 <2.5.0",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz",
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "from": "async@>=0.2.6 <0.3.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
+ },
+ "source-map": {
+ "version": "0.1.34",
+ "from": "source-map@0.1.34",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz",
+ "dependencies": {
+ "amdefine": {
+ "version": "1.0.0",
+ "from": "amdefine@>=0.0.4",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "from": "uglify-to-browserify@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
+ },
+ "yargs": {
+ "version": "3.5.4",
+ "from": "yargs@>=3.5.4 <3.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz",
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "from": "camelcase@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "from": "decamelize@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "from": "window-size@0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "from": "wordwrap@0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "ldapjs": {
+ "version": "1.0.0",
+ "from": "ldapjs@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-1.0.0.tgz",
+ "dependencies": {
+ "asn1": {
+ "version": "0.2.3",
+ "from": "asn1@0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
+ },
+ "assert-plus": {
+ "version": "0.1.5",
+ "from": "assert-plus@0.1.5",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
+ },
+ "bunyan": {
+ "version": "1.5.1",
+ "from": "bunyan@1.5.1",
+ "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz",
+ "dependencies": {
+ "mv": {
+ "version": "2.1.1",
+ "from": "mv@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.1 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "ncp": {
+ "version": "2.0.0",
+ "from": "ncp@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz"
+ },
+ "rimraf": {
+ "version": "2.4.5",
+ "from": "rimraf@>=2.4.0 <2.5.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "6.0.4",
+ "from": "glob@>=6.0.1 <7.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "dependencies": {
+ "inflight": {
+ "version": "1.0.5",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "safe-json-stringify": {
+ "version": "1.0.3",
+ "from": "safe-json-stringify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.3.tgz"
+ }
+ }
+ },
+ "dashdash": {
+ "version": "1.10.1",
+ "from": "dashdash@1.10.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.10.1.tgz"
+ },
+ "backoff": {
+ "version": "2.4.1",
+ "from": "backoff@2.4.1",
+ "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.4.1.tgz",
+ "dependencies": {
+ "precond": {
+ "version": "0.2.3",
+ "from": "precond@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz"
+ }
+ }
+ },
+ "ldap-filter": {
+ "version": "0.2.2",
+ "from": "ldap-filter@0.2.2",
+ "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.2.2.tgz"
+ },
+ "once": {
+ "version": "1.3.2",
+ "from": "once@1.3.2",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "vasync": {
+ "version": "1.6.3",
+ "from": "vasync@1.6.3",
+ "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.6.3.tgz"
+ },
+ "verror": {
+ "version": "1.6.0",
+ "from": "verror@1.6.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.6.0.tgz",
+ "dependencies": {
+ "extsprintf": {
+ "version": "1.2.0",
+ "from": "extsprintf@1.2.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz"
+ }
+ }
+ },
+ "dtrace-provider": {
+ "version": "0.6.0",
+ "from": "dtrace-provider@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "2.3.5",
+ "from": "nan@>=2.0.8 <3.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.5.tgz"
+ }
+ }
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.13.1",
+ "from": "lodash@>=4.13.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz"
+ },
+ "logger-sharelatex": {
+ "version": "1.3.1",
+ "from": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.3.1",
+ "resolved": "git+https://github.com/sharelatex/logger-sharelatex.git#bf413ec621a000cf0e08c939de38d5e24541a08c",
+ "dependencies": {
+ "bunyan": {
+ "version": "1.5.1",
+ "from": "bunyan@1.5.1",
+ "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz",
+ "dependencies": {
+ "dtrace-provider": {
+ "version": "0.6.0",
+ "from": "dtrace-provider@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "2.3.5",
+ "from": "nan@>=2.0.8 <3.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.5.tgz"
+ }
+ }
+ },
+ "mv": {
+ "version": "2.1.1",
+ "from": "mv@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.1 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "ncp": {
+ "version": "2.0.0",
+ "from": "ncp@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz"
+ },
+ "rimraf": {
+ "version": "2.4.5",
+ "from": "rimraf@>=2.4.0 <2.5.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "6.0.4",
+ "from": "glob@>=6.0.1 <7.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "dependencies": {
+ "inflight": {
+ "version": "1.0.5",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "from": "once@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "safe-json-stringify": {
+ "version": "1.0.3",
+ "from": "safe-json-stringify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.3.tgz"
+ }
+ }
+ },
+ "coffee-script": {
+ "version": "1.4.0",
+ "from": "coffee-script@1.4.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.4.0.tgz"
+ },
+ "raven": {
+ "version": "0.8.1",
+ "from": "raven@>=0.8.0 <0.9.0",
+ "resolved": "https://registry.npmjs.org/raven/-/raven-0.8.1.tgz",
+ "dependencies": {
+ "cookie": {
+ "version": "0.1.0",
+ "from": "cookie@0.1.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz"
+ },
+ "lsmod": {
+ "version": "0.0.3",
+ "from": "lsmod@>=0.0.3 <0.1.0",
+ "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-0.0.3.tgz"
+ },
+ "stack-trace": {
+ "version": "0.0.7",
+ "from": "stack-trace@0.0.7",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.7.tgz"
+ }
+ }
+ }
+ }
+ },
+ "lynx": {
+ "version": "0.1.1",
+ "from": "lynx@0.1.1",
+ "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz",
+ "dependencies": {
+ "mersenne": {
+ "version": "0.0.3",
+ "from": "mersenne@>=0.0.3 <0.1.0",
+ "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.3.tgz"
+ },
+ "statsd-parser": {
+ "version": "0.0.4",
+ "from": "statsd-parser@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz"
+ }
+ }
+ },
+ "marked": {
+ "version": "0.3.5",
+ "from": "marked@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.5.tgz"
+ },
+ "method-override": {
+ "version": "2.3.6",
+ "from": "method-override@>=2.3.3 <3.0.0",
+ "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.6.tgz",
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "from": "methods@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
+ },
+ "parseurl": {
+ "version": "1.3.1",
+ "from": "parseurl@>=1.3.0 <1.4.0",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz"
+ },
+ "vary": {
+ "version": "1.1.0",
+ "from": "vary@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.0.tgz"
+ }
+ }
+ },
+ "metrics-sharelatex": {
+ "version": "1.3.0",
+ "from": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.3.0",
+ "resolved": "git+https://github.com/sharelatex/metrics-sharelatex.git#080c4aeb696edcd5d6d86f202f2c528f0661d7a6",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.6.0",
+ "from": "coffee-script@1.6.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz"
+ }
+ }
+ },
+ "mimelib": {
+ "version": "0.2.14",
+ "from": "mimelib@0.2.14",
+ "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.2.14.tgz",
+ "dependencies": {
+ "encoding": {
+ "version": "0.1.12",
+ "from": "encoding@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.13",
+ "from": "iconv-lite@>=0.4.13 <0.5.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz"
+ }
+ }
+ },
+ "addressparser": {
+ "version": "0.2.1",
+ "from": "addressparser@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.2.1.tgz"
+ }
+ }
+ },
+ "mocha": {
+ "version": "1.17.1",
+ "from": "mocha@1.17.1",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.17.1.tgz",
+ "dependencies": {
+ "commander": {
+ "version": "2.0.0",
+ "from": "commander@2.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz"
+ },
+ "growl": {
+ "version": "1.7.0",
+ "from": "growl@>=1.7.0 <1.8.0",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz"
+ },
+ "jade": {
+ "version": "0.26.3",
+ "from": "jade@0.26.3",
+ "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
+ "dependencies": {
+ "commander": {
+ "version": "0.6.1",
+ "from": "commander@0.6.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz"
+ },
+ "mkdirp": {
+ "version": "0.3.0",
+ "from": "mkdirp@0.3.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz"
+ }
+ }
+ },
+ "diff": {
+ "version": "1.0.7",
+ "from": "diff@1.0.7",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@*",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ },
+ "glob": {
+ "version": "3.2.3",
+ "from": "glob@3.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz",
+ "dependencies": {
+ "minimatch": {
+ "version": "0.2.14",
+ "from": "minimatch@>=0.2.11 <0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "2.0.3",
+ "from": "graceful-fs@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "mongojs": {
+ "version": "0.18.2",
+ "from": "mongojs@0.18.2",
+ "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-0.18.2.tgz",
+ "dependencies": {
+ "thunky": {
+ "version": "0.1.0",
+ "from": "thunky@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz"
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "from": "readable-stream@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "mongodb": {
+ "version": "1.4.32",
+ "from": "mongodb@1.4.32",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-1.4.32.tgz",
+ "dependencies": {
+ "bson": {
+ "version": "0.2.22",
+ "from": "bson@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-0.2.22.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "1.8.4",
+ "from": "nan@>=1.8.0 <1.9.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
+ }
+ }
+ },
+ "kerberos": {
+ "version": "0.0.9",
+ "from": "kerberos@0.0.9",
+ "resolved": "https://registry.npmjs.org/kerberos/-/kerberos-0.0.9.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "1.6.2",
+ "from": "nan@1.6.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.6.2.tgz"
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.1.4",
+ "from": "readable-stream@latest",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz",
+ "dependencies": {
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "mongoose": {
+ "version": "4.1.0",
+ "from": "mongoose@4.1.0",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.1.0.tgz",
+ "dependencies": {
+ "async": {
+ "version": "0.9.0",
+ "from": "async@0.9.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
+ },
+ "bson": {
+ "version": "0.3.2",
+ "from": "bson@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-0.3.2.tgz",
+ "dependencies": {
+ "bson-ext": {
+ "version": "0.1.13",
+ "from": "bson-ext@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/bson-ext/-/bson-ext-0.1.13.tgz",
+ "dependencies": {
+ "bindings": {
+ "version": "1.2.1",
+ "from": "bindings@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
+ },
+ "nan": {
+ "version": "2.0.9",
+ "from": "nan@>=2.0.9 <2.1.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.0.9.tgz"
+ }
+ }
+ }
+ }
+ },
+ "hooks-fixed": {
+ "version": "1.1.0",
+ "from": "hooks-fixed@1.1.0",
+ "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-1.1.0.tgz"
+ },
+ "kareem": {
+ "version": "1.0.1",
+ "from": "kareem@1.0.1",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.0.1.tgz"
+ },
+ "mongodb": {
+ "version": "2.0.34",
+ "from": "mongodb@2.0.34",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.0.34.tgz",
+ "dependencies": {
+ "mongodb-core": {
+ "version": "1.2.0",
+ "from": "mongodb-core@1.2.0",
+ "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-1.2.0.tgz",
+ "dependencies": {
+ "bson": {
+ "version": "0.4.23",
+ "from": "bson@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-0.4.23.tgz"
+ },
+ "kerberos": {
+ "version": "0.0.21",
+ "from": "kerberos@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/kerberos/-/kerberos-0.0.21.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "2.3.5",
+ "from": "nan@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.5.tgz"
+ }
+ }
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "1.0.31",
+ "from": "readable-stream@1.0.31",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "mpath": {
+ "version": "0.1.1",
+ "from": "mpath@0.1.1",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.1.1.tgz"
+ },
+ "mpromise": {
+ "version": "0.5.4",
+ "from": "mpromise@0.5.4",
+ "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.4.tgz"
+ },
+ "mquery": {
+ "version": "1.6.1",
+ "from": "mquery@1.6.1",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-1.6.1.tgz",
+ "dependencies": {
+ "bluebird": {
+ "version": "2.9.26",
+ "from": "bluebird@2.9.26",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.26.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "ms": {
+ "version": "0.1.0",
+ "from": "ms@0.1.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.1.0.tgz"
+ },
+ "muri": {
+ "version": "1.0.0",
+ "from": "muri@1.0.0",
+ "resolved": "https://registry.npmjs.org/muri/-/muri-1.0.0.tgz"
+ },
+ "regexp-clone": {
+ "version": "0.0.1",
+ "from": "regexp-clone@0.0.1",
+ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz"
+ },
+ "sliced": {
+ "version": "0.0.5",
+ "from": "sliced@0.0.5",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz"
+ }
+ }
+ },
+ "multer": {
+ "version": "0.1.8",
+ "from": "multer@>=0.1.8 <0.2.0",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-0.1.8.tgz",
+ "dependencies": {
+ "busboy": {
+ "version": "0.2.13",
+ "from": "busboy@>=0.2.9 <0.3.0",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.13.tgz",
+ "dependencies": {
+ "dicer": {
+ "version": "0.2.5",
+ "from": "dicer@0.2.5",
+ "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
+ "dependencies": {
+ "streamsearch": {
+ "version": "0.1.2",
+ "from": "streamsearch@0.1.2",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz"
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "from": "readable-stream@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ },
+ "qs": {
+ "version": "1.2.2",
+ "from": "qs@>=1.2.2 <1.3.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz"
+ },
+ "type-is": {
+ "version": "1.5.7",
+ "from": "type-is@>=1.5.2 <1.6.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz",
+ "dependencies": {
+ "media-typer": {
+ "version": "0.3.0",
+ "from": "media-typer@0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "from": "mime-types@>=2.0.9 <2.1.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0",
+ "from": "mime-db@>=1.12.0 <1.13.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "node-uuid": {
+ "version": "1.4.1",
+ "from": "node-uuid@1.4.1",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz"
+ },
+ "nodemailer": {
+ "version": "2.1.0",
+ "from": "nodemailer@2.1.0",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.1.0.tgz",
+ "dependencies": {
+ "libmime": {
+ "version": "2.0.0",
+ "from": "libmime@2.0.0",
+ "resolved": "https://registry.npmjs.org/libmime/-/libmime-2.0.0.tgz",
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.13",
+ "from": "iconv-lite@0.4.13",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz"
+ },
+ "libbase64": {
+ "version": "0.1.0",
+ "from": "libbase64@0.1.0",
+ "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz"
+ },
+ "libqp": {
+ "version": "1.1.0",
+ "from": "libqp@1.1.0",
+ "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz"
+ }
+ }
+ },
+ "mailcomposer": {
+ "version": "3.3.2",
+ "from": "mailcomposer@3.3.2",
+ "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-3.3.2.tgz",
+ "dependencies": {
+ "buildmail": {
+ "version": "3.3.2",
+ "from": "buildmail@3.3.2",
+ "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-3.3.2.tgz",
+ "dependencies": {
+ "addressparser": {
+ "version": "1.0.0",
+ "from": "addressparser@1.0.0",
+ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.0.tgz"
+ },
+ "libbase64": {
+ "version": "0.1.0",
+ "from": "libbase64@0.1.0",
+ "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz"
+ },
+ "libqp": {
+ "version": "1.1.0",
+ "from": "libqp@1.1.0",
+ "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz"
+ },
+ "nodemailer-fetch": {
+ "version": "1.2.1",
+ "from": "nodemailer-fetch@1.2.1",
+ "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.2.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "nodemailer-direct-transport": {
+ "version": "2.0.1",
+ "from": "nodemailer-direct-transport@2.0.1",
+ "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-2.0.1.tgz",
+ "dependencies": {
+ "smtp-connection": {
+ "version": "2.0.1",
+ "from": "smtp-connection@2.0.1",
+ "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.0.1.tgz"
+ }
+ }
+ },
+ "nodemailer-shared": {
+ "version": "1.0.3",
+ "from": "nodemailer-shared@1.0.3",
+ "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.0.3.tgz",
+ "dependencies": {
+ "nodemailer-fetch": {
+ "version": "1.2.1",
+ "from": "nodemailer-fetch@1.2.1",
+ "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.2.1.tgz"
+ }
+ }
+ },
+ "nodemailer-smtp-pool": {
+ "version": "2.1.0",
+ "from": "nodemailer-smtp-pool@2.1.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.1.0.tgz",
+ "dependencies": {
+ "clone": {
+ "version": "1.0.2",
+ "from": "clone@1.0.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz"
+ },
+ "nodemailer-wellknown": {
+ "version": "0.1.7",
+ "from": "nodemailer-wellknown@0.1.7",
+ "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.7.tgz"
+ },
+ "smtp-connection": {
+ "version": "2.0.1",
+ "from": "smtp-connection@2.0.1",
+ "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.0.1.tgz"
+ }
+ }
+ },
+ "nodemailer-smtp-transport": {
+ "version": "2.0.1",
+ "from": "nodemailer-smtp-transport@2.0.1",
+ "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.0.1.tgz",
+ "dependencies": {
+ "clone": {
+ "version": "1.0.2",
+ "from": "clone@1.0.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz"
+ },
+ "nodemailer-wellknown": {
+ "version": "0.1.7",
+ "from": "nodemailer-wellknown@0.1.7",
+ "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.7.tgz"
+ },
+ "smtp-connection": {
+ "version": "2.0.1",
+ "from": "smtp-connection@2.0.1",
+ "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "nodemailer-sendgrid-transport": {
+ "version": "0.2.0",
+ "from": "nodemailer-sendgrid-transport@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-sendgrid-transport/-/nodemailer-sendgrid-transport-0.2.0.tgz",
+ "dependencies": {
+ "sendgrid": {
+ "version": "1.9.2",
+ "from": "sendgrid@>=1.8.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-1.9.2.tgz",
+ "dependencies": {
+ "mime": {
+ "version": "1.3.4",
+ "from": "mime@>=1.2.9 <2.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "from": "lodash@>=3.0.1 <4.0.0||>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
+ },
+ "smtpapi": {
+ "version": "1.2.0",
+ "from": "smtpapi@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/smtpapi/-/smtpapi-1.2.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "nodemailer-ses-transport": {
+ "version": "1.4.0",
+ "from": "nodemailer-ses-transport@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-ses-transport/-/nodemailer-ses-transport-1.4.0.tgz",
+ "dependencies": {
+ "aws-sdk": {
+ "version": "2.4.2",
+ "from": "aws-sdk@>=2.4.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.4.2.tgz",
+ "dependencies": {
+ "sax": {
+ "version": "1.1.5",
+ "from": "sax@1.1.5",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.5.tgz"
+ },
+ "xml2js": {
+ "version": "0.4.15",
+ "from": "xml2js@0.4.15",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.15.tgz"
+ },
+ "xmlbuilder": {
+ "version": "2.6.2",
+ "from": "xmlbuilder@2.6.2",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.6.2.tgz",
+ "dependencies": {
+ "lodash": {
+ "version": "3.5.0",
+ "from": "lodash@>=3.5.0 <3.6.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.5.0.tgz"
+ }
+ }
+ },
+ "jmespath": {
+ "version": "0.15.0",
+ "from": "jmespath@0.15.0",
+ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "from": "optimist@0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.3",
+ "from": "wordwrap@>=0.0.2 <0.1.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
+ },
+ "minimist": {
+ "version": "0.0.10",
+ "from": "minimist@>=0.0.1 <0.1.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz"
+ }
+ }
+ },
+ "redback": {
+ "version": "0.4.0",
+ "from": "redback@0.4.0",
+ "resolved": "https://registry.npmjs.org/redback/-/redback-0.4.0.tgz"
+ },
+ "redis": {
+ "version": "0.10.1",
+ "from": "redis@0.10.1",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-0.10.1.tgz"
+ },
+ "redis-sharelatex": {
+ "version": "0.0.9",
+ "from": "redis-sharelatex@0.0.9",
+ "resolved": "https://registry.npmjs.org/redis-sharelatex/-/redis-sharelatex-0.0.9.tgz",
+ "dependencies": {
+ "chai": {
+ "version": "1.9.1",
+ "from": "chai@1.9.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.1.tgz",
+ "dependencies": {
+ "assertion-error": {
+ "version": "1.0.0",
+ "from": "assertion-error@1.0.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz"
+ },
+ "deep-eql": {
+ "version": "0.1.3",
+ "from": "deep-eql@0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+ "dependencies": {
+ "type-detect": {
+ "version": "0.1.1",
+ "from": "type-detect@0.1.1",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "coffee-script": {
+ "version": "1.8.0",
+ "from": "coffee-script@1.8.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.8.0.tgz",
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ }
+ }
+ },
+ "grunt-contrib-coffee": {
+ "version": "0.11.1",
+ "from": "grunt-contrib-coffee@0.11.1",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.11.1.tgz",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.7.1",
+ "from": "coffee-script@>=1.7.0 <1.8.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz",
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@>=0.3.5 <0.4.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ }
+ }
+ },
+ "chalk": {
+ "version": "0.5.1",
+ "from": "chalk@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "1.1.0",
+ "from": "ansi-styles@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "has-ansi": {
+ "version": "0.1.0",
+ "from": "has-ansi@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "0.2.1",
+ "from": "ansi-regex@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "0.3.0",
+ "from": "strip-ansi@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "0.2.1",
+ "from": "ansi-regex@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "0.2.0",
+ "from": "supports-color@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
+ }
+ }
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "from": "lodash@>=2.4.1 <2.5.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz"
+ }
+ }
+ },
+ "grunt-mocha-test": {
+ "version": "0.12.0",
+ "from": "grunt-mocha-test@0.12.0",
+ "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.12.0.tgz",
+ "dependencies": {
+ "hooker": {
+ "version": "0.2.3",
+ "from": "hooker@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz"
+ },
+ "fs-extra": {
+ "version": "0.11.1",
+ "from": "fs-extra@>=0.11.1 <0.12.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.11.1.tgz",
+ "dependencies": {
+ "ncp": {
+ "version": "0.6.0",
+ "from": "ncp@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.6.0.tgz"
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.1 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "jsonfile": {
+ "version": "2.3.1",
+ "from": "jsonfile@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.3.1.tgz"
+ },
+ "rimraf": {
+ "version": "2.5.2",
+ "from": "rimraf@>=2.2.8 <3.0.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.2.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "7.0.5",
+ "from": "glob@>=7.0.0 <8.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz",
+ "dependencies": {
+ "fs.realpath": {
+ "version": "1.0.0",
+ "from": "fs.realpath@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ },
+ "inflight": {
+ "version": "1.0.5",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "from": "once@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "mocha": {
+ "version": "1.21.4",
+ "from": "mocha@1.21.4",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.21.4.tgz",
+ "dependencies": {
+ "commander": {
+ "version": "2.0.0",
+ "from": "commander@2.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz"
+ },
+ "growl": {
+ "version": "1.8.1",
+ "from": "growl@>=1.8.0 <1.9.0",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.8.1.tgz"
+ },
+ "jade": {
+ "version": "0.26.3",
+ "from": "jade@0.26.3",
+ "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
+ "dependencies": {
+ "commander": {
+ "version": "0.6.1",
+ "from": "commander@0.6.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz"
+ },
+ "mkdirp": {
+ "version": "0.3.0",
+ "from": "mkdirp@0.3.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz"
+ }
+ }
+ },
+ "diff": {
+ "version": "1.0.7",
+ "from": "diff@1.0.7",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz"
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@*",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ },
+ "glob": {
+ "version": "3.2.3",
+ "from": "glob@3.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz",
+ "dependencies": {
+ "minimatch": {
+ "version": "0.2.14",
+ "from": "minimatch@>=0.2.11 <0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "dependencies": {
+ "lru-cache": {
+ "version": "2.7.3",
+ "from": "lru-cache@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "from": "sigmund@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "2.0.3",
+ "from": "graceful-fs@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "redis": {
+ "version": "0.12.1",
+ "from": "redis@>=0.12.1 <0.13.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-0.12.1.tgz"
+ },
+ "redis-sentinel": {
+ "version": "0.1.1",
+ "from": "redis-sentinel@0.1.1",
+ "resolved": "https://registry.npmjs.org/redis-sentinel/-/redis-sentinel-0.1.1.tgz",
+ "dependencies": {
+ "redis": {
+ "version": "0.11.0",
+ "from": "redis@>=0.11.0 <0.12.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-0.11.0.tgz"
+ },
+ "q": {
+ "version": "0.9.2",
+ "from": "q@0.9.2",
+ "resolved": "https://registry.npmjs.org/q/-/q-0.9.2.tgz"
+ }
+ }
+ },
+ "sandboxed-module": {
+ "version": "1.0.1",
+ "from": "sandboxed-module@1.0.1",
+ "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-1.0.1.tgz",
+ "dependencies": {
+ "require-like": {
+ "version": "0.1.2",
+ "from": "require-like@0.1.2",
+ "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz"
+ },
+ "stack-trace": {
+ "version": "0.0.9",
+ "from": "stack-trace@0.0.9",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz"
+ }
+ }
+ },
+ "sinon": {
+ "version": "1.10.3",
+ "from": "sinon@1.10.3",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.10.3.tgz",
+ "dependencies": {
+ "formatio": {
+ "version": "1.0.2",
+ "from": "formatio@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.0.2.tgz",
+ "dependencies": {
+ "samsam": {
+ "version": "1.1.3",
+ "from": "samsam@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.3.tgz"
+ }
+ }
+ },
+ "util": {
+ "version": "0.10.3",
+ "from": "util@>=0.10.3 <1.0.0",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.7.0",
+ "from": "underscore@1.7.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz"
+ }
+ }
+ },
+ "request": {
+ "version": "2.72.0",
+ "from": "request@>=2.69.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.72.0.tgz",
+ "dependencies": {
+ "aws-sign2": {
+ "version": "0.6.0",
+ "from": "aws-sign2@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
+ },
+ "aws4": {
+ "version": "1.4.1",
+ "from": "aws4@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz"
+ },
+ "bl": {
+ "version": "1.1.2",
+ "from": "bl@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "from": "readable-stream@>=2.0.5 <2.1.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "from": "caseless@>=0.11.0 <0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "from": "combined-stream@>=1.0.5 <1.1.0",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "dependencies": {
+ "delayed-stream": {
+ "version": "1.0.0",
+ "from": "delayed-stream@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.0",
+ "from": "extend@>=3.0.0 <3.1.0",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "from": "forever-agent@>=0.6.1 <0.7.0",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
+ },
+ "form-data": {
+ "version": "1.0.0-rc4",
+ "from": "form-data@>=1.0.0-rc3 <1.1.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz",
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "from": "async@>=1.5.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz"
+ }
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "from": "har-validator@>=2.0.6 <2.1.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "from": "chalk@>=1.1.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.2.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ }
+ }
+ },
+ "commander": {
+ "version": "2.9.0",
+ "from": "commander@>=2.9.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "dependencies": {
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "from": "graceful-readlink@>=1.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
+ }
+ }
+ },
+ "is-my-json-valid": {
+ "version": "2.13.1",
+ "from": "is-my-json-valid@>=2.12.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz",
+ "dependencies": {
+ "generate-function": {
+ "version": "2.0.0",
+ "from": "generate-function@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "from": "generate-object-property@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "dependencies": {
+ "is-property": {
+ "version": "1.0.2",
+ "from": "is-property@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
+ }
+ }
+ },
+ "jsonpointer": {
+ "version": "2.0.0",
+ "from": "jsonpointer@2.0.0",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "from": "xtend@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
+ }
+ }
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "from": "pinkie-promise@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "dependencies": {
+ "pinkie": {
+ "version": "2.0.4",
+ "from": "pinkie@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
+ }
+ }
+ }
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "from": "hawk@>=3.1.3 <3.2.0",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "dependencies": {
+ "hoek": {
+ "version": "2.16.3",
+ "from": "hoek@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
+ },
+ "boom": {
+ "version": "2.10.1",
+ "from": "boom@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "from": "cryptiles@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "from": "sntp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "from": "http-signature@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "dependencies": {
+ "assert-plus": {
+ "version": "0.2.0",
+ "from": "assert-plus@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
+ },
+ "jsprim": {
+ "version": "1.3.0",
+ "from": "jsprim@>=1.2.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz",
+ "dependencies": {
+ "extsprintf": {
+ "version": "1.0.2",
+ "from": "extsprintf@1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
+ },
+ "json-schema": {
+ "version": "0.2.2",
+ "from": "json-schema@0.2.2",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz"
+ },
+ "verror": {
+ "version": "1.3.6",
+ "from": "verror@1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
+ }
+ }
+ },
+ "sshpk": {
+ "version": "1.8.3",
+ "from": "sshpk@>=1.7.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.8.3.tgz",
+ "dependencies": {
+ "asn1": {
+ "version": "0.2.3",
+ "from": "asn1@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ },
+ "dashdash": {
+ "version": "1.14.0",
+ "from": "dashdash@>=1.12.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz"
+ },
+ "getpass": {
+ "version": "0.1.6",
+ "from": "getpass@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz"
+ },
+ "jsbn": {
+ "version": "0.1.0",
+ "from": "jsbn@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
+ },
+ "tweetnacl": {
+ "version": "0.13.3",
+ "from": "tweetnacl@>=0.13.0 <0.14.0",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
+ },
+ "jodid25519": {
+ "version": "1.0.2",
+ "from": "jodid25519@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "from": "ecc-jsbn@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "from": "is-typedarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "from": "isstream@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "from": "json-stringify-safe@>=5.0.1 <6.0.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
+ },
+ "mime-types": {
+ "version": "2.1.11",
+ "from": "mime-types@>=2.1.7 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.23.0",
+ "from": "mime-db@>=1.23.0 <1.24.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
+ }
+ }
+ },
+ "node-uuid": {
+ "version": "1.4.7",
+ "from": "node-uuid@>=1.4.7 <1.5.0",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "from": "oauth-sign@>=0.8.1 <0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
+ },
+ "qs": {
+ "version": "6.1.0",
+ "from": "qs@>=6.1.0 <6.2.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.1.0.tgz"
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "from": "stringstream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
+ },
+ "tough-cookie": {
+ "version": "2.2.2",
+ "from": "tough-cookie@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz"
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "from": "tunnel-agent@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
+ }
+ }
+ },
+ "requests": {
+ "version": "0.1.7",
+ "from": "requests@>=0.1.7 <0.2.0",
+ "resolved": "https://registry.npmjs.org/requests/-/requests-0.1.7.tgz",
+ "dependencies": {
+ "axo": {
+ "version": "0.0.1",
+ "from": "axo@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/axo/-/axo-0.0.1.tgz"
+ },
+ "eventemitter3": {
+ "version": "1.1.1",
+ "from": "eventemitter3@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz"
+ },
+ "extendible": {
+ "version": "0.1.1",
+ "from": "extendible@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/extendible/-/extendible-0.1.1.tgz"
+ },
+ "hang": {
+ "version": "1.0.0",
+ "from": "hang@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/hang/-/hang-1.0.0.tgz"
+ },
+ "loads": {
+ "version": "0.0.4",
+ "from": "loads@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/loads/-/loads-0.0.4.tgz",
+ "dependencies": {
+ "failure": {
+ "version": "1.1.1",
+ "from": "failure@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/failure/-/failure-1.1.1.tgz"
+ },
+ "one-time": {
+ "version": "0.0.4",
+ "from": "one-time@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz"
+ },
+ "xhr-response": {
+ "version": "1.0.1",
+ "from": "xhr-response@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-response/-/xhr-response-1.0.1.tgz"
+ },
+ "xhr-status": {
+ "version": "1.0.0",
+ "from": "xhr-status@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-status/-/xhr-status-1.0.0.tgz"
+ }
+ }
+ },
+ "xhr-send": {
+ "version": "1.0.0",
+ "from": "xhr-send@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-send/-/xhr-send-1.0.0.tgz"
+ }
+ }
+ },
+ "rimraf": {
+ "version": "2.2.6",
+ "from": "rimraf@2.2.6",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz"
+ },
+ "sanitizer": {
+ "version": "0.1.1",
+ "from": "sanitizer@0.1.1",
+ "resolved": "https://registry.npmjs.org/sanitizer/-/sanitizer-0.1.1.tgz"
+ },
+ "settings-sharelatex": {
+ "version": "1.0.0",
+ "from": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0",
+ "resolved": "git+https://github.com/sharelatex/settings-sharelatex.git#cbc5e41c1dbe6789721a14b3fdae05bf22546559",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.6.0",
+ "from": "coffee-script@1.6.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz"
+ }
+ }
+ },
+ "sixpack-client": {
+ "version": "1.0.0",
+ "from": "sixpack-client@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sixpack-client/-/sixpack-client-1.0.0.tgz"
+ },
+ "temp": {
+ "version": "0.8.3",
+ "from": "temp@>=0.8.3 <0.9.0",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
+ "dependencies": {
+ "os-tmpdir": {
+ "version": "1.0.1",
+ "from": "os-tmpdir@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz"
+ }
+ }
+ },
+ "translations-sharelatex": {
+ "version": "0.1.4",
+ "from": "git+https://github.com/sharelatex/translations-sharelatex.git#master",
+ "resolved": "git+https://github.com/sharelatex/translations-sharelatex.git#80fc5f140a5bddbe758cfc60651fb411e5b0ca5d",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.10.0",
+ "from": "coffee-script@>=1.7.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz"
+ },
+ "i18next": {
+ "version": "1.7.10",
+ "from": "i18next@>=1.7.1 <1.8.0",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-1.7.10.tgz",
+ "dependencies": {
+ "cookies": {
+ "version": "0.6.1",
+ "from": "cookies@>=0.2.2",
+ "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.6.1.tgz",
+ "dependencies": {
+ "depd": {
+ "version": "1.1.0",
+ "from": "depd@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
+ },
+ "keygrip": {
+ "version": "1.0.1",
+ "from": "keygrip@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.1.tgz"
+ }
+ }
+ },
+ "json5": {
+ "version": "0.2.0",
+ "from": "json5@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.2.0.tgz"
+ }
+ }
+ },
+ "onesky": {
+ "version": "0.1.6",
+ "from": "onesky@>=0.1.5 <0.2.0",
+ "resolved": "https://registry.npmjs.org/onesky/-/onesky-0.1.6.tgz",
+ "dependencies": {
+ "request": {
+ "version": "2.40.0",
+ "from": "request@>=2.40.0 <2.41.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.40.0.tgz",
+ "dependencies": {
+ "qs": {
+ "version": "1.0.2",
+ "from": "qs@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-1.0.2.tgz"
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "from": "json-stringify-safe@>=5.0.0 <5.1.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
+ },
+ "mime-types": {
+ "version": "1.0.2",
+ "from": "mime-types@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz"
+ },
+ "forever-agent": {
+ "version": "0.5.2",
+ "from": "forever-agent@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz"
+ },
+ "tough-cookie": {
+ "version": "2.2.2",
+ "from": "tough-cookie@>=0.12.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz"
+ },
+ "form-data": {
+ "version": "0.1.4",
+ "from": "form-data@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz",
+ "dependencies": {
+ "combined-stream": {
+ "version": "0.0.7",
+ "from": "combined-stream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
+ "dependencies": {
+ "delayed-stream": {
+ "version": "0.0.5",
+ "from": "delayed-stream@0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+ }
+ }
+ },
+ "mime": {
+ "version": "1.2.11",
+ "from": "mime@>=1.2.11 <1.3.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
+ },
+ "async": {
+ "version": "0.9.2",
+ "from": "async@>=0.9.0 <0.10.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
+ }
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "from": "tunnel-agent@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
+ },
+ "http-signature": {
+ "version": "0.10.1",
+ "from": "http-signature@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
+ "dependencies": {
+ "assert-plus": {
+ "version": "0.1.5",
+ "from": "assert-plus@>=0.1.5 <0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
+ },
+ "asn1": {
+ "version": "0.1.11",
+ "from": "asn1@0.1.11",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
+ },
+ "ctype": {
+ "version": "0.5.3",
+ "from": "ctype@0.5.3",
+ "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
+ }
+ }
+ },
+ "oauth-sign": {
+ "version": "0.3.0",
+ "from": "oauth-sign@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz"
+ },
+ "hawk": {
+ "version": "1.1.1",
+ "from": "hawk@1.1.1",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz",
+ "dependencies": {
+ "hoek": {
+ "version": "0.9.1",
+ "from": "hoek@>=0.9.0 <0.10.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+ },
+ "boom": {
+ "version": "0.4.2",
+ "from": "boom@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz"
+ },
+ "cryptiles": {
+ "version": "0.2.2",
+ "from": "cryptiles@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz"
+ },
+ "sntp": {
+ "version": "0.2.4",
+ "from": "sntp@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz"
+ }
+ }
+ },
+ "aws-sign2": {
+ "version": "0.5.0",
+ "from": "aws-sign2@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "from": "stringstream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.6.0",
+ "from": "underscore@1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
+ },
+ "v8-profiler": {
+ "version": "5.6.5",
+ "from": "v8-profiler@>=5.2.3 <6.0.0",
+ "resolved": "https://registry.npmjs.org/v8-profiler/-/v8-profiler-5.6.5.tgz",
+ "dependencies": {
+ "nan": {
+ "version": "2.3.5",
+ "from": "nan@>=2.3.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.5.tgz"
+ },
+ "node-pre-gyp": {
+ "version": "0.6.28",
+ "from": "node-pre-gyp@>=0.6.5 <0.7.0",
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.28.tgz",
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "from": "nopt@>=3.0.1 <3.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "from": "abbrev@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
+ }
+ }
+ },
+ "npmlog": {
+ "version": "2.0.4",
+ "from": "npmlog@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz",
+ "dependencies": {
+ "ansi": {
+ "version": "0.3.1",
+ "from": "ansi@>=0.3.1 <0.4.0",
+ "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz"
+ },
+ "are-we-there-yet": {
+ "version": "1.1.2",
+ "from": "are-we-there-yet@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz",
+ "dependencies": {
+ "delegates": {
+ "version": "1.0.0",
+ "from": "delegates@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
+ },
+ "readable-stream": {
+ "version": "2.1.4",
+ "from": "readable-stream@>=2.0.0 <3.0.0||>=1.1.13 <2.0.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz",
+ "dependencies": {
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ }
+ }
+ }
+ },
+ "gauge": {
+ "version": "1.2.7",
+ "from": "gauge@>=1.2.5 <1.3.0",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz",
+ "dependencies": {
+ "has-unicode": {
+ "version": "2.0.1",
+ "from": "has-unicode@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz"
+ },
+ "lodash.pad": {
+ "version": "4.4.0",
+ "from": "lodash.pad@>=4.1.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.4.0.tgz",
+ "dependencies": {
+ "lodash._baseslice": {
+ "version": "4.0.0",
+ "from": "lodash._baseslice@>=4.0.0 <4.1.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseslice/-/lodash._baseslice-4.0.0.tgz"
+ },
+ "lodash._basetostring": {
+ "version": "4.12.0",
+ "from": "lodash._basetostring@>=4.12.0 <4.13.0",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz"
+ },
+ "lodash.tostring": {
+ "version": "4.1.3",
+ "from": "lodash.tostring@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.3.tgz"
+ }
+ }
+ },
+ "lodash.padend": {
+ "version": "4.5.0",
+ "from": "lodash.padend@>=4.1.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.5.0.tgz",
+ "dependencies": {
+ "lodash._baseslice": {
+ "version": "4.0.0",
+ "from": "lodash._baseslice@>=4.0.0 <4.1.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseslice/-/lodash._baseslice-4.0.0.tgz"
+ },
+ "lodash._basetostring": {
+ "version": "4.12.0",
+ "from": "lodash._basetostring@>=4.12.0 <4.13.0",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz"
+ },
+ "lodash.tostring": {
+ "version": "4.1.3",
+ "from": "lodash.tostring@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.3.tgz"
+ }
+ }
+ },
+ "lodash.padstart": {
+ "version": "4.5.0",
+ "from": "lodash.padstart@>=4.1.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.5.0.tgz",
+ "dependencies": {
+ "lodash._baseslice": {
+ "version": "4.0.0",
+ "from": "lodash._baseslice@>=4.0.0 <4.1.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseslice/-/lodash._baseslice-4.0.0.tgz"
+ },
+ "lodash._basetostring": {
+ "version": "4.12.0",
+ "from": "lodash._basetostring@>=4.12.0 <4.13.0",
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz"
+ },
+ "lodash.tostring": {
+ "version": "4.1.3",
+ "from": "lodash.tostring@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.3.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "rc": {
+ "version": "1.1.6",
+ "from": "rc@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.6.tgz",
+ "dependencies": {
+ "deep-extend": {
+ "version": "0.4.1",
+ "from": "deep-extend@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz"
+ },
+ "ini": {
+ "version": "1.3.4",
+ "from": "ini@>=1.3.0 <1.4.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz"
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "from": "strip-json-comments@>=1.0.4 <1.1.0",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz"
+ }
+ }
+ },
+ "rimraf": {
+ "version": "2.5.2",
+ "from": "rimraf@>=2.5.0 <2.6.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.2.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "7.0.5",
+ "from": "glob@>=7.0.0 <8.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz",
+ "dependencies": {
+ "fs.realpath": {
+ "version": "1.0.0",
+ "from": "fs.realpath@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ },
+ "inflight": {
+ "version": "1.0.5",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "from": "once@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
+ }
+ }
+ }
+ }
+ },
+ "semver": {
+ "version": "5.1.1",
+ "from": "semver@>=5.1.0 <5.2.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz"
+ },
+ "tar": {
+ "version": "2.2.1",
+ "from": "tar@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "dependencies": {
+ "block-stream": {
+ "version": "0.0.9",
+ "from": "block-stream@*",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz"
+ },
+ "fstream": {
+ "version": "1.0.10",
+ "from": "fstream@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz",
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.4",
+ "from": "graceful-fs@>=4.1.2 <5.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz"
+ }
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "tar-pack": {
+ "version": "3.1.4",
+ "from": "tar-pack@>=3.1.0 <3.2.0",
+ "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.1.4.tgz",
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.2.0 <2.3.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ }
+ }
+ },
+ "fstream": {
+ "version": "1.0.10",
+ "from": "fstream@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz",
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.1.4",
+ "from": "graceful-fs@>=4.1.2 <5.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ }
+ }
+ },
+ "fstream-ignore": {
+ "version": "1.0.5",
+ "from": "fstream-ignore@>=1.0.5 <1.1.0",
+ "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.2",
+ "from": "minimatch@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz",
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.5",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.5.tgz",
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.1",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "from": "once@>=1.3.3 <1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "dependencies": {
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.1.4",
+ "from": "readable-stream@>=2.1.4 <2.2.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.4.tgz",
+ "dependencies": {
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@>=2.0.1 <2.1.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ }
+ },
+ "uid-number": {
+ "version": "0.0.6",
+ "from": "uid-number@>=0.0.6 <0.1.0",
+ "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "xml2js": {
+ "version": "0.2.0",
+ "from": "xml2js@0.2.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.0.tgz",
+ "dependencies": {
+ "sax": {
+ "version": "1.2.1",
+ "from": "sax@>=0.1.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz"
+ }
+ }
+ }
+ }
+}
diff --git a/services/web/package.json b/services/web/package.json
index 3f077d61fd..8d14a350dc 100644
--- a/services/web/package.json
+++ b/services/web/package.json
@@ -76,6 +76,7 @@
"grunt-contrib-watch": "^1.0.0",
"grunt-env": "0.4.4",
"grunt-exec": "^0.4.7",
+ "grunt-execute": "^0.2.2",
"grunt-file-append": "0.0.6",
"grunt-git-rev-parse": "^0.1.4",
"grunt-mocha-test": "0.9.0",
diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
index 596f350812..800d6bd194 100644
--- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
+++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
@@ -74,15 +74,17 @@ define [
editor.commands.removeCommand "foldall"
# For European keyboards, the / is above 7 so needs Shift pressing.
- # This comes through as Ctrl-Shift-/ which is mapped to toggleBlockComment.
+ # This comes through as Command-Shift-/ on OS X, which is mapped to
+ # toggleBlockComment.
# This doesn't do anything for LaTeX, so remap this to togglecomment to
# work for European keyboards as normal.
+ # On Windows, the key combo comes as Ctrl-Shift-7.
editor.commands.removeCommand "toggleBlockComment"
editor.commands.removeCommand "togglecomment"
editor.commands.addCommand {
name: "togglecomment",
- bindKey: { win: "Ctrl-/|Ctrl-Shift-/", mac: "Command-/|Command-Shift-/" },
+ bindKey: { win: "Ctrl-/|Ctrl-Shift-7", mac: "Command-/|Command-Shift-/" },
exec: (editor) -> editor.toggleCommentLines(),
multiSelectAction: "forEachLine",
scrollIntoView: "selectionPart"
diff --git a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee
index b4cb138be8..e7735e89dc 100644
--- a/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee
+++ b/services/web/public/coffee/ide/human-readable-logs/HumanReadableLogsRules.coffee
@@ -1,90 +1,90 @@
define -> [
regexToMatch: /Misplaced alignment tab character \&/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Misplaced_alignment_tab_character_%26"
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Misplaced_alignment_tab_character_%26"
humanReadableHint: """
You have placed an alignment tab character '&' in the wrong place. If you want to align something, you must write it inside an align environment such as \\begin{align} \u2026 \\end{align}, \\begin{tabular} \u2026 \\end{tabular}, etc. If you want to write an ampersand '&' in text, you must write \\& instead.
"""
,
regexToMatch: /Extra alignment tab has been changed to \\cr/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Extra_alignment_tab_has_been_changed_to_%5Ccr"
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Extra_alignment_tab_has_been_changed_to_%5Ccr"
humanReadableHint: """
You have written too many alignment tabs in a table, causing one of them to be turned into a line break. Make sure you have specified the correct number of columns in your table.
"""
,
regexToMatch: /Display math should end with \$\$/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Display_math_should_end_with_$$."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Display_math_should_end_with_$$."
humanReadableHint: """
You have forgotten a $ sign at the end of 'display math' mode. When writing in display math mode, you must always math write inside $$ \u2026 $$. Check that the number of $s match around each math expression.
"""
,
regexToMatch: /Missing [{$] inserted./
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Missing_$_inserted"
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Missing_$_inserted"
humanReadableHint: """
- Check that your $'s match around math expressions. If they do, then you've probably used a symbol in normal text that needs to be in math mode. Symbols such as subscripts ( _ ), integrals ( \\int ), Greek letters ( \\alpha, \\beta, \\delta ), and modifiers (\\vec{x}, \\tilde{x} ) must be written in math mode. See the full list here.
+ Check that your $'s match around math expressions. If they do, then you've probably used a symbol in normal text that needs to be in math mode. Symbols such as subscripts ( _ ), integrals ( \\int ), Greek letters ( \\alpha, \\beta, \\delta ), and modifiers (\\vec{x}, \\tilde{x} ) must be written in math mode. See the full list here.If you intended to use mathematics mode, then use $ \u2026 $ for 'inline math mode', $$ \u2026 $$ for 'display math mode' or alternatively \begin{math} \u2026 \end{math}.
"""
,
regexToMatch: /(undefined )?[rR]eference(s)?.+(undefined)?/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:There_were_undefined_references."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/There_were_undefined_references."
humanReadableHint: """
You have referenced something which has not yet been labelled. If you have labelled it already, make sure that what is written inside \\ref{...} is the same as what is written inside \\label{...}.
"""
,
regexToMatch: /Citation .+ on page .+ undefined on input line .+/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Citation_XXX_on_page_XXX_undefined_on_input_line_XXX."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Citation_XXX_on_page_XXX_undefined_on_input_line_XXX."
humanReadableHint: """
You have cited something which is not included in your bibliography. Make sure that the citation (\\cite{...}) has a corresponding key in your bibliography, and that both are spelled the same way.
"""
,
regexToMatch: /(Label .+)? multiply[ -]defined( labels)?/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:There_were_multiply-defined_labels."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/There_were_multiply-defined_labels."
humanReadableHint: """
You have used the same label more than once. Check that each \\label{...} labels only one item.
"""
,
regexToMatch: /`!?h' float specifier changed to `!?ht'/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:%60!h%27_float_specifier_changed_to_%60!ht%27."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/%60!h%27_float_specifier_changed_to_%60!ht%27."
humanReadableHint: """
The float specifier 'h' is too strict of a demand for LaTeX to place your float in a nice way here. Try relaxing it by using 'ht', or even 'htbp' if necessary. If you want to try keep the float here anyway, check out the float package.
"""
,
regexToMatch: /No positions in optional float specifier/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:No_positions_in_optional_float_specifier."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/No_positions_in_optional_float_specifier."
humanReadableHint: """
You have forgotten to include a float specifier, which tells LaTeX where to position your figure. Find out more about float specifiers here.
"""
,
regexToMatch: /Undefined control sequence/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:Undefined_control_sequence."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/Undefined_control_sequence."
humanReadableHint: """
The compiler is having trouble understanding a command you have used. Check that the command is spelled correctly. If the command is part of a package, make sure you have included the package in your preamble using \\usepackage{...}.
"""
,
regexToMatch: /File .+ not found/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:File_XXX_not_found_on_input_line_XXX."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/File_XXX_not_found_on_input_line_XXX."
humanReadableHint: """
- The compiler cannot find the file you want to include. Make sure that you have uploaded the file and specified the file location correctly.
+ The compiler cannot find the file you want to include. Make sure that you have uploaded the file and specified the file location correctly.
"""
,
regexToMatch: /LaTeX Error: Unknown graphics extension: \..+/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_graphics_extension:_.gif."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_Unknown_graphics_extension:_.gif."
humanReadableHint: """
- The compiler does not recognise the file type of one of your images. Make sure you are using a supported image format for your choice of compiler, and check that there are no periods (.) in the name of your image.
+ The compiler does not recognise the file type of one of your images. Make sure you are using a supported image format for your choice of compiler, and check that there are no periods (.) in the name of your image.
"""
,
regexToMatch: /LaTeX Error: Unknown float option `H'/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_float_option_%60H%27."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_Unknown_float_option_%60H%27."
humanReadableHint: """
The compiler isn't recognizing the float option 'H'. Include \\usepackage{float} in your preamble to fix this.
"""
,
regexToMatch: /LaTeX Error: Unknown float option `.+'/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_float_option_%60H%27."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_Unknown_float_option_%60H%27."
humanReadableHint: """
You have used a float specifier which the compiler does not understand. You can learn more about the different float options available for placing figures here.
"""
,
regexToMatch: /LaTeX Error: \\math.+ allowed only in math mode/
- extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_%5Cmathrm_allowed_only_in_math_mode."
+ extraInfoURL: "https://www.sharelatex.com/learn/Errors/LaTeX_Error:_%5Cmathrm_allowed_only_in_math_mode."
humanReadableHint: """
You have used a font command which is only available in math mode. To use this command, you must be in maths mode (E.g. $ \u2026 $ or \\begin{math} \u2026 \\end{math}). If you want to use it outside of math mode, use the text version instead: \\textrm, \\textit, etc.
"""
diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
index 52b243c79b..610915ec3a 100644
--- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
+++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
@@ -6,13 +6,14 @@ define [
], (App, Ace, HumanReadableLogs, BibLogParser) ->
App.controller "PdfController", ($scope, $http, ide, $modal, synctex, event_tracking, localStorage) ->
- # enable per-user containers if querystring includes isolated=true
- perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined
+ # enable per-user containers by default
+ perUserCompile = true
autoCompile = true
# pdf.view = uncompiled | pdf | errors
$scope.pdf.view = if $scope?.pdf?.url then 'pdf' else 'uncompiled'
$scope.shouldShowLogs = false
+ $scope.wikiEnabled = window.wikiEnabled;
if ace.require("ace/lib/useragent").isMac
$scope.modifierKey = "Cmd"
@@ -24,6 +25,11 @@ define [
qs_args = ("#{k}=#{v}" for k, v of args)
if qs_args.length then "?" + qs_args.join("&") else ""
+ $scope.stripHTMLFromString = (htmlStr) ->
+ tmp = document.createElement("DIV")
+ tmp.innerHTML = htmlStr
+ return tmp.textContent || tmp.innerText || ""
+
$scope.$on "project:joined", () ->
return if !autoCompile
autoCompile = false
@@ -173,7 +179,7 @@ define [
accumulateResults = (newEntries) ->
for key in ['all', 'errors', 'warnings']
logEntries[key] = logEntries[key].concat newEntries[key]
-
+
# use the parsers for each file type
processLog = (log) ->
$scope.pdf.rawLog = log
@@ -319,8 +325,8 @@ define [
$scope.startedFreeTrial = true
App.factory "synctex", ["ide", "$http", "$q", (ide, $http, $q) ->
- # enable per-user containers if querystring includes isolated=true
- perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined
+ # enable per-user containers by default
+ perUserCompile = true
synctex =
syncToPdf: (cursorPosition) ->
diff --git a/services/web/public/coffee/ide/wordcount/controllers/WordCountModalController.coffee b/services/web/public/coffee/ide/wordcount/controllers/WordCountModalController.coffee
index 2336de614d..5166a32ae1 100644
--- a/services/web/public/coffee/ide/wordcount/controllers/WordCountModalController.coffee
+++ b/services/web/public/coffee/ide/wordcount/controllers/WordCountModalController.coffee
@@ -5,7 +5,9 @@ define [
$scope.status =
loading:true
- perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined
+ # enable per-user containers by default
+ perUserCompile = true
+
opts =
url:"/project/#{ide.project_id}/wordcount"
method:"GET"
diff --git a/services/web/public/coffee/main/new-subscription.coffee b/services/web/public/coffee/main/new-subscription.coffee
index 404b512e7b..93c2c0a7cc 100644
--- a/services/web/public/coffee/main/new-subscription.coffee
+++ b/services/web/public/coffee/main/new-subscription.coffee
@@ -115,6 +115,13 @@ define [
currencyCode:pricing.items.currency
plan_code:pricing.items.plan.code
coupon_code:pricing.items?.coupon?.code || ""
+ isPaypal: $scope.paymentMethod == 'paypal'
+ address:
+ address1: $scope.data.address1
+ address2: $scope.data.address2
+ country: $scope.data.country
+ state: $scope.data.state
+ postal_code: $scope.data.postal_code
$http.post("/user/subscription/create", postData)
.success (data, status, headers)->
sixpack.convert "in-editor-free-trial-plan", pricing.items.plan.code, (err)->
diff --git a/services/web/public/stylesheets/app/editor/pdf.less b/services/web/public/stylesheets/app/editor/pdf.less
index db29870c1a..2d147c2f69 100644
--- a/services/web/public/stylesheets/app/editor/pdf.less
+++ b/services/web/public/stylesheets/app/editor/pdf.less
@@ -120,6 +120,10 @@
float: right;
color: @gray;
font-weight: 700;
+
+ .fa {
+ display: none;
+ }
}
.entry-message {
font-weight: 700;
@@ -130,6 +134,26 @@
font-size: 0.8rem;
//font-family: @font-family-monospace;
}
+
+ &:hover .line-no {
+ color: inherit;
+ .fa {
+ display: inline-block;
+ }
+ }
+
+ &.alert-danger:hover {
+ background-color: darken(@alert-danger-bg, 5%);
+ }
+
+ &.alert-warning:hover {
+ background-color: darken(@alert-warning-bg, 5%);
+ }
+
+ &.alert-info:hover {
+ background-color: darken(@alert-info-bg, 5%);
+ }
+
}
pre {
font-size: 12px;
diff --git a/services/web/public/stylesheets/app/wiki.less b/services/web/public/stylesheets/app/wiki.less
index 210230989c..5f7462d02c 100644
--- a/services/web/public/stylesheets/app/wiki.less
+++ b/services/web/public/stylesheets/app/wiki.less
@@ -39,6 +39,8 @@
}
.example {
+ max-width: 100%;
+
.code {
pre {
background-color: @gray-lightest;
@@ -49,10 +51,13 @@
}
}
.output {
+ text-align: center;
+ padding-top: 10px;
+
img {
- width: auto !important;
- height: auto !important;
- max-width: 100% !important;
+ width: auto;
+ height: auto;
+ max-width: 100%;
box-shadow: 0 1px 3px @gray-light;
border-radius: 6px;
}
diff --git a/services/web/test/UnitTests/coffee/Authentication/AuthenticationManagerTests.coffee b/services/web/test/UnitTests/coffee/Authentication/AuthenticationManagerTests.coffee
index f4d5e72c26..2805527259 100644
--- a/services/web/test/UnitTests/coffee/Authentication/AuthenticationManagerTests.coffee
+++ b/services/web/test/UnitTests/coffee/Authentication/AuthenticationManagerTests.coffee
@@ -16,6 +16,7 @@ describe "AuthenticationManager", ->
users: {}
ObjectId: ObjectId
"bcrypt": @bcrypt = {}
+ "settings-sharelatex": { security: { bcryptRounds: 12 } }
@callback = sinon.stub()
describe "authenticate", ->
@@ -31,6 +32,7 @@ describe "AuthenticationManager", ->
beforeEach (done) ->
@user.hashedPassword = @hashedPassword = "asdfjadflasdf"
@bcrypt.compare = sinon.stub().callsArgWith(2, null, true)
+ @bcrypt.getRounds = sinon.stub().returns 12
@AuthenticationManager.authenticate email: @email, @unencryptedPassword, (error, user) =>
@callback(error, user)
done()
@@ -54,6 +56,35 @@ describe "AuthenticationManager", ->
it "should not return the user", ->
@callback.calledWith(null, null).should.equal true
+ describe "when the hashed password matches but the number of rounds is too low", ->
+ beforeEach (done) ->
+ @user.hashedPassword = @hashedPassword = "asdfjadflasdf"
+ @bcrypt.compare = sinon.stub().callsArgWith(2, null, true)
+ @bcrypt.getRounds = sinon.stub().returns 7
+ @AuthenticationManager.setUserPassword = sinon.stub().callsArgWith(2, null)
+ @AuthenticationManager.authenticate email: @email, @unencryptedPassword, (error, user) =>
+ @callback(error, user)
+ done()
+
+ it "should look up the correct user in the database", ->
+ @User.findOne.calledWith(email: @email).should.equal true
+
+ it "should check that the passwords match", ->
+ @bcrypt.compare
+ .calledWith(@unencryptedPassword, @hashedPassword)
+ .should.equal true
+
+ it "should check the number of rounds", ->
+ @bcrypt.getRounds.called.should.equal true
+
+ it "should set the users password (with a higher number of rounds)", ->
+ @AuthenticationManager.setUserPassword
+ .calledWith("user-id", @unencryptedPassword)
+ .should.equal true
+
+ it "should return the user", ->
+ @callback.calledWith(null, @user).should.equal true
+
describe "when the user does not exist in the database", ->
beforeEach ->
@User.findOne = sinon.stub().callsArgWith(1, null, null)
@@ -87,7 +118,7 @@ describe "AuthenticationManager", ->
it "should hash the password", ->
@bcrypt.genSalt
- .calledWith(7)
+ .calledWith(12)
.should.equal true
@bcrypt.hash
.calledWith(@password, @salt)
diff --git a/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee b/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee
index e05040772d..5a5e9fc40c 100644
--- a/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee
+++ b/services/web/test/UnitTests/coffee/Subscription/RecurlyWrapperTests.coffee
@@ -1,9 +1,10 @@
should = require('chai').should()
+expect = require('chai').expect
sinon = require 'sinon'
crypto = require 'crypto'
querystring = require 'querystring'
-RecurlyWrapper = require "../../../../app/js/Features/Subscription/RecurlyWrapper"
-Settings = require "settings-sharelatex"
+modulePath = "../../../../app/js/Features/Subscription/RecurlyWrapper"
+SandboxedModule = require('sandboxed-module')
tk = require("timekeeper")
fixtures =
@@ -97,22 +98,37 @@ mockApiRequest = (options, callback) ->
describe "RecurlyWrapper", ->
- beforeEach ->
- Settings.plans = [{
- planCode: "collaborator"
- name: "Collaborator"
- features:
- collaborators: -1
- versioning: true
- }]
- Settings.defaultPlanCode =
- collaborators: 0
- versioning: false
+
+ before ->
+ @settings =
+ plans: [{
+ planCode: "collaborator"
+ name: "Collaborator"
+ features:
+ collaborators: -1
+ versioning: true
+ }]
+ defaultPlanCode:
+ collaborators: 0
+ versioning: false
+ apis:
+ recurly:
+ apiKey: 'nonsense'
+ privateKey: 'private_nonsense'
+
+ @RecurlyWrapper = RecurlyWrapper = SandboxedModule.require modulePath, requires:
+ "settings-sharelatex": @settings
+ "logger-sharelatex":
+ err: sinon.stub()
+ error: sinon.stub()
+ log: sinon.stub()
+ "request": sinon.stub()
describe "sign", ->
+
before (done) ->
tk.freeze Date.now() # freeze the time for these tests
- RecurlyWrapper.sign({
+ @RecurlyWrapper.sign({
subscription :
plan_code : "gold"
name : "$$$"
@@ -127,7 +143,7 @@ describe "RecurlyWrapper", ->
it "should be signed correctly", ->
signed = @signature.split("|")[0]
query = @signature.split("|")[1]
- crypto.createHmac("sha1", Settings.apis.recurly.privateKey).update(query).digest("hex").should.equal signed
+ crypto.createHmac("sha1", @settings.apis.recurly.privateKey).update(query).digest("hex").should.equal signed
it "should be url escaped", ->
query = @signature.split("|")[1]
@@ -149,38 +165,39 @@ describe "RecurlyWrapper", ->
describe "_parseXml", ->
it "should convert different data types into correct representations", (done) ->
- xml =
- "" +
- "" +
- " " +
- " " +
- " gold" +
- " Gold plan" +
- " " +
- " 44f83d7cba354d5b84812419f923ea96" +
- " active" +
- " 800" +
- " EUR" +
- " 1" +
- " 2011-05-27T07:00:00Z" +
- " " +
- " " +
- " 2011-06-27T07:00:00Z" +
- " 2011-07-27T07:00:00Z" +
- " " +
- " " +
- " " +
- " " +
- " ipaddresses" +
- " 10" +
- " 150" +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- RecurlyWrapper._parseXml xml, (error, data) ->
+ xml = """
+
+
+
+
+ gold
+ Gold plan
+
+ 44f83d7cba354d5b84812419f923ea96
+ active
+ 800
+ EUR
+ 1
+ 2011-05-27T07:00:00Z
+
+
+ 2011-06-27T07:00:00Z
+ 2011-07-27T07:00:00Z
+
+
+
+
+ ipaddresses
+ 10
+ 150
+
+
+
+
+
+
+ """
+ @RecurlyWrapper._parseXml xml, (error, data) ->
data.subscription.plan.plan_code.should.equal "gold"
data.subscription.plan.name.should.equal "Gold plan"
data.subscription.uuid.should.equal "44f83d7cba354d5b84812419f923ea96"
@@ -188,32 +205,37 @@ describe "RecurlyWrapper", ->
data.subscription.unit_amount_in_cents.should.equal 800
data.subscription.currency.should.equal "EUR"
data.subscription.quantity.should.equal 1
+
data.subscription.activated_at.should.deep.equal new Date("2011-05-27T07:00:00Z")
should.equal data.subscription.canceled_at, null
should.equal data.subscription.expires_at, null
+
data.subscription.current_period_started_at.should.deep.equal new Date("2011-06-27T07:00:00Z")
+
data.subscription.current_period_ends_at.should.deep.equal new Date("2011-07-27T07:00:00Z")
should.equal data.subscription.trial_started_at, null
should.equal data.subscription.trial_ends_at, null
- data.subscription.subscription_add_ons.should.deep.equal [{
+
+ data.subscription.subscription_add_ons[0].should.deep.equal {
add_on_code: "ipaddresses"
quantity: "10"
unit_amount_in_cents: "150"
- }]
+ }
data.subscription.account.url.should.equal "https://api.recurly.com/v2/accounts/1"
data.subscription.url.should.equal "https://api.recurly.com/v2/subscriptions/44f83d7cba354d5b84812419f923ea96"
data.subscription.plan.url.should.equal "https://api.recurly.com/v2/plans/gold"
done()
-
+
describe "getSubscription", ->
+
describe "with proper subscription id", ->
before ->
- @apiRequest = sinon.stub(RecurlyWrapper, "apiRequest", mockApiRequest)
- RecurlyWrapper.getSubscription "44f83d7cba354d5b84812419f923ea96", (error, recurlySubscription) =>
+ @apiRequest = sinon.stub(@RecurlyWrapper, "apiRequest", mockApiRequest)
+ @RecurlyWrapper.getSubscription "44f83d7cba354d5b84812419f923ea96", (error, recurlySubscription) =>
@recurlySubscription = recurlySubscription
after ->
- RecurlyWrapper.apiRequest.restore()
-
+ @RecurlyWrapper.apiRequest.restore()
+
it "should look up the subscription at the normal API end point", ->
@apiRequest.args[0][0].url.should.equal "subscriptions/44f83d7cba354d5b84812419f923ea96"
@@ -222,12 +244,12 @@ describe "RecurlyWrapper", ->
describe "with ReculyJS token", ->
before ->
- @apiRequest = sinon.stub(RecurlyWrapper, "apiRequest", mockApiRequest)
- RecurlyWrapper.getSubscription "70db44b10f5f4b238669480c9903f6f5", {recurlyJsResult: true}, (error, recurlySubscription) =>
+ @apiRequest = sinon.stub(@RecurlyWrapper, "apiRequest", mockApiRequest)
+ @RecurlyWrapper.getSubscription "70db44b10f5f4b238669480c9903f6f5", {recurlyJsResult: true}, (error, recurlySubscription) =>
@recurlySubscription = recurlySubscription
after ->
- RecurlyWrapper.apiRequest.restore()
-
+ @RecurlyWrapper.apiRequest.restore()
+
it "should return the subscription", ->
@recurlySubscription.uuid.should.equal "44f83d7cba354d5b84812419f923ea96"
@@ -236,30 +258,30 @@ describe "RecurlyWrapper", ->
describe "with includeAccount", ->
beforeEach ->
- @apiRequest = sinon.stub(RecurlyWrapper, "apiRequest", mockApiRequest)
- RecurlyWrapper.getSubscription "44f83d7cba354d5b84812419f923ea96", {includeAccount: true}, (error, recurlySubscription) =>
+ @apiRequest = sinon.stub(@RecurlyWrapper, "apiRequest", mockApiRequest)
+ @RecurlyWrapper.getSubscription "44f83d7cba354d5b84812419f923ea96", {includeAccount: true}, (error, recurlySubscription) =>
@recurlySubscription = recurlySubscription
afterEach ->
- RecurlyWrapper.apiRequest.restore()
+ @RecurlyWrapper.apiRequest.restore()
it "should request the account from the API", ->
@apiRequest.args[1][0].url.should.equal "accounts/104"
-
+
it "should populate the account attribute", ->
@recurlySubscription.account.account_code.should.equal "104"
-
+
describe "updateSubscription", ->
beforeEach (done) ->
@recurlySubscriptionId = "subscription-id-123"
- @apiRequest = sinon.stub RecurlyWrapper, "apiRequest", (options, callback) =>
+ @apiRequest = sinon.stub @RecurlyWrapper, "apiRequest", (options, callback) =>
@requestOptions = options
callback null, {}, fixtures["subscriptions/44f83d7cba354d5b84812419f923ea96"]
- RecurlyWrapper.updateSubscription @recurlySubscriptionId, { plan_code : "silver", timeframe: "now" }, (error, recurlySubscription) =>
+ @RecurlyWrapper.updateSubscription @recurlySubscriptionId, { plan_code : "silver", timeframe: "now" }, (error, recurlySubscription) =>
@recurlySubscription = recurlySubscription
done()
afterEach ->
- RecurlyWrapper.apiRequest.restore()
+ @RecurlyWrapper.apiRequest.restore()
it "should send an update request to the API", ->
@apiRequest.called.should.equal true
@@ -275,59 +297,723 @@ describe "RecurlyWrapper", ->
it "should return the updated subscription", ->
should.exist @recurlySubscription
@recurlySubscription.plan.plan_code.should.equal "gold"
-
+
describe "cancelSubscription", ->
beforeEach (done) ->
@recurlySubscriptionId = "subscription-id-123"
- @apiRequest = sinon.stub RecurlyWrapper, "apiRequest", (options, callback) =>
+ @apiRequest = sinon.stub @RecurlyWrapper, "apiRequest", (options, callback) =>
options.url.should.equal "subscriptions/#{@recurlySubscriptionId}/cancel"
options.method.should.equal "put"
callback()
- RecurlyWrapper.cancelSubscription(@recurlySubscriptionId, done)
+ @RecurlyWrapper.cancelSubscription(@recurlySubscriptionId, done)
afterEach ->
- RecurlyWrapper.apiRequest.restore()
+ @RecurlyWrapper.apiRequest.restore()
it "should send a cancel request to the API", ->
@apiRequest.called.should.equal true
-
+
describe "reactivateSubscription", ->
beforeEach (done) ->
@recurlySubscriptionId = "subscription-id-123"
- @apiRequest = sinon.stub RecurlyWrapper, "apiRequest", (options, callback) =>
+ @apiRequest = sinon.stub @RecurlyWrapper, "apiRequest", (options, callback) =>
options.url.should.equal "subscriptions/#{@recurlySubscriptionId}/reactivate"
options.method.should.equal "put"
callback()
- RecurlyWrapper.reactivateSubscription(@recurlySubscriptionId, done)
+ @RecurlyWrapper.reactivateSubscription(@recurlySubscriptionId, done)
afterEach ->
- RecurlyWrapper.apiRequest.restore()
+ @RecurlyWrapper.apiRequest.restore()
it "should send a cancel request to the API", ->
@apiRequest.called.should.equal true
-
-
+
+
describe "redeemCoupon", ->
beforeEach (done) ->
@recurlyAccountId = "account-id-123"
@coupon_code = "312321312"
- @apiRequest = sinon.stub RecurlyWrapper, "apiRequest", (options, callback) =>
+ @apiRequest = sinon.stub @RecurlyWrapper, "apiRequest", (options, callback) =>
options.url.should.equal "coupons/#{@coupon_code}/redeem"
options.body.indexOf("#{@recurlyAccountId}").should.not.equal -1
options.body.indexOf("USD").should.not.equal -1
options.method.should.equal "post"
callback()
- RecurlyWrapper.redeemCoupon(@recurlyAccountId, @coupon_code, done)
+ @RecurlyWrapper.redeemCoupon(@recurlyAccountId, @coupon_code, done)
afterEach ->
- RecurlyWrapper.apiRequest.restore()
+ @RecurlyWrapper.apiRequest.restore()
it "should send the request to redem the coupon", ->
@apiRequest.called.should.equal true
-
+
+ describe "_addressToXml", ->
+
+ beforeEach ->
+ @address =
+ address1: "addr_one"
+ address2: "addr_two"
+ country: "some_country"
+ state: "some_state"
+ postal_code: "some_zip"
+ nonsenseKey: "rubbish"
+
+ it 'should generate the correct xml', () ->
+ result = @RecurlyWrapper._addressToXml @address
+ should.equal(
+ result,
+ """
+
+ addr_one
+ addr_two
+ some_country
+ some_state
+ some_zip
+ \n
+ """
+ )
+
+ describe 'createSubscription', ->
+
+ beforeEach ->
+ @user =
+ _id: 'some_id'
+ email: 'user@example.com'
+ @subscriptionDetails =
+ currencyCode: "EUR"
+ plan_code: "some_plan_code"
+ coupon_code: ""
+ isPaypal: true
+ address:
+ address1: "addr_one"
+ address2: "addr_two"
+ country: "some_country"
+ state: "some_state"
+ zip: "some_zip"
+ @subscription = {}
+ @recurly_token_id = "a-token-id"
+ @call = (callback) =>
+ @RecurlyWrapper.createSubscription(@user, @subscriptionDetails, @recurly_token_id, callback)
+ describe 'when paypal', ->
+ beforeEach ->
+ @subscriptionDetails.isPaypal = true
+ @_createPaypalSubscription = sinon.stub(@RecurlyWrapper, '_createPaypalSubscription')
+ @_createPaypalSubscription.callsArgWith(3, null, @subscription)
+
+ afterEach ->
+ @_createPaypalSubscription.restore()
+
+ it 'should not produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.equal null
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should produce a subscription object', (done) ->
+ @call (err, sub) =>
+ expect(sub).to.deep.equal @subscription
+ done()
+
+ it 'should call _createPaypalSubscription', (done) ->
+ @call (err, sub) =>
+ @_createPaypalSubscription.callCount.should.equal 1
+ done()
+
+ describe "when _createPaypalSubscription produces an error", ->
+
+ beforeEach ->
+ @_createPaypalSubscription.callsArgWith(3, new Error('woops'))
+
+ it 'should produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe 'when not paypal', ->
+
+ beforeEach ->
+ @subscriptionDetails.isPaypal = false
+ @_createCreditCardSubscription = sinon.stub(@RecurlyWrapper, '_createCreditCardSubscription')
+ @_createCreditCardSubscription.callsArgWith(3, null, @subscription)
+
+ afterEach ->
+ @_createCreditCardSubscription.restore()
+
+ it 'should not produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.equal null
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should produce a subscription object', (done) ->
+ @call (err, sub) =>
+ expect(sub).to.deep.equal @subscription
+ done()
+
+ it 'should call _createCreditCardSubscription', (done) ->
+ @call (err, sub) =>
+ @_createCreditCardSubscription.callCount.should.equal 1
+ done()
+
+ describe "when _createCreditCardSubscription produces an error", ->
+
+ beforeEach ->
+ @_createCreditCardSubscription.callsArgWith(3, new Error('woops'))
+
+ it 'should produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+
+ describe '_createCreditCardSubscription', ->
+
+ beforeEach ->
+ @user =
+ _id: 'some_id'
+ email: 'user@example.com'
+ @subscriptionDetails =
+ currencyCode: "EUR"
+ plan_code: "some_plan_code"
+ coupon_code: ""
+ isPaypal: true
+ address:
+ address1: "addr_one"
+ address2: "addr_two"
+ country: "some_country"
+ state: "some_state"
+ zip: "some_zip"
+ @subscription = {}
+ @recurly_token_id = "a-token-id"
+ @apiRequest = sinon.stub(@RecurlyWrapper, 'apiRequest')
+ @response =
+ statusCode: 200
+ @body = "is_bad"
+ @apiRequest.callsArgWith(1, null, @response, @body)
+ @_parseSubscriptionXml = sinon.stub(@RecurlyWrapper, '_parseSubscriptionXml')
+ @_parseSubscriptionXml.callsArgWith(1, null, @subscription)
+ @call = (callback) =>
+ @RecurlyWrapper._createCreditCardSubscription(@user, @subscriptionDetails, @recurly_token_id, callback)
+
+ afterEach ->
+ @apiRequest.restore()
+ @_parseSubscriptionXml.restore()
+
+ it 'should not produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.not.be.instanceof Error
+ expect(err).to.equal null
+ done()
+
+ it 'should produce a subscription', (done) ->
+ @call (err, sub) =>
+ expect(sub).to.equal @subscription
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, sub) =>
+ @apiRequest.callCount.should.equal 1
+ done()
+
+ it 'should call _parseSubscriptionXml', (done) ->
+ @call (err, sub) =>
+ @_parseSubscriptionXml.callCount.should.equal 1
+ done()
+
+ describe 'when api request produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'))
+
+ it 'should produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, sub) =>
+ @apiRequest.callCount.should.equal 1
+ done()
+
+ it 'should not _parseSubscriptionXml', (done) ->
+ @call (err, sub) =>
+ @_parseSubscriptionXml.callCount.should.equal 0
+ done()
+
+ describe 'when parse xml produces an error', ->
+
+ beforeEach ->
+ @_parseSubscriptionXml.callsArgWith(1, new Error('woops'))
+
+ it 'should produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe '_createPaypalSubscription', ->
+
+ beforeEach ->
+ @checkAccountExists = sinon.stub(@RecurlyWrapper._paypal, 'checkAccountExists')
+ @createAccount = sinon.stub(@RecurlyWrapper._paypal, 'createAccount')
+ @createBillingInfo = sinon.stub(@RecurlyWrapper._paypal, 'createBillingInfo')
+ @setAddress = sinon.stub(@RecurlyWrapper._paypal, 'setAddress')
+ @createSubscription = sinon.stub(@RecurlyWrapper._paypal, 'createSubscription')
+ @user =
+ _id: 'some_id'
+ email: 'user@example.com'
+ @subscriptionDetails =
+ currencyCode: "EUR"
+ plan_code: "some_plan_code"
+ coupon_code: ""
+ isPaypal: true
+ address:
+ address1: "addr_one"
+ address2: "addr_two"
+ country: "some_country"
+ state: "some_state"
+ zip: "some_zip"
+ @subscription = {}
+ @recurly_token_id = "a-token-id"
+
+ # set up data callbacks
+ user = @user
+ subscriptionDetails = @subscriptionDetails
+ recurly_token_id = @recurly_token_id
+
+ @checkAccountExists.callsArgWith(1, null,
+ {user, subscriptionDetails, recurly_token_id,
+ userExists: false, account: {accountCode: 'xx'}}
+ )
+ @createAccount.callsArgWith(1, null,
+ {user, subscriptionDetails, recurly_token_id,
+ userExists: false, account: {accountCode: 'xx'}}
+ )
+ @createBillingInfo.callsArgWith(1, null,
+ {user, subscriptionDetails, recurly_token_id,
+ userExists: false, account: {accountCode: 'xx'}, billingInfo: {token_id: 'abc'}}
+ )
+ @setAddress.callsArgWith(1, null,
+ {user, subscriptionDetails, recurly_token_id,
+ userExists: false, account: {accountCode: 'xx'}, billingInfo: {token_id: 'abc'}}
+ )
+ @createSubscription.callsArgWith(1, null,
+ {user, subscriptionDetails, recurly_token_id,
+ userExists: false, account: {accountCode: 'xx'}, billingInfo: {token_id: 'abc'}, subscription: @subscription}
+ )
+
+ @call = (callback) =>
+ @RecurlyWrapper._createPaypalSubscription @user, @subscriptionDetails, @recurly_token_id, callback
+
+ afterEach ->
+ @checkAccountExists.restore()
+ @createAccount.restore()
+ @createBillingInfo.restore()
+ @setAddress.restore()
+ @createSubscription.restore()
+
+ it 'should not produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should produce a subscription object', (done) ->
+ @call (err, sub) =>
+ expect(sub).to.not.equal null
+ expect(sub).to.equal @subscription
+ done()
+
+ it 'should call each of the paypal stages', (done) ->
+ @call (err, sub) =>
+ @checkAccountExists.callCount.should.equal 1
+ @createAccount.callCount.should.equal 1
+ @createBillingInfo.callCount.should.equal 1
+ @setAddress.callCount.should.equal 1
+ @createSubscription.callCount.should.equal 1
+ done()
+
+ describe 'when one of the paypal stages produces an error', ->
+
+ beforeEach ->
+ @createAccount.callsArgWith(1, new Error('woops'))
+
+ it 'should produce an error', (done) ->
+ @call (err, sub) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ it 'should stop calling the paypal stages after the error', (done) ->
+ @call (err, sub) =>
+ @checkAccountExists.callCount.should.equal 1
+ @createAccount.callCount.should.equal 1
+ @createBillingInfo.callCount.should.equal 0
+ @setAddress.callCount.should.equal 0
+ @createSubscription.callCount.should.equal 0
+ done()
+
+ describe 'paypal actions', ->
+
+ beforeEach ->
+ @apiRequest = sinon.stub(@RecurlyWrapper, 'apiRequest')
+ @_parseAccountXml = sinon.spy(@RecurlyWrapper, '_parseAccountXml')
+ @_parseBillingInfoXml = sinon.spy(@RecurlyWrapper, '_parseBillingInfoXml')
+ @_parseSubscriptionXml = sinon.spy(@RecurlyWrapper, '_parseSubscriptionXml')
+ @cache =
+ user: @user = {_id: 'some_id'}
+ recurly_token_id: @recurly_token_id = "some_token"
+ subscriptionDetails: @subscriptionDetails =
+ currencyCode: "EUR"
+ plan_code: "some_plan_code"
+ coupon_code: ""
+ isPaypal: true
+ address:
+ address1: "addr_one"
+ address2: "addr_two"
+ country: "some_country"
+ state: "some_state"
+ zip: "some_zip"
+
+ afterEach ->
+ @apiRequest.restore()
+ @_parseAccountXml.restore()
+ @_parseBillingInfoXml.restore()
+ @_parseSubscriptionXml.restore()
+
+ describe '_paypal.checkAccountExists', ->
+
+ beforeEach ->
+ @call = (callback) =>
+ @RecurlyWrapper._paypal.checkAccountExists @cache, callback
+
+ describe 'when the account exists', ->
+
+ beforeEach ->
+ resultXml = 'abc'
+ @apiRequest.callsArgWith(1, null, {statusCode: 200}, resultXml)
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ done()
+
+ it 'should call _parseAccountXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseAccountXml.callCount.should.equal 1
+ done()
+
+ it 'should add the account to the cumulative result', (done) ->
+ @call (err, result) =>
+ expect(result.account).to.not.equal null
+ expect(result.account).to.not.equal undefined
+ expect(result.account).to.deep.equal {
+ account_code: 'abc'
+ }
+ done()
+
+ it 'should set userExists to true', (done) ->
+ @call (err, result) =>
+ expect(result.userExists).to.equal true
+ done()
+
+ describe 'when the account does not exist', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('not found'), {statusCode: 404}, '')
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ @apiRequest.firstCall.args[0].method.should.equal 'GET'
+ done()
+
+ it 'should not call _parseAccountXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseAccountXml.callCount.should.equal 0
+ done()
+
+ it 'should not add the account to result', (done) ->
+ @call (err, result) =>
+ expect(result.account).to.equal undefined
+ done()
+
+ it 'should set userExists to false', (done) ->
+ @call (err, result) =>
+ expect(result.userExists).to.equal false
+ done()
+
+ describe 'when apiRequest produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'), {statusCode: 500})
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe '_paypal.createAccount', ->
+
+ beforeEach ->
+ @call = (callback) =>
+ @RecurlyWrapper._paypal.createAccount @cache, callback
+
+ describe 'when address is missing from subscriptionDetails', ->
+
+ beforeEach ->
+ @cache.subscriptionDetails.address = null
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe 'when account already exists', ->
+
+ beforeEach ->
+ @cache.userExists = true
+ @cache.account =
+ account_code: 'abc'
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should produce cache object', (done) ->
+ @call (err, result) =>
+ expect(result).to.deep.equal @cache
+ expect(result.account).to.deep.equal {
+ account_code: 'abc'
+ }
+ done()
+
+ it 'should not call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 0
+ done()
+
+ it 'should not call _parseAccountXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseAccountXml.callCount.should.equal 0
+ done()
+
+ describe 'when account does not exist', ->
+
+ beforeEach ->
+ @cache.userExists = false
+ resultXml = 'abc'
+ @apiRequest.callsArgWith(1, null, {statusCode: 200}, resultXml)
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ @apiRequest.firstCall.args[0].method.should.equal 'POST'
+ done()
+
+ it 'should call _parseAccountXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseAccountXml.callCount.should.equal 1
+ done()
+
+ describe 'when apiRequest produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'), {statusCode: 500})
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe '_paypal.createBillingInfo', ->
+
+ beforeEach ->
+ @cache.account =
+ account_code: 'abc'
+ @call = (callback) =>
+ @RecurlyWrapper._paypal.createBillingInfo @cache, callback
+
+ describe 'when account_code is missing from cache', ->
+
+ beforeEach ->
+ @cache.account.account_code = null
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe 'when all goes well', ->
+
+ beforeEach ->
+ resultXml = '1'
+ @apiRequest.callsArgWith(1, null, {statusCode: 200}, resultXml)
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ @apiRequest.firstCall.args[0].method.should.equal 'POST'
+ done()
+
+ it 'should call _parseBillingInfoXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseBillingInfoXml.callCount.should.equal 1
+ done()
+
+ it 'should set billingInfo on cache', (done) ->
+ @call (err, result) =>
+ expect(result.billingInfo).to.deep.equal {
+ a: "1"
+ }
+ done()
+
+ describe 'when apiRequest produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'), {statusCode: 500})
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe '_paypal.setAddress', ->
+
+ beforeEach ->
+ @cache.account =
+ account_code: 'abc'
+ @cache.billingInfo = {}
+ @call = (callback) =>
+ @RecurlyWrapper._paypal.setAddress @cache, callback
+
+ describe 'when account_code is missing from cache', ->
+
+ beforeEach ->
+ @cache.account.account_code = null
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe 'when address is missing from subscriptionDetails', ->
+
+ beforeEach ->
+ @cache.subscriptionDetails.address = null
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe 'when all goes well', ->
+
+ beforeEach ->
+ resultXml = 'London'
+ @apiRequest.callsArgWith(1, null, {statusCode: 200}, resultXml)
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ @apiRequest.firstCall.args[0].method.should.equal 'PUT'
+ done()
+
+ it 'should call _parseBillingInfoXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseBillingInfoXml.callCount.should.equal 1
+ done()
+
+ it 'should set billingInfo on cache', (done) ->
+ @call (err, result) =>
+ expect(result.billingInfo).to.deep.equal {
+ city: 'London'
+ }
+ done()
+
+ describe 'when apiRequest produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'), {statusCode: 500})
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()
+
+ describe '_paypal.createSubscription', ->
+
+ beforeEach ->
+ @cache.account =
+ account_code: 'abc'
+ @cache.billingInfo = {}
+ @call = (callback) =>
+ @RecurlyWrapper._paypal.createSubscription @cache, callback
+
+ describe 'when all goes well', ->
+
+ beforeEach ->
+ resultXml = '1'
+ @apiRequest.callsArgWith(1, null, {statusCode: 200}, resultXml)
+
+ it 'should not produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.not.be.instanceof Error
+ done()
+
+ it 'should call apiRequest', (done) ->
+ @call (err, result) =>
+ @apiRequest.callCount.should.equal 1
+ @apiRequest.firstCall.args[0].method.should.equal 'POST'
+ done()
+
+ it 'should call _parseSubscriptionXml', (done) ->
+ @call (err, result) =>
+ @RecurlyWrapper._parseSubscriptionXml.callCount.should.equal 1
+ done()
+
+ it 'should set subscription on cache', (done) ->
+ @call (err, result) =>
+ expect(result.subscription).to.deep.equal {
+ a: "1"
+ }
+ done()
+
+ describe 'when apiRequest produces an error', ->
+
+ beforeEach ->
+ @apiRequest.callsArgWith(1, new Error('woops'), {statusCode: 500})
+
+ it 'should produce an error', (done) ->
+ @call (err, result) =>
+ expect(err).to.be.instanceof Error
+ done()