diff --git a/***MY README***.md b/***MY README***.md
new file mode 100644
index 0000000..47f1ba1
--- /dev/null
+++ b/***MY README***.md
@@ -0,0 +1,13 @@
+My solution consists an android app as well as a nodejs backend
+
+The `AirtimeRewards` folder contains the android project
+
+The `airtime-rewards-backend` folder contains the nodejs backend
+
+My solution is an app that gives people airtime rewards for answering surveys created by organisations
+
+I'm making use of the following Africa's Talking APIs
+1) Airtime
+2) SMS
+
+Please Enjoy!
\ No newline at end of file
diff --git a/AirtimeRewards/.gitignore b/AirtimeRewards/.gitignore
new file mode 100644
index 0000000..5edb4ee
--- /dev/null
+++ b/AirtimeRewards/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/AirtimeRewards/.idea/assetWizardSettings.xml b/AirtimeRewards/.idea/assetWizardSettings.xml
new file mode 100644
index 0000000..524d57f
--- /dev/null
+++ b/AirtimeRewards/.idea/assetWizardSettings.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/.idea/caches/build_file_checksums.ser b/AirtimeRewards/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..01c7485
Binary files /dev/null and b/AirtimeRewards/.idea/caches/build_file_checksums.ser differ
diff --git a/AirtimeRewards/.idea/codeStyles/Project.xml b/AirtimeRewards/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/AirtimeRewards/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/.idea/dictionaries/michael.xml b/AirtimeRewards/.idea/dictionaries/michael.xml
new file mode 100644
index 0000000..7532c9e
--- /dev/null
+++ b/AirtimeRewards/.idea/dictionaries/michael.xml
@@ -0,0 +1,7 @@
+
+
+
+ firebase
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/.idea/gradle.xml b/AirtimeRewards/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/AirtimeRewards/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/.idea/misc.xml b/AirtimeRewards/.idea/misc.xml
new file mode 100644
index 0000000..c24c0fc
--- /dev/null
+++ b/AirtimeRewards/.idea/misc.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/.idea/runConfigurations.xml b/AirtimeRewards/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/AirtimeRewards/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/.gitignore b/AirtimeRewards/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/AirtimeRewards/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/AirtimeRewards/app/build.gradle b/AirtimeRewards/app/build.gradle
new file mode 100644
index 0000000..a6ada45
--- /dev/null
+++ b/AirtimeRewards/app/build.gradle
@@ -0,0 +1,88 @@
+apply plugin: 'com.android.application'
+
+apply plugin: 'kotlin-android'
+
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 27
+ defaultConfig {
+ applicationId "com.makerloom.airtimerewards"
+ minSdkVersion 16
+ targetSdkVersion 27
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ multiDexEnabled true
+ vectorDrawables.useSupportLibrary = true
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ release {}
+ }
+ dexOptions {
+ jumboMode true
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ sourceSets {
+ main {
+ res.srcDirs = [
+ 'src/main/res',
+ 'src/main/res/menu'
+ ]
+ }
+ }
+}
+
+ext {
+ supportLibVersion = '27.1.1'
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
+
+ // Support Libraries
+ implementation "com.android.support:appcompat-v7:$supportLibVersion"
+ implementation "com.android.support:design:$supportLibVersion"
+ implementation "com.android.support:recyclerview-v7:$supportLibVersion"
+ implementation "com.android.support:support-annotations:$supportLibVersion"
+ implementation "com.android.support:cardview-v7:$supportLibVersion"
+ implementation "com.android.support:support-v4:$supportLibVersion"
+ implementation "com.android.support:support-vector-drawable:$supportLibVersion"
+ implementation 'com.android.support:multidex:1.0.3'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.google.android:flexbox:0.3.2'
+
+ // Firebase & Google Libraries
+ implementation 'com.google.firebase:firebase-core:16.0.4'
+ implementation 'com.google.firebase:firebase-functions:16.1.2'
+ implementation 'com.google.firebase:firebase-firestore:17.1.2'
+ implementation 'com.google.firebase:firebase-auth:16.0.5' // 16.0.1
+ implementation 'com.firebaseui:firebase-ui-auth:4.1.0' // 3.1.2
+
+ // Miscellaneous Libraries
+ implementation 'com.github.medyo:fancybuttons:1.8.4'
+ implementation 'com.karumi:dexter:4.2.0'
+ implementation 'com.stepstone.stepper:material-stepper:4.3.1'
+ implementation 'com.github.bumptech.glide:glide:4.5.0'
+ implementation 'com.google.code.gson:gson:2.8.2'
+ implementation 'com.squareup.retrofit2:retrofit:2.4.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
+
+ // Testing Libraries
+ implementation 'com.android.support:support-v4:27.1.1'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
+
+apply plugin: 'com.google.gms.google-services'
+
+com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
diff --git a/AirtimeRewards/app/google-services.json b/AirtimeRewards/app/google-services.json
new file mode 100644
index 0000000..382904c
--- /dev/null
+++ b/AirtimeRewards/app/google-services.json
@@ -0,0 +1,55 @@
+{
+ "project_info": {
+ "project_number": "724456800518",
+ "firebase_url": "https://airtime-rewards.firebaseio.com",
+ "project_id": "airtime-rewards",
+ "storage_bucket": "airtime-rewards.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:724456800518:android:2c170b2df8c5b0c7",
+ "android_client_info": {
+ "package_name": "com.makerloom.airtimerewards"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "724456800518-12b1mp2ktot47be5v5umd8gi2r4i1pf3.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.makerloom.airtimerewards",
+ "certificate_hash": "7d4d3d266a5fcf4953e8806abe4acc99db9b187c"
+ }
+ },
+ {
+ "client_id": "724456800518-vb1qk675cg9k5mk7ns89l431kor9414h.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyDEYU_e6C9SDwH4GAiZ7Ulj8xXlcSFPmT4"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 2,
+ "other_platform_oauth_client": [
+ {
+ "client_id": "724456800518-vb1qk675cg9k5mk7ns89l431kor9414h.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ },
+ "ads_service": {
+ "status": 2
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/proguard-rules.pro b/AirtimeRewards/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/AirtimeRewards/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/AirtimeRewards/app/src/androidTest/java/com/makerloom/airtimerewards/ExampleInstrumentedTest.kt b/AirtimeRewards/app/src/androidTest/java/com/makerloom/airtimerewards/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..ef56289
--- /dev/null
+++ b/AirtimeRewards/app/src/androidTest/java/com/makerloom/airtimerewards/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.makerloom.airtimerewards
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.runner.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getTargetContext()
+ assertEquals("com.makerloom.airtimerewards", appContext.packageName)
+ }
+}
diff --git a/AirtimeRewards/app/src/main/AndroidManifest.xml b/AirtimeRewards/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..169046b
--- /dev/null
+++ b/AirtimeRewards/app/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/CompleteActivity.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/CompleteActivity.kt
new file mode 100644
index 0000000..b9cae8c
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/CompleteActivity.kt
@@ -0,0 +1,17 @@
+package com.makerloom.airtimerewards
+
+import android.os.Bundle
+import android.support.design.widget.Snackbar
+import android.support.v7.app.AppCompatActivity
+
+import kotlinx.android.synthetic.main.activity_complete.*
+
+class CompleteActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_complete)
+ setSupportActionBar(toolbar)
+ }
+
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MainActivity.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MainActivity.kt
new file mode 100644
index 0000000..da3fb7c
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MainActivity.kt
@@ -0,0 +1,121 @@
+package com.makerloom.airtimerewards
+
+import android.app.ProgressDialog
+import android.content.Intent
+import android.graphics.Typeface
+import android.os.Bundle
+import android.os.Handler
+import android.support.design.widget.Snackbar
+import android.support.v7.app.AppCompatActivity
+import com.google.gson.Gson
+import com.makerloom.airtimerewards.api.API
+import com.makerloom.airtimerewards.api.APIService
+import com.makerloom.airtimerewards.models.Question
+import com.makerloom.airtimerewards.models.RequestSurveyRequest
+import com.makerloom.airtimerewards.models.RequestSurveyResponse
+import com.makerloom.airtimerewards.models.Survey
+import com.makerloom.airtimerewards.utils.JsonUtils
+import com.makerloom.airtimerewards.utils.SnackbarUtils
+
+import kotlinx.android.synthetic.main.activity_main.*
+import kotlinx.android.synthetic.main.content_main.*
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class MainActivity : AppCompatActivity() {
+
+ val searchButtonFontName = "sans-serif-light"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ setSupportActionBar(toolbar)
+
+ look_for_survey_btn.textViewObject.typeface = Typeface.create(searchButtonFontName, Typeface.BOLD_ITALIC)
+ look_for_survey_btn.setOnClickListener {
+ checkForSurveys()
+ }
+ }
+
+ private var progressDialog: ProgressDialog? = null
+
+ fun startSurveyProgress () {
+ progressDialog = ProgressDialog(this@MainActivity)
+
+ progressDialog?.apply {
+ setMessage("Looking For Surveys ...")
+ setCancelable(false)
+ setProgressStyle(ProgressDialog.STYLE_SPINNER)
+ show()
+ }
+ }
+
+ fun stopSurveyProgress () {
+ try {
+ progressDialog?.apply {
+ hide()
+ dismiss()
+ }
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ }
+
+
+ fun checkForSurveys () {
+ startSurveyProgress()
+
+ val surveyRequest = RequestSurveyRequest(true)
+
+ val call: Call = API.Service.requestSurvey(surveyRequest)
+
+ call
+ .enqueue(object : Callback {
+ override fun onFailure(call: Call?, t: Throwable?) {
+ SnackbarUtils.showSnackbar(this@MainActivity, "We were unable to load a survey. Please try again later.")
+ stopSurveyProgress()
+ }
+
+ override fun onResponse(call: Call?, response: Response?) {
+ response?.apply {
+ if (isSuccessful) {
+ loadSurvey(body())
+ }
+ else {
+ SnackbarUtils.showSnackbar(this@MainActivity, "We were unable to load a survey. Please try again later.")
+ }
+ }
+ stopSurveyProgress()
+ }
+ })
+
+// Handler().postDelayed(Runnable {
+// stopSurveyProgress()
+//
+// val gson = Gson()
+// val questions = ArrayList()
+// val dummyQuestionsArray = JsonUtils.loadJsonArrayFromAsset(applicationContext, R.raw.questions)
+// dummyQuestionsArray?.let {
+// for (i in 0 until dummyQuestionsArray.length()) {
+// val qJson = dummyQuestionsArray[i]
+// val question = gson.fromJson(qJson.toString(), Question::class.java)
+// questions.add(question)
+// }
+// val dummyResponse = RequestSurveyResponse(true, Survey(questions))
+// loadSurvey(dummyResponse)
+// }
+// }, 4000)
+ }
+
+ fun loadSurvey (response: RequestSurveyResponse?) {
+ val survey = Intent(this@MainActivity, SurveyActivity::class.java)
+
+ val gson = Gson()
+ survey.putExtra(SurveyActivity.SURVEY_DATA_KEY, gson.toJson(response))
+
+ startActivity(survey)
+ }
+
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MyStepperAdapter.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MyStepperAdapter.kt
new file mode 100644
index 0000000..4f35e6f
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/MyStepperAdapter.kt
@@ -0,0 +1,39 @@
+package com.makerloom.airtimerewards
+
+import android.support.v4.app.FragmentManager
+import android.content.Context
+import android.util.Log
+import com.makerloom.airtimerewards.models.Survey
+import com.stepstone.stepper.Step
+
+import com.stepstone.stepper.adapter.AbstractFragmentStepAdapter
+import com.stepstone.stepper.viewmodel.StepViewModel
+
+class MyStepperAdapter(fragmentManager: FragmentManager, context: Context, survey: Survey) : AbstractFragmentStepAdapter(fragmentManager, context) {
+ private var survey: Survey
+
+ init {
+ this.survey = survey
+ }
+
+ override fun getCount(): Int {
+ return survey.questions.size
+ }
+
+ override fun createStep(position: Int): Step {
+ val questionFragment = SurveyQuestionFragment.newInstance(position, survey.questions.get(position))
+ Log.d(TAG, questionFragment.toString())
+
+ return questionFragment
+ }
+
+ override fun getViewModel(position: Int): StepViewModel {
+ return StepViewModel.Builder(context)
+ .setTitle("Question ${position + 1}")
+ .create()
+ }
+
+ companion object {
+ val TAG = MyStepperAdapter::class.java.simpleName
+ }
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyActivity.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyActivity.kt
new file mode 100644
index 0000000..d562178
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyActivity.kt
@@ -0,0 +1,267 @@
+package com.makerloom.airtimerewards
+
+import android.app.ActionBar
+import android.app.ProgressDialog
+import android.content.DialogInterface
+import android.content.Intent
+import android.net.Uri
+import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+import android.os.Handler
+import android.support.v7.app.AlertDialog
+import android.util.DisplayMetrics
+import android.util.Log
+import android.util.TypedValue
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.widget.EditText
+import android.widget.LinearLayout
+import com.google.gson.Gson
+import com.makerloom.airtimerewards.api.API
+import com.makerloom.airtimerewards.models.*
+import com.makerloom.airtimerewards.utils.DialogUtils
+import com.makerloom.airtimerewards.utils.PhoneUtils
+import com.makerloom.airtimerewards.utils.SnackbarUtils
+import com.makerloom.airtimerewards.utils.SurveyUtils
+import com.makerloom.airtimerewards.utils.SurveyUtils.Companion.buildQuestionView
+import com.stepstone.stepper.StepperLayout
+import com.stepstone.stepper.VerificationError
+import kotlinx.android.synthetic.main.activity_main.*
+import kotlinx.android.synthetic.main.content_survey.*
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class SurveyActivity : AppCompatActivity(), StepperLayout.StepperListener, SurveyQuestionFragment.OnFragmentInteractionListener {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_survey)
+ setSupportActionBar(toolbar)
+ supportActionBar?.apply {
+ setDisplayHomeAsUpEnabled(true)
+ setHomeButtonEnabled(true)
+ }
+
+ val surveyData = intent.getStringExtra(SurveyActivity.SURVEY_DATA_KEY)
+ Log.d(TAG, surveyData)
+
+ val gson = Gson()
+ val response = gson.fromJson(surveyData, RequestSurveyResponse::class.java)
+
+ stepper_layout.adapter = MyStepperAdapter(supportFragmentManager, this@SurveyActivity, response.survey)
+ stepper_layout.setListener(this@SurveyActivity)
+ }
+
+ fun getAmountAndPhoneNumber(post: Runnable) {
+ amount = getAmount()
+
+ val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT)
+
+ val editText = EditText(this@SurveyActivity)
+ editText.apply {
+ setSingleLine(true)
+ setText(DEFAULT_PHONE_NUMBER)
+ setSelection(DEFAULT_PHONE_NUMBER.length)
+ layoutParams = params
+ }
+
+ val layout = LinearLayout(this@SurveyActivity)
+ layout.apply {
+ addView(editText)
+ layoutParams = params
+ setPadding(paddingLeft + 36, paddingTop, paddingRight + 36, paddingBottom)
+ }
+
+ var alertDialog: AlertDialog? = null
+ val alertDialogBuilder = AlertDialog.Builder(this@SurveyActivity)
+ .setTitle("Survey Completed")
+ .setMessage("What phone number do you want your airtime reward sent to?")
+ .setView(layout)
+ .setCancelable(true)
+ .setPositiveButton("Continue", object: DialogInterface.OnClickListener {
+ override fun onClick(dialog: DialogInterface?, which: Int) {
+ val phoneNumber = editText.text.toString()
+ Log.d(TAG,"phoneNumber = $phoneNumber\namount = $amount")
+ if (PhoneUtils.isValid(phoneNumber)) {
+ this@SurveyActivity.phoneNumber = phoneNumber
+ post.run()
+ }
+ else {
+ SnackbarUtils.showSnackbar(this@SurveyActivity, "Please enter a valid phone number")
+ DialogUtils.dismiss(alertDialog)
+ getAmountAndPhoneNumber(post)
+ }
+ }
+ })
+
+ alertDialog = alertDialogBuilder.create()
+ alertDialog.show()
+ }
+
+ private var amount: Int = getAmount()
+
+ private var phoneNumber: String = DEFAULT_PHONE_NUMBER
+
+ override fun onCompleted(completeButton: View?) {
+ getAmountAndPhoneNumber(Runnable {
+ showProgress()
+ sendAirtime(amount, phoneNumber)
+ Handler().postDelayed(Runnable {
+ sendConfirmationText(amount, phoneNumber)
+ }, 500)
+ })
+ }
+
+ fun goToCompleteActivity () {
+ startActivity(Intent(this@SurveyActivity, CompleteActivity::class.java))
+ finish()
+ }
+
+ override fun onError(verificationError: VerificationError?) {
+ Log.d(TAG, "onError $verificationError")
+ }
+
+ override fun onStepSelected(newStepPosition: Int) {
+ Log.d(TAG, "onStepSelected $newStepPosition")
+ }
+
+ override fun onReturn() {
+ Log.d(TAG, "onReturn")
+ finish()
+ }
+
+ override fun onFragmentInteraction(uri: Uri) {
+ Log.d(TAG, "onFragmentInteraction $uri")
+ }
+
+ var airtimeRequestComplete = false
+ fun sendAirtime ( amount: Int, phoneNumber: String) {
+ airtimeRequestComplete = false
+ val request = SendAirtimeRequest(true, amount, phoneNumber = phoneNumber, to = phoneNumber)
+
+ val call = API.Service.sendAirtime(request)
+ call.enqueue(object : Callback {
+ override fun onFailure(call: Call?, t: Throwable?) {
+ Log.d(TAG, "onFailure Airtime")
+ SnackbarUtils.showSnackbar(this@SurveyActivity, "An error occured while submitting the survey, Please try again later")
+ complete()
+ }
+
+ override fun onResponse(call: Call?, response: Response?) {
+ complete()
+ Log.d(TAG, "onResponse Airtime")
+ Log.d(TAG, response?.toString())
+ response?.apply {
+ Log.d(TAG, response.body().toString())
+ if (isSuccessful && isSuccessful(response.body())) {
+ Log.d(TAG, "Send Airtime Success")
+ goToCompleteActivity()
+ }
+ else {
+ SnackbarUtils.showSnackbar(this@SurveyActivity, "An error occured while submitting the survey, Please try again later")
+ }
+ }
+ }
+
+ fun complete () {
+ airtimeRequestComplete = true
+ hideProgress()
+ }
+ })
+ }
+
+ var textRequestComplete = false
+ fun sendConfirmationText (amount: Int, phoneNumber: String) {
+ textRequestComplete = false
+ val request = SendTextRequest(true, amount, to = phoneNumber, phoneNumber = phoneNumber)
+
+ val call = API.Service.sendText(request)
+ call.enqueue(object : Callback {
+ override fun onFailure(call: Call?, t: Throwable?) {
+ Log.d(TAG, "onFailure Text")
+ SnackbarUtils.showSnackbar(this@SurveyActivity, "An error occured while submitting the survey, Please try again later")
+ complete()
+ }
+
+ override fun onResponse(call: Call?, response: Response?) {
+ complete()
+ Log.d(TAG, "onResponse Text")
+ Log.d(TAG, response?.toString())
+ response?.apply {
+ Log.d(TAG, response.body().toString())
+ if (!isSuccessful || !isSuccessful(response.body())) {
+ SnackbarUtils.showSnackbar(this@SurveyActivity, "An error occured while submitting the survey, Please try again later")
+ }
+ else {
+ Log.d(TAG, "Send Text Success")
+ }
+ }
+ }
+
+ fun complete () {
+ textRequestComplete = true
+ hideProgress()
+ }
+ })
+ }
+
+ fun isSuccessful (response: SendAirtimeResponse?): Boolean {
+ return response != null && response.success
+ }
+
+ fun isSuccessful (response: SendTextResponse?): Boolean {
+ return response != null && response.success
+ }
+
+ fun bothRequestsComplete (): Boolean {
+ return textRequestComplete && airtimeRequestComplete
+ }
+
+ private var progressDialog: ProgressDialog? = null
+
+ fun hideProgress () {
+ if (bothRequestsComplete()) {
+ try {
+ progressDialog?.apply {
+ hide()
+ dismiss()
+ }
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ }
+ }
+
+ fun showProgress () {
+ progressDialog = ProgressDialog(this@SurveyActivity)
+ progressDialog?.apply {
+ setMessage("Submitting Survey Answers & Processing Airtime Reward ...")
+ setCancelable(false)
+ setProgressStyle(ProgressDialog.STYLE_SPINNER)
+ show()
+ }
+ }
+
+ companion object {
+ val SURVEY_DATA_KEY = "SURVEY_DATA"
+
+ val TAG = SurveyActivity::class.java.simpleName
+
+ val DEFAULT_PHONE_NUMBER = "+2349034099658"
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+ if (item?.itemId == android.R.id.home) {
+ onBackPressed()
+ return true
+ }
+
+ return super.onOptionsItemSelected(item)
+ }
+
+ fun getAmount(): Int {
+ return 50
+ }
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyQuestionFragment.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyQuestionFragment.kt
new file mode 100644
index 0000000..7660626
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/SurveyQuestionFragment.kt
@@ -0,0 +1,104 @@
+package com.makerloom.airtimerewards
+
+import android.content.Context
+import android.net.Uri
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v7.app.AppCompatActivity
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.google.gson.Gson
+import com.makerloom.airtimerewards.models.Question
+import com.makerloom.airtimerewards.utils.SurveyUtils
+import com.stepstone.stepper.Step
+import com.stepstone.stepper.VerificationError
+import java.text.FieldPosition
+
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val POSITION_KEY = "param1"
+private const val QUESTION_KEY = "param2"
+
+class SurveyQuestionFragment : Fragment(), Step {
+ // TODO: Rename and change types of parameters
+ private var position: Int? = null
+ private var question: Question? = null
+ private var listener: OnFragmentInteractionListener? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ arguments?.let {
+ position = it.getInt(POSITION_KEY)
+
+ val gson = Gson()
+ question = gson.fromJson(it.getString(QUESTION_KEY), Question::class.java)
+ }
+ }
+
+ override fun verifyStep(): VerificationError? {
+ Log.d(TAG, "verifyStep")
+ return null
+ }
+
+ override fun onError(error: VerificationError) {
+ Log.d(TAG, "onError")
+ }
+
+ override fun onSelected() {
+ Log.d(TAG, "onSelected")
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+ val view = inflater.inflate(R.layout.fragment_survey_question, container, false)
+
+ (view as ViewGroup).addView(SurveyUtils.buildQuestionView(activity as AppCompatActivity,
+ question!!))
+
+ return view
+ }
+
+ // TODO: Rename method, update argument and hook method into UI event
+ fun onButtonPressed(uri: Uri) {
+ listener?.onFragmentInteraction(uri)
+ }
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ if (context is OnFragmentInteractionListener) {
+ listener = context
+ } else {
+ throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
+ }
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ listener = null
+ }
+
+ interface OnFragmentInteractionListener {
+ // TODO: Update argument type and name
+ fun onFragmentInteraction(uri: Uri)
+ }
+
+ companion object {
+ val TAG = SurveyQuestionFragment::class.java.simpleName
+
+ // TODO: Rename and change types and number of parameters
+ @JvmStatic
+ fun newInstance(position: Int, question: Question) =
+ SurveyQuestionFragment().apply {
+ arguments = Bundle().apply {
+ putInt(POSITION_KEY, position)
+
+ val gson = Gson()
+ putString(QUESTION_KEY, gson.toJson(question))
+ }
+ }
+ }
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/API.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/API.kt
new file mode 100644
index 0000000..9b79990
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/API.kt
@@ -0,0 +1,66 @@
+package com.makerloom.airtimerewards.api
+
+import android.util.Log
+
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+
+import okhttp3.OkHttpClient
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+object API {
+ private val DEFAULT_TIMEOUT_IN_SECONDS = 30
+
+ private val DEBUG = !true
+
+ private val TAG = API::class.java.simpleName
+
+ private val PROTOCOL = "http"
+ private val DEBUG_IP_ADDR = "192.168.43.121"
+ private val DEBUG_DOMAIN = "$DEBUG_IP_ADDR:3000"
+ private val PRODUCTION_DOMAIN = "airtime-rewards-backend.herokuapp.com"
+ private val DEBUG_BASE_URL = String.format(Locale.getDefault(), "%s://%s", PROTOCOL, DEBUG_DOMAIN)
+ private val PRODUCTION_BASE_URL = String.format(Locale.getDefault(), "%s://%s", PROTOCOL, PRODUCTION_DOMAIN)
+ private val ROUTE = "/api/"
+
+ val baseUrl: String
+ get() {
+ val url: String
+ if (DEBUG) {
+ url = DEBUG_BASE_URL
+ } else {
+ url = PRODUCTION_BASE_URL
+ }
+
+ Log.d(TAG, url)
+ return url
+ }
+
+ val url: String
+ get() {
+ val url: String
+ if (DEBUG) {
+ url = DEBUG_BASE_URL + ROUTE
+ } else {
+ url = PRODUCTION_BASE_URL + ROUTE
+ }
+
+ Log.d(TAG, url)
+ return url
+ }
+
+ private val okHttpClient = OkHttpClient.Builder()
+ .connectTimeout(DEFAULT_TIMEOUT_IN_SECONDS.toLong(), TimeUnit.SECONDS)
+ .writeTimeout(DEFAULT_TIMEOUT_IN_SECONDS.toLong(), TimeUnit.SECONDS)
+ .readTimeout(DEFAULT_TIMEOUT_IN_SECONDS.toLong(), TimeUnit.SECONDS)
+ .build()
+
+ private val retrofit = Retrofit.Builder()
+ .baseUrl(url)
+ .addConverterFactory(GsonConverterFactory.create())
+ .client(okHttpClient)
+ .build()
+
+ val Service = retrofit.create(APIService::class.java)
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/APIService.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/APIService.kt
new file mode 100644
index 0000000..d0e35b9
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/api/APIService.kt
@@ -0,0 +1,23 @@
+package com.makerloom.airtimerewards.api
+
+import com.makerloom.airtimerewards.models.RequestSurveyRequest
+import com.makerloom.airtimerewards.models.RequestSurveyResponse
+import com.makerloom.airtimerewards.models.SendAirtimeRequest
+import com.makerloom.airtimerewards.models.SendAirtimeResponse
+import com.makerloom.airtimerewards.models.SendTextRequest
+import com.makerloom.airtimerewards.models.SendTextResponse
+
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+interface APIService {
+ @POST("sendAirtime")
+ fun sendAirtime(@Body request: SendAirtimeRequest): Call
+
+ @POST("sendText")
+ fun sendText(@Body request: SendTextRequest): Call
+
+ @POST("requestSurvey")
+ fun requestSurvey(@Body request: RequestSurveyRequest): Call
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Question.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Question.kt
new file mode 100644
index 0000000..53209d0
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Question.kt
@@ -0,0 +1,10 @@
+package com.makerloom.airtimerewards.models
+
+data class Question (val questionText: String,
+ val imageUrl: String? = null,
+
+ val inputType: Boolean? = false,
+ val radioButtonType: Boolean? = false,
+ val checkBoxType: Boolean? = false,
+
+ val options: ArrayList? = null)
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Request.java b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Request.java
new file mode 100644
index 0000000..8318569
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Request.java
@@ -0,0 +1,5 @@
+package com.makerloom.airtimerewards.models;
+
+public class Request {
+ Request () {}
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyRequest.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyRequest.kt
new file mode 100644
index 0000000..2f35d4c
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyRequest.kt
@@ -0,0 +1,3 @@
+package com.makerloom.airtimerewards.models
+
+data class RequestSurveyRequest (val success: Boolean) : Request()
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyResponse.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyResponse.kt
new file mode 100644
index 0000000..36fef21
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/RequestSurveyResponse.kt
@@ -0,0 +1,4 @@
+package com.makerloom.airtimerewards.models
+
+data class RequestSurveyResponse (val success: Boolean,
+ val survey: Survey) : Response()
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Response.java b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Response.java
new file mode 100644
index 0000000..59e38ee
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Response.java
@@ -0,0 +1,5 @@
+package com.makerloom.airtimerewards.models;
+
+public class Response {
+ Response () {}
+}
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeRequest.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeRequest.kt
new file mode 100644
index 0000000..b7d9fb7
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeRequest.kt
@@ -0,0 +1,6 @@
+package com.makerloom.airtimerewards.models
+
+data class SendAirtimeRequest(val success: Boolean,
+ val amount: Int,
+ val phoneNumber: String,
+ val to: String) : Request()
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeResponse.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeResponse.kt
new file mode 100644
index 0000000..437d7a0
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendAirtimeResponse.kt
@@ -0,0 +1,5 @@
+package com.makerloom.airtimerewards.models
+
+data class SendAirtimeResponse(val success: Boolean,
+ val amount: Int,
+ val phoneNumber: String): Response()
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextRequest.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextRequest.kt
new file mode 100644
index 0000000..3f796e1
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextRequest.kt
@@ -0,0 +1,6 @@
+package com.makerloom.airtimerewards.models
+
+data class SendTextRequest(val success: Boolean,
+ val amount: Int,
+ val to: String,
+ val phoneNumber: String) : Request()
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextResponse.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextResponse.kt
new file mode 100644
index 0000000..1193711
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/SendTextResponse.kt
@@ -0,0 +1,5 @@
+package com.makerloom.airtimerewards.models
+
+data class SendTextResponse (val success: Boolean,
+ val amount: Int,
+ val to: String) : Response()
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Survey.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Survey.kt
new file mode 100644
index 0000000..69dd918
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/models/Survey.kt
@@ -0,0 +1,3 @@
+package com.makerloom.airtimerewards.models
+
+data class Survey (val questions: ArrayList)
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/DialogUtils.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/DialogUtils.kt
new file mode 100644
index 0000000..1660ca3
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/DialogUtils.kt
@@ -0,0 +1,16 @@
+package com.makerloom.airtimerewards.utils
+
+import android.support.v7.app.AlertDialog
+
+class DialogUtils {
+ companion object {
+ fun dismiss (alertDialog: AlertDialog?) {
+ try {
+ alertDialog?.dismiss()
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/JsonUtils.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/JsonUtils.kt
new file mode 100644
index 0000000..82b4b7a
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/JsonUtils.kt
@@ -0,0 +1,54 @@
+package com.makerloom.airtimerewards.utils
+
+import android.content.Context
+import org.json.JSONArray
+import org.json.JSONObject
+
+
+
+class JsonUtils {
+ companion object {
+ fun loadJsonStringFromAsset(context: Context, resId: Int): String? {
+ var jsonString: String? = null
+
+ try {
+ val `is` = context.getResources().openRawResource(resId)
+ val size = `is`.available()
+ val buffer = ByteArray(size)
+ `is`.read(buffer)
+ `is`.close()
+ jsonString = String(buffer, Charsets.UTF_8)
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ return null
+ }
+
+ return jsonString
+ }
+
+ fun loadJsonFromAsset(context: Context, resId: Int): JSONObject? {
+ try {
+ val jsonString = loadJsonStringFromAsset(context, resId)
+ return JSONObject(jsonString)
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ return null
+ }
+
+ }
+
+ fun loadJsonArrayFromAsset(context: Context, resId: Int): JSONArray? {
+ try {
+ val jsonString = loadJsonStringFromAsset(context, resId)
+ return JSONArray(jsonString)
+ }
+ catch (ex: Exception) {
+ ex.printStackTrace()
+ return null
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/PhoneUtils.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/PhoneUtils.kt
new file mode 100644
index 0000000..726a73f
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/PhoneUtils.kt
@@ -0,0 +1,91 @@
+package com.makerloom.airtimerewards.utils
+
+import java.util.ArrayList
+import java.util.Arrays
+
+class PhoneUtils {
+ companion object {
+ internal val INVALID_NUMBER: Int? = -1
+
+ internal val MTN_NUMBER = 0
+ internal val GLO_NUMBER = 1
+ internal val AIRTEL_NUMBER = 2
+ internal val ETISALAT_NUMBER = 3
+
+ internal val allNumberPrefixes: List
+ get() {
+ val allNumberPrefixes = ArrayList()
+
+ allNumberPrefixes.addAll(Arrays.asList(*MTN.numberPrefixes))
+ allNumberPrefixes.addAll(Arrays.asList(*GLO.numberPrefixes))
+ allNumberPrefixes.addAll(Arrays.asList(*Airtel.numberPrefixes))
+ allNumberPrefixes.addAll(Arrays.asList(*Etisalat.numberPrefixes))
+
+ return allNumberPrefixes
+ }
+
+ internal var ALL_NUMBER_PREFIXES = allNumberPrefixes
+
+ internal val MIN_PHONE_NO_LEN = 11
+ internal val MAX_PHONE_NO_LEN = 14
+
+ internal var NIGERIA_CODE = "+234"
+
+ fun isValid(phoneNumber: String): Boolean {
+ val len = phoneNumber.length
+
+ for (numberPrefix in ALL_NUMBER_PREFIXES) {
+ if (phoneNumber.startsWith(numberPrefix) && (len == MIN_PHONE_NO_LEN && !phoneNumber.startsWith("+234") || len == MAX_PHONE_NO_LEN && !phoneNumber.startsWith("0"))) {
+ return true
+ }
+ }
+
+ return false
+ }
+
+ internal fun getType(phoneNumber: String): Int {
+ // MTN
+ for (numberPrefix in MTN.numberPrefixes) {
+ if (phoneNumber.startsWith(numberPrefix)) {
+ return MTN_NUMBER
+ }
+ }
+ // GLO
+ for (numberPrefix in GLO.numberPrefixes) {
+ if (phoneNumber.startsWith(numberPrefix)) {
+ return GLO_NUMBER
+ }
+ }
+ // Airtel
+ for (numberPrefix in Airtel.numberPrefixes) {
+ if (phoneNumber.startsWith(numberPrefix)) {
+ return AIRTEL_NUMBER
+ }
+ }
+ // Etisalat
+ for (numberPrefix in Etisalat.numberPrefixes) {
+ if (phoneNumber.startsWith(numberPrefix)) {
+ return ETISALAT_NUMBER
+ }
+ }
+
+ return INVALID_NUMBER!!
+ }
+
+ internal object MTN {
+ var numberPrefixes = arrayOf("+234703", "+234706", "+234803", "+234806", "+234810", "+234813", "+234814", "+234816", "+234903", "+234906", "0703", "0706", "0803", "0806", "0810", "0813", "0814", "0816", "0903", "0906")
+ }
+
+ internal object GLO {
+ var numberPrefixes = arrayOf("+234705", "+234805", "+234807", "+234811", "+234815", "+234905", "0705", "0805", "0807", "0811", "0815", "0905")
+ }
+
+ internal object Airtel {
+ var numberPrefixes = arrayOf("+234701", "+234708", "+234802", "+234808", "+234812", "+234902", "+234907", "0701", "0708", "0802", "0808", "0812", "0902", "0907")
+ }
+
+ internal object Etisalat {
+ var numberPrefixes = arrayOf("+234809", "+234817", "+234818", "+234908", "+234909", "0809", "0817", "0818", "0908", "0909")
+ }
+ }
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SnackbarUtils.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SnackbarUtils.kt
new file mode 100644
index 0000000..6af5b52
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SnackbarUtils.kt
@@ -0,0 +1,14 @@
+package com.makerloom.airtimerewards.utils
+
+import android.content.Context
+import android.support.design.widget.Snackbar
+import android.support.v7.app.AppCompatActivity
+
+class SnackbarUtils {
+ companion object {
+ fun showSnackbar (activity: AppCompatActivity, message: String) {
+ Snackbar.make(activity.findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG)
+ .show()
+ }
+ }
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SurveyUtils.kt b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SurveyUtils.kt
new file mode 100644
index 0000000..c1f37d5
--- /dev/null
+++ b/AirtimeRewards/app/src/main/java/com/makerloom/airtimerewards/utils/SurveyUtils.kt
@@ -0,0 +1,105 @@
+package com.makerloom.airtimerewards.utils
+
+import android.content.Context
+import android.graphics.Typeface
+import android.support.v4.content.ContextCompat
+import android.util.TypedValue
+import android.view.Gravity
+import android.view.View
+import android.widget.*
+import android.widget.LinearLayout.HORIZONTAL
+import android.widget.LinearLayout.VERTICAL
+import com.makerloom.airtimerewards.R
+import com.makerloom.airtimerewards.models.Question
+
+class SurveyUtils {
+ companion object {
+ fun buildQuestionView (context: Context, question: Question): View {
+ val layout = LinearLayout(context)
+ layout.orientation = LinearLayout.VERTICAL
+
+ layout.addView(buildQuestionTextView(context, question))
+
+ if (question.checkBoxType != null && question.checkBoxType) {
+ layout.addView(buildCheckBoxesView(context, question))
+ }
+ else if (question.radioButtonType != null && question.radioButtonType) {
+ layout.addView(buildRadioButtonsView(context, question))
+ }
+ else {
+ layout.addView(buildEditTextView(context, question))
+ }
+
+ return layout
+ }
+
+ private fun buildRadioButtonsView (context: Context, question: Question): View {
+ val radioGroup = RadioGroup(context)
+ radioGroup.orientation = LinearLayout.VERTICAL
+
+ question.options?.forEach {
+ val radioButton = RadioButton(context)
+
+ radioButton.apply {
+ text = it
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 16.5f)
+ typeface = Typeface.DEFAULT
+ setTextColor(ContextCompat.getColor(context, R.color.material_grey_600))
+ }
+
+ radioGroup.addView(radioButton)
+ }
+
+ return radioGroup
+ }
+
+ private fun buildCheckBoxesView (context: Context, question: Question): View {
+ val layout = LinearLayout(context)
+ layout.orientation = LinearLayout.VERTICAL
+
+ question.options?.forEach {
+ val checkBox = CheckBox(context)
+
+ checkBox.apply {
+ text = it
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 16.5f)
+ typeface = Typeface.DEFAULT
+ setTextColor(ContextCompat.getColor(context, R.color.material_grey_600))
+ }
+
+ layout.addView(checkBox)
+ }
+
+ return layout
+ }
+
+ private fun buildEditTextView (context: Context, question: Question): View {
+ val editText = EditText(context)
+
+ editText.apply {
+ hint = ""
+ setSingleLine(true)
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 16.5f)
+ typeface = Typeface.DEFAULT
+ setTextColor(ContextCompat.getColor(context, R.color.material_grey_600))
+ }
+
+ return editText
+ }
+
+ private fun buildQuestionTextView (context: Context, question: Question): View {
+ val textView = TextView(context)
+
+ textView.apply {
+ text = question.questionText
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 17.0f)
+ typeface = Typeface.create("sans-serif-light", Typeface.BOLD)
+ setTextColor(ContextCompat.getColor(context, R.color.material_grey_800))
+ setPadding(paddingLeft + 12, paddingTop + 32, paddingRight, paddingBottom + 24)
+ }
+
+ return textView
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/AirtimeRewards/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c7bd21d
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AirtimeRewards/app/src/main/res/drawable/ic_complete.xml b/AirtimeRewards/app/src/main/res/drawable/ic_complete.xml
new file mode 100644
index 0000000..8619d39
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/drawable/ic_complete.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/AirtimeRewards/app/src/main/res/drawable/ic_launcher_background.xml b/AirtimeRewards/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..d5fccc5
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AirtimeRewards/app/src/main/res/layout/activity_complete.xml b/AirtimeRewards/app/src/main/res/layout/activity_complete.xml
new file mode 100644
index 0000000..901d2de
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/activity_complete.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/activity_main.xml b/AirtimeRewards/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..f787496
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/activity_survey.xml b/AirtimeRewards/app/src/main/res/layout/activity_survey.xml
new file mode 100644
index 0000000..6f1393a
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/activity_survey.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/content_complete.xml b/AirtimeRewards/app/src/main/res/layout/content_complete.xml
new file mode 100644
index 0000000..6a7f80a
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/content_complete.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/content_main.xml b/AirtimeRewards/app/src/main/res/layout/content_main.xml
new file mode 100644
index 0000000..61df34d
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/content_main.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/content_survey.xml b/AirtimeRewards/app/src/main/res/layout/content_survey.xml
new file mode 100644
index 0000000..2574afa
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/content_survey.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/layout/fragment_survey_question.xml b/AirtimeRewards/app/src/main/res/layout/fragment_survey_question.xml
new file mode 100644
index 0000000..205e0f5
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/layout/fragment_survey_question.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher.png b/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher.png b/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
Binary files /dev/null and b/AirtimeRewards/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/AirtimeRewards/app/src/main/res/raw/questions.json b/AirtimeRewards/app/src/main/res/raw/questions.json
new file mode 100644
index 0000000..2423057
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/raw/questions.json
@@ -0,0 +1,58 @@
+[
+ {
+ "questionText": "What age bracket do you belong to?",
+ "radioButtonType": true,
+ "options": [
+ "Below 18",
+ "18-25",
+ "26-30",
+ "31-40",
+ "41-50",
+ "Above 50"
+ ]
+ },
+ {
+ "questionText": "What is your favourite instant noodles product?",
+ "radioButtonType": true,
+ "options": [
+ "Indomie Noodles",
+ "Mi Mi Noodles",
+ "Dangote Noodles",
+ "Other"
+ ]
+ },
+ {
+ "questionText": "What is your party of choice in the upcoming elections?",
+ "radioButtonType": true,
+ "options": [
+ "PDP",
+ "APC",
+ "SDP",
+ "Other"
+ ]
+ },
+ {
+ "questionText": "Who is your candidate of choice in the upcoming elections?",
+ "radioButtonType": true,
+ "options": [
+ "Donald Duke",
+ "Atiku Abubakar",
+ "Mohammadu Buhari",
+ "Other"
+ ]
+ },
+ {
+ "questionText": "What is your favourite car brand?",
+ "inputType": true
+ },
+ {
+ "questionText": "Which transport means would you use when travelling across geopolitical zones?",
+ "checkBoxType": true,
+ "options": [
+ "Train",
+ "Public Vehicle",
+ "Private Vehicle",
+ "Plane"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/values/colors.xml b/AirtimeRewards/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..516bf70
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ @color/md_blue_600
+ @color/md_blue_700
+ @color/md_blue_200
+
diff --git a/AirtimeRewards/app/src/main/res/values/colors_material.xml b/AirtimeRewards/app/src/main/res/values/colors_material.xml
new file mode 100644
index 0000000..f802c39
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/values/colors_material.xml
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+ @color/md_grey_50
+
+ #1F000000
+
+ #61000000
+
+ #8A000000
+ #8A000000
+
+ #DE000000
+
+ @color/md_grey_300
+ @color/md_grey_100
+ @color/md_white_1000
+ @color/md_white_1000
+
+
+ @color/md_grey_850
+
+ #1FFFFFFF
+
+ #4DFFFFFF
+
+ #B3FFFFFF
+ #B3FFFFFF
+
+ #FFFFFFFF
+
+ @color/md_black_1000
+ @color/md_grey_900
+ @color/md_grey_800
+ @color/md_grey_800
+
+
+ #FFEBEE
+ #FFCDD2
+ #EF9A9A
+ #E57373
+ #EF5350
+ #F44336
+ #E53935
+ #D32F2F
+ #C62828
+ #B71C1C
+ #FF8A80
+ #FF5252
+ #FF1744
+ #D50000
+
+
+ #FCE4EC
+ #F8BBD0
+ #F48FB1
+ #F06292
+ #EC407A
+ #E91E63
+ #D81B60
+ #C2185B
+ #AD1457
+ #880E4F
+ #FF80AB
+ #FF4081
+ #F50057
+ #C51162
+
+
+ #F3E5F5
+ #E1BEE7
+ #CE93D8
+ #BA68C8
+ #AB47BC
+ #9C27B0
+ #8E24AA
+ #7B1FA2
+ #6A1B9A
+ #4A148C
+ #EA80FC
+ #E040FB
+ #D500F9
+ #AA00FF
+
+
+ #EDE7F6
+ #D1C4E9
+ #B39DDB
+ #9575CD
+ #7E57C2
+ #673AB7
+ #5E35B1
+ #512DA8
+ #4527A0
+ #311B92
+ #B388FF
+ #7C4DFF
+ #651FFF
+ #6200EA
+
+
+ #E8EAF6
+ #C5CAE9
+ #9FA8DA
+ #7986CB
+ #5C6BC0
+ #3F51B5
+ #3949AB
+ #303F9F
+ #283593
+ #1A237E
+ #8C9EFF
+ #536DFE
+ #3D5AFE
+ #304FFE
+
+
+ #E3F2FD
+ #BBDEFB
+ #90CAF9
+ #64B5F6
+ #42A5F5
+ #2196F3
+ #1E88E5
+ #1976D2
+ #1565C0
+ #0D47A1
+ #82B1FF
+ #448AFF
+ #2979FF
+ #2962FF
+
+
+ #E1F5FE
+ #B3E5FC
+ #81D4FA
+ #4FC3F7
+ #29B6F6
+ #03A9F4
+ #039BE5
+ #0288D1
+ #0277BD
+ #01579B
+ #80D8FF
+ #40C4FF
+ #00B0FF
+ #0091EA
+
+
+ #E0F7FA
+ #B2EBF2
+ #80DEEA
+ #4DD0E1
+ #26C6DA
+ #00BCD4
+ #00ACC1
+ #0097A7
+ #00838F
+ #006064
+ #84FFFF
+ #18FFFF
+ #00E5FF
+ #00B8D4
+
+
+ #E0F2F1
+ #B2DFDB
+ #80CBC4
+ #4DB6AC
+ #26A69A
+ #009688
+ #00897B
+ #00796B
+ #00695C
+ #004D40
+ #A7FFEB
+ #64FFDA
+ #1DE9B6
+ #00BFA5
+
+
+ #E8F5E9
+ #C8E6C9
+ #A5D6A7
+ #81C784
+ #66BB6A
+ #4CAF50
+ #43A047
+ #388E3C
+ #2E7D32
+ #1B5E20
+ #B9F6CA
+ #69F0AE
+ #00E676
+ #00C853
+
+
+ #F1F8E9
+ #DCEDC8
+ #C5E1A5
+ #AED581
+ #9CCC65
+ #8BC34A
+ #7CB342
+ #689F38
+ #558B2F
+ #33691E
+ #CCFF90
+ #B2FF59
+ #76FF03
+ #64DD17
+
+
+ #F9FBE7
+ #F0F4C3
+ #E6EE9C
+ #DCE775
+ #D4E157
+ #CDDC39
+ #C0CA33
+ #AFB42B
+ #9E9D24
+ #827717
+ #F4FF81
+ #EEFF41
+ #C6FF00
+ #AEEA00
+
+
+ #FFFDE7
+ #FFF9C4
+ #FFF59D
+ #FFF176
+ #FFEE58
+ #FFEB3B
+ #FDD835
+ #FBC02D
+ #F9A825
+ #F57F17
+ #FFFF8D
+ #FFFF00
+ #FFEA00
+ #FFD600
+
+
+ #FFF8E1
+ #FFECB3
+ #FFE082
+ #FFD54F
+ #FFCA28
+ #FFC107
+ #FFB300
+ #FFA000
+ #FF8F00
+ #FF6F00
+ #FFE57F
+ #FFD740
+ #FFC400
+ #FFAB00
+
+
+ #FFF3E0
+ #FFE0B2
+ #FFCC80
+ #FFB74D
+ #FFA726
+ #FF9800
+ #FB8C00
+ #F57C00
+ #EF6C00
+ #E65100
+ #FFD180
+ #FFAB40
+ #FF9100
+ #FF6D00
+
+
+ #FBE9E7
+ #FFCCBC
+ #FFAB91
+ #FF8A65
+ #FF7043
+ #FF5722
+ #F4511E
+ #E64A19
+ #D84315
+ #BF360C
+ #FF9E80
+ #FF6E40
+ #FF3D00
+ #DD2C00
+
+
+ #EFEBE9
+ #D7CCC8
+ #BCAAA4
+ #A1887F
+ #8D6E63
+ #795548
+ #6D4C41
+ #5D4037
+ #4E342E
+ #3E2723
+
+
+ #FAFAFA
+ #F5F5F5
+ #EEEEEE
+ #E0E0E0
+ #BDBDBD
+ #9E9E9E
+ #757575
+ #616161
+ #424242
+ #303030
+ #212121
+
+
+ #ECEFF1
+ #CFD8DC
+ #B0BEC5
+ #90A4AE
+ #78909C
+ #607D8B
+ #546E7A
+ #455A64
+ #37474F
+ #263238
+
+
+ #000000
+ #FFFFFF
+
+
\ No newline at end of file
diff --git a/AirtimeRewards/app/src/main/res/values/dimens.xml b/AirtimeRewards/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..59a0b0c
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/values/dimens.xml
@@ -0,0 +1,3 @@
+
+ 16dp
+
diff --git a/AirtimeRewards/app/src/main/res/values/strings.xml b/AirtimeRewards/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e66de11
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/values/strings.xml
@@ -0,0 +1,9 @@
+
+ Airtime Rewards
+ @string/app_name
+ Survey
+
+
+ Hello blank fragment
+ @string/app_name
+
diff --git a/AirtimeRewards/app/src/main/res/values/styles.xml b/AirtimeRewards/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..545b9c6
--- /dev/null
+++ b/AirtimeRewards/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AirtimeRewards/app/src/test/java/com/makerloom/airtimerewards/ExampleUnitTest.kt b/AirtimeRewards/app/src/test/java/com/makerloom/airtimerewards/ExampleUnitTest.kt
new file mode 100644
index 0000000..60becc2
--- /dev/null
+++ b/AirtimeRewards/app/src/test/java/com/makerloom/airtimerewards/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.makerloom.airtimerewards
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/AirtimeRewards/build.gradle b/AirtimeRewards/build.gradle
new file mode 100644
index 0000000..28d7446
--- /dev/null
+++ b/AirtimeRewards/build.gradle
@@ -0,0 +1,35 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.2.30'
+ repositories {
+ jcenter()
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.google.gms:google-services:4.1.0'
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ google()
+ mavenLocal()
+ mavenCentral()
+ maven {
+ url "https://jitpack.io"
+ }
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/AirtimeRewards/gradle.properties b/AirtimeRewards/gradle.properties
new file mode 100644
index 0000000..743d692
--- /dev/null
+++ b/AirtimeRewards/gradle.properties
@@ -0,0 +1,13 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/AirtimeRewards/gradle/wrapper/gradle-wrapper.jar b/AirtimeRewards/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
Binary files /dev/null and b/AirtimeRewards/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/AirtimeRewards/gradle/wrapper/gradle-wrapper.properties b/AirtimeRewards/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..6153b4f
--- /dev/null
+++ b/AirtimeRewards/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Oct 27 16:48:53 WAT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/AirtimeRewards/gradlew b/AirtimeRewards/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/AirtimeRewards/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/AirtimeRewards/gradlew.bat b/AirtimeRewards/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/AirtimeRewards/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/AirtimeRewards/settings.gradle b/AirtimeRewards/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/AirtimeRewards/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/airtime-rewards-backend/.gitignore b/airtime-rewards-backend/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/airtime-rewards-backend/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/airtime-rewards-backend/README.md b/airtime-rewards-backend/README.md
new file mode 100644
index 0000000..1d5c2f9
--- /dev/null
+++ b/airtime-rewards-backend/README.md
@@ -0,0 +1 @@
+# Airtime Rewards Backend Server
diff --git a/airtime-rewards-backend/app.js b/airtime-rewards-backend/app.js
new file mode 100644
index 0000000..4944e43
--- /dev/null
+++ b/airtime-rewards-backend/app.js
@@ -0,0 +1,65 @@
+'use strict'
+
+let path = require('path')
+let express = require('express')
+let stylus = require('stylus')
+let nib = require('nib')
+let bodyParser = require('body-parser')
+let favicon = require('serve-favicon')
+let multer = require('multer')
+let ms = require('ms')
+let compression = require('compression')
+let uuid = require('uuid')
+
+let routes = require('./app/routes')
+let api = require('./app/api')
+
+let app = express()
+
+app.set('homedir', __dirname)
+app.set('port', process.env.PORT || 3000)
+app.set('host', process.env.HOST || 'localhost')
+app.set('views', __dirname + '/public/views/pug')
+app.set('view engine', 'pug')
+app.set('projectName', 'Airtime Rewards')
+app.locals['companyName'] = 'Makerloom Software Ltd.'
+app.locals.year = new Date().getFullYear()
+app.locals.designerPerson = 'Michael Ogezi'
+app.locals.designerPersonSite = 'https://makerloom.com'
+
+app.use(compression())
+app.use(express.static(path.join(__dirname + '/public'), {
+ maxAge: process.env.NODE_ENV == 'production' ? ms('1 day') : ms('0')
+}))
+app.use(bodyParser.json())
+app.use(bodyParser.urlencoded({
+ extended: true
+}))
+app.use((req, res, next) => {
+ console.log(req.path)
+ next()
+})
+
+// Constants
+const _API = 'api'
+const _SEND_TEXT = 'sendText'
+const _SEND_AIRTIME = 'sendAirtime'
+const _SEND_DATA = 'sendData'
+const _REQUEST_SURVEY = 'requestSurvey'
+
+// Home page
+app.get('/', routes.index)
+
+// API routes
+app.post(`/${_API}/${_SEND_TEXT}`, api.sendText)
+
+app.post(`/${_API}/${_REQUEST_SURVEY}`, api.requestSurvey)
+
+app.post(`/${_API}/${_SEND_DATA}`, api.sendData)
+app.post(`/${_API}/${_SEND_AIRTIME}`, api.sendAirtime)
+
+app.locals.pretty = true
+
+app.listen(app.get('port'), () => {
+ console.log(`Listening on ${app.get('host')}:${app.get('port')} in ${process.env.NODE_ENV} mode`)
+})
\ No newline at end of file
diff --git a/airtime-rewards-backend/app.json b/airtime-rewards-backend/app.json
new file mode 100644
index 0000000..20c9066
--- /dev/null
+++ b/airtime-rewards-backend/app.json
@@ -0,0 +1,7 @@
+{
+ "name": "airtime-rewards-backend",
+ "description": "",
+ "repository": "https://github.com/okibeogezi/airtime-rewards-backend",
+ "keywords": [],
+ "image": "heroku/nodejs"
+}
diff --git a/airtime-rewards-backend/app/api.js b/airtime-rewards-backend/app/api.js
new file mode 100644
index 0000000..5d6709f
--- /dev/null
+++ b/airtime-rewards-backend/app/api.js
@@ -0,0 +1,138 @@
+'use strict'
+
+let helpers = require('./helpers')
+
+let surveys = require('./surveys')
+
+const _API_KEY = '38f478a9501db883d47e251dbc0a7f5ad36e20cb1eabfe16566308d2b56eeb08'
+const _USERNAME = 'sandbox'
+
+let AfricasTalking = require('africastalking')
+let options = {
+ apiKey: _API_KEY,
+ username: _USERNAME,
+}
+let africasTalking = AfricasTalking(options)
+
+let { SMS, AIRTIME } = africasTalking
+
+let defaultErr = {
+ success: false
+}
+
+let invalidArgsErr = {
+ success: false,
+ errorMessage: "Invalid arguments"
+}
+
+let apiError = (errorMessage) => {
+ return {
+ success: false,
+ errorMessage
+ }
+}
+
+module.exports = {
+ sendAirtime: (req, res, next) => {
+ let { phoneNumber, to, amount } = req.body
+
+ console.log(`AIRTIME AMOUNT = ₦${amount}`)
+ console.log(`RECIPIENT PHONE NUMBER = ${to || phoneNumber}`)
+
+ if (!(phoneNumber || to) || !amount) {
+ return res.send(invalidArgsErr)
+ }
+
+ AIRTIME.send({
+ recipients: [
+ {
+ phoneNumber: to || phoneNumber,
+ amount: `NGN ${amount}`
+ }
+ ]
+ })
+ .then((dat) => {
+ console.log(`Airtime dat = `, dat)
+ if (dat.errorMessage == 'None' || !dat.errorMessage) {
+ console.log(`Airtime was successfully sent to ${to || phoneNumber}`)
+ res.send({
+ success: true,
+ amount,
+ phoneNumber: phoneNumber || to,
+ to: to || phoneNumber
+ })
+ }
+ else {
+ console.error(`Airtime errMessage = `, dat.errorMessage)
+ res.send(apiError(dat.errorMessage))
+ }
+ })
+ .catch((err) => {
+ console.error(`err = `, err)
+ res.send(defaultErr)
+ })
+ },
+
+ sendData: (req, res, next) => {
+
+ },
+
+ sendText: (req, res, next) => {
+ let { amount, phoneNumber, to } = req.body
+
+ let message = `₦${amount} airtime has been sent to your phone number`
+ let enqueue = true
+ let from
+
+ console.log(`TEXT MESSAGE = "${message}"`)
+ console.log(`AIRTIME AMOUNT = ₦${amount}`)
+ console.log(`RECIPIENT PHONE NUMBER = ${phoneNumber || to}`)
+
+ if (!(phoneNumber || to) || !amount) {
+ return res.send(invalidArgsErr)
+ }
+
+ SMS.send({
+ message,
+ to: phoneNumber || to,
+ from,
+ enqueue
+ })
+ .then((dat) => {
+ console.log(`Text dat = `, dat)
+ if (dat.errorMessage == 'None' || !dat.errorMessage) {
+ console.log(`Text message was successfully sent to ${to || phoneNumber}`)
+ res.send({
+ success: true,
+ amount,
+ phoneNumber,
+ to,
+ message
+ })
+ }
+ else {
+ console.error(`Text errMessage = `, dat.errorMessage)
+ res.send(apiError(dat.errorMessage))
+ }
+ })
+ .catch((err) => {
+ console.error(`err = `, err)
+ res.send(defaultErr)
+ })
+ },
+
+ requestSurvey: (req, res, next) => {
+ try {
+ res.send({
+ success: true,
+ survey: surveys.getRandomSurvey()
+ })
+ }
+ catch (err) {
+ res.send({
+ success: false,
+ errorMessage: err
+ })
+ }
+ }
+}
diff --git a/airtime-rewards-backend/app/helpers.js b/airtime-rewards-backend/app/helpers.js
new file mode 100644
index 0000000..7ce4d01
--- /dev/null
+++ b/airtime-rewards-backend/app/helpers.js
@@ -0,0 +1,53 @@
+'use script'
+
+let uuid = require('uuid')
+
+let generateOrQuery = (id) => {
+ return {
+ $or: [
+ { uuid: id },
+ { _id: id }
+ ]
+ }
+}
+
+let getValueBetweenInclusive = (start, stop) => {
+ let diff = Math.abs(stop - start) + 1
+ return Math.floor(Math.random() * diff) + start
+}
+
+let getQueryForDoc = (doc) => {
+ return {
+ $or: [
+ { _id: doc._id }, { _id: doc.uuid },
+ { uuid: doc.uuid}, { uuid: doc._id }
+ ]
+ }
+}
+
+let getItemImagePath = (imageUuid) => {
+ return `/uploads/${imageUuid}`;
+}
+
+let getItemImageLocalPath = (imageUuid) => {
+ return `public/uploads/${imageUuid}`;
+}
+
+let getQueryForUser = (user) => {
+ return {
+ $or: [
+ { _id: user._id },
+ { phone: user.phone || uuid.v4() },
+ { email: user.email || uuid.v4() }
+ ]
+ }
+}
+
+module.exports = {
+ generateOrQuery,
+ getQueryForDoc,
+ getQueryForUser,
+ getItemImagePath,
+ getItemImageLocalPath,
+ getValueBetweenInclusive
+}
\ No newline at end of file
diff --git a/airtime-rewards-backend/app/routes.js b/airtime-rewards-backend/app/routes.js
new file mode 100644
index 0000000..80271d1
--- /dev/null
+++ b/airtime-rewards-backend/app/routes.js
@@ -0,0 +1,15 @@
+'use strict'
+
+let _ = require('underscore')
+let fs = require('fs')
+let path = require('path')
+
+let helpers = require('../app/helpers')
+
+let index = (req, res, next) => {
+ res.send(`Welcome to the ${req.app.get('projectName')} API v1\n`)
+}
+
+module.exports = {
+ index
+}
\ No newline at end of file
diff --git a/airtime-rewards-backend/app/surveys.js b/airtime-rewards-backend/app/surveys.js
new file mode 100644
index 0000000..f67ff85
--- /dev/null
+++ b/airtime-rewards-backend/app/surveys.js
@@ -0,0 +1,104 @@
+let _ = require('underscore')
+
+let helpers = require('./helpers')
+
+let questions = [
+ {
+ questionText: 'What is your favourite car brand?',
+ inputType: true,
+ },
+ {
+ questionText: 'What age bracket are you in?',
+ radioButtonType: true,
+ options: [
+ 'Below 18',
+ '18-25',
+ '26-30',
+ '31-40',
+ '41-50',
+ 'Above 50'
+ ]
+ },
+ {
+ questionText: 'What is your favourite instant noodles product?',
+ radioButtonType: true,
+ options: [
+ 'Indomie Noodles',
+ 'Mi Mi Noodles',
+ 'Dangote Noodles',
+ 'Other'
+ ]
+ },
+ {
+ questionText: 'What is your party of choice in the upcoming elections?',
+ radioButtonType: true,
+ options: [
+ 'PDP',
+ 'APC',
+ 'SDP',
+ 'Other'
+ ]
+ },
+ {
+ questionText: 'Who is your candidate of choice in the upcoming elections?',
+ radioButtonType: true,
+ options: [
+ 'Donald Duke',
+ 'Atiku Abubakar',
+ 'Mohammadu Buhari',
+ 'Other'
+ ]
+ },
+ {
+ questionText: 'Which transport means would you use when travelling across geopolitical zones?',
+ checkBoxType: true,
+ options: [
+ 'Train',
+ 'Public Vehicle',
+ 'Private Vehicle',
+ 'Plane'
+ ]
+ }
+]
+
+class Question {
+ constructor () {
+ this.imageUrl
+ this.questionText
+
+ this.inputType
+ this.checkBoxType
+ this.radioButtonType
+
+ this.options
+ }
+}
+
+class Answer {
+ constructor () {
+ this.questionText
+
+ this.inputType
+ this.checkBoxType
+ this.radioButtonType
+
+ this.answers
+ this.options
+ }
+}
+
+class Survey {
+ constructor (questions) {
+ this.questions = questions
+ }
+}
+
+
+
+module.exports = {
+ getRandomSurvey: () => {
+ let qCount = helpers.getValueBetweenInclusive(3, 5)
+
+ return new Survey(_.sample(questions, qCount))
+ }
+}
\ No newline at end of file
diff --git a/airtime-rewards-backend/objects/item.js b/airtime-rewards-backend/objects/item.js
new file mode 100644
index 0000000..b1aaf41
--- /dev/null
+++ b/airtime-rewards-backend/objects/item.js
@@ -0,0 +1,41 @@
+'use strict'
+
+let util = require('util')
+let uuid = require('uuid')
+let assert = require('assert')
+
+let Market = require('../objects/market')
+
+class Item {
+ static fromJSON (obj) {
+ const { name, description, markets, image } = obj
+
+ return new Item(name, description, markets, image)
+ }
+
+ static fromJSONArray (objArray) {
+ let items = []
+ for (let item of objArray) {
+ items.push(this.fromJSON(item))
+ }
+ return items
+ }
+
+ constructor (name, desc, markets, image) {
+ this.name = name
+ assert(util.isString(this.name))
+
+ this.description = desc || ''
+ assert(util.isString(this.description))
+
+ this.markets = Market.fromJSONArray(markets || [])
+ assert(util.isArray(this.markets))
+ assert(this.markets[0] instanceof Market || !this.markets.length)
+
+ this.image = image || ''
+
+ this.uuid = uuid.v4()
+ }
+}
+
+module.exports = Item
\ No newline at end of file
diff --git a/airtime-rewards-backend/objects/itemgroup.js b/airtime-rewards-backend/objects/itemgroup.js
new file mode 100644
index 0000000..2626587
--- /dev/null
+++ b/airtime-rewards-backend/objects/itemgroup.js
@@ -0,0 +1,91 @@
+'use strict'
+
+let util = require('util')
+let uuid = require('uuid')
+let assert = require('assert')
+let Item = require('./item')
+let itemGroupDB = require('../models/itemgroups')
+
+let helpers = require('../app/helpers')
+let getQueryForItemGroup = helpers.getQueryForDoc
+
+class ItemGroup {
+ static fromJSON (obj) {
+ const { name, description, items, priority } = obj
+
+ return new ItemGroup(name, description, items, priority)
+ }
+
+ constructor (name, desc, items, priority) {
+ this.name = name
+ assert(util.isString(this.name))
+
+ this.description = desc || ''
+ assert(util.isString(this.description))
+
+ this.items = Item.fromJSONArray(items || [])
+ assert(util.isArray(this.items))
+ assert(this.items[0] instanceof Item || !this.items.length)
+
+ this.priority = parseInt(priority) || 3
+ assert(util.isNumber(this.priority))
+
+ this.uuid = uuid.v4()
+ }
+
+ static update (itemGroup, cb) {
+ itemGroupDB.update(getQueryForItemGroup(itemGroup), itemGroup, {}, (err, cnt) => {
+ console.log('Updates:', cnt)
+ if (err) {
+ return cb(err)
+ }
+
+ cb(err, cnt)
+ })
+ }
+
+ static remove (itemGroup, cb) {
+ itemGroupDB.remove(itemGroup, {}, (err, cnt) => {
+ console.log('Removals:', cnt)
+ if (err) {
+ return cb(err, cnt)
+ }
+
+ cb(err, cnt)
+ })
+ }
+
+ static save (itemGroup, cb) {
+ itemGroupDB.insert(itemGroup, (err, newDoc) => {
+ if (err) {
+ return cb(err, newDoc)
+ }
+
+ cb(err, newDoc)
+ })
+ }
+
+ static findAll (cb) {
+ itemGroupDB.find({}).sort({
+ priority: -1
+ }).exec((err, docs) => {
+ if (err) {
+ return cb(err, docs)
+ }
+
+ cb(err, docs)
+ })
+ }
+
+ static findOne (query, cb) {
+ itemGroupDB.findOne(query, (err, doc) => {
+ if (err) {
+ return cb(err, doc)
+ }
+
+ cb(err, doc)
+ })
+ }
+}
+
+module.exports = ItemGroup
\ No newline at end of file
diff --git a/airtime-rewards-backend/objects/market.js b/airtime-rewards-backend/objects/market.js
new file mode 100644
index 0000000..cfb564e
--- /dev/null
+++ b/airtime-rewards-backend/objects/market.js
@@ -0,0 +1,64 @@
+'use strict'
+
+let util = require('util')
+let uuid = require('uuid')
+let assert = require('assert')
+
+class Market {
+ static fromJSON (obj) {
+ let { name, phone, grades } = obj
+
+ return new Market(name, phone, grades)
+ }
+
+ static isFilledJSON (obj) {
+ let { name, phone, grades } = obj
+ console.log(grades)
+ grades = grades.filter((grade) => {
+ if (grade) {
+ return grade
+ }
+ })
+ obj.grades = grades
+ let hasGrade = false
+ for (let grade of grades) {
+ if (grade) {
+ hasGrade = true
+ }
+ }
+
+ if (name || phone || hasGrade) {
+ return true
+ }
+
+ return false
+ }
+
+ static fromJSONArray (objArray) {
+ let markets = []
+ for (let market of objArray) {
+ if (Market.isFilledJSON(market)) {
+ markets.push(Market.fromJSON(market))
+ }
+ }
+ return markets
+ }
+
+ constructor (name, phone, grades) {
+ this.name = name || ''
+ assert(util.isString(this.name))
+
+ this.phone = phone || ''
+ // TODO: Use better validation
+ assert(util.isString(this.phone)) // &&
+ // (this.phone.length == 11 && this.phone.startsWith('0') ||
+ // this.phone.length == 14 && this.phone.startsWith('+234')))
+
+ this.grades = grades || []
+ assert(util.isArray(this.grades))
+
+ this.uuid = uuid.v4()
+ }
+}
+
+module.exports = Market
\ No newline at end of file
diff --git a/airtime-rewards-backend/objects/marketSuggestions.js b/airtime-rewards-backend/objects/marketSuggestions.js
new file mode 100644
index 0000000..531ac32
--- /dev/null
+++ b/airtime-rewards-backend/objects/marketSuggestions.js
@@ -0,0 +1,57 @@
+'use strict'
+
+let util = require('util')
+let uuid = require('uuid')
+let assert = require('assert')
+let marketSuggestionsDB = require('../models/marketSuggestions')
+
+let helpers = require('../app/helpers')
+let getQueryForItemGroup = helpers.getQueryForDoc
+
+class MarketSuggestion {
+ static fromJSON (obj) {
+ let { name, location, phone, email } = obj
+
+ return new MarketSuggestion(name, location, phone, email)
+ }
+
+ constructor (name, location, phone, email) {
+ this.name = name || ''
+ assert(util.isString(this.name))
+
+ this.location = location || ''
+ assert(util.isString(this.location))
+
+ this.phone = phone || ''
+ // TODO: Use better validation
+ assert(util.isString(this.phone)) // &&
+ // (this.phone.length == 11 && this.phone.startsWith('0') ||
+ // this.phone.length == 14 && this.phone.startsWith('+234')))
+
+ this.email = email || ''
+ assert(util.isString(this.email))
+
+ this.uuid = uuid.v4()
+ }
+
+ static save (suggestion, cb) {
+ marketSuggestionsDB.insert(suggestion, (err, newDoc) => {
+ if (err) {
+ return cb(err, newDoc)
+ }
+
+ cb(err, newDoc)
+ })
+ }
+
+ static findAll (cb) {
+ marketSuggestionsDB.find({}, (err, docs) => {
+ if (err) {
+ return cb(err, docs)
+ }
+ cb(err, docs)
+ })
+ }
+}
+
+module.exports = MarketSuggestion
\ No newline at end of file
diff --git a/airtime-rewards-backend/objects/user.js b/airtime-rewards-backend/objects/user.js
new file mode 100644
index 0000000..e61d228
--- /dev/null
+++ b/airtime-rewards-backend/objects/user.js
@@ -0,0 +1,169 @@
+'use strict'
+
+let util = require('util')
+let uuid = require('uuid')
+let ms = require('ms')
+let assert = require('assert')
+let userDB = require('../models/users')
+
+let helpers = require('../app/helpers')
+let getQueryForUser = helpers.getQueryForUser
+
+let defaultCb = (err, doc) => {
+ if (err) {
+ console.error(err)
+ }
+ else {
+ console.log(doc)
+ }
+}
+
+class User {
+ static fromJSON (obj) {
+ let { phone, email, password, loginCount, paymentValidTill } = obj
+
+ let user = new User(phone, email, password, loginCount, paymentValidTill)
+ user.uuid = obj.uuid || user.uuid, user._id = obj._id
+
+ return user
+ }
+
+ constructor (phone, email, password, loginCount, paymentValidTill) {
+ this.phone = phone || ''
+ // TODO: Use better validation
+ assert(util.isString(this.phone)) /* &&
+ (this.phone.length == 11 && this.phone.startsWith('0') ||
+ this.phone.length == 14 && this.phone.startsWith('+234'))) */
+
+ this.email = email || ''
+ assert(util.isString(this.email))
+
+ this.password = password || ''
+ assert(util.isString(this.password))
+
+ this.loginCount = loginCount || 0
+ assert(util.isNumber(this.loginCount))
+
+ this.paymentValidTill = paymentValidTill || 0
+ assert(util.isNumber(this.paymentValidTill))
+
+ this.uuid = uuid.v4()
+ }
+
+ static signup (phone, email, password, cb) { // cb(err, success, user, message)
+ userDB.find({
+ $or: [
+ { phone }, { email }
+ ]
+ }, (err, docs) => {
+ if (err) {
+ cb(err, false)
+ }
+ else if (docs.length) {
+ cb(err, false, null, 'Phone number or email are already in use. Please use another and try again.')
+ }
+ else {
+ userDB.insert({
+ phone, email, password
+ }, (err, doc) => {
+ if (err) {
+ cb(err, false)
+ }
+ else {
+ console.log(`User account created`)
+ let user = User.fromJSON(doc)
+ cb(err, true, user)
+ User.incLoginCount(user, (err, cnt) => {
+ if (!err) {
+ console.log(`User loginCount updated to ${user.loginCount}`)
+ }
+ })
+ }
+ })
+ }
+ })
+ }
+
+ static login (phone, password, cb) { // cb(err, success, user, message)
+ userDB.findOne({
+ password, phone
+ }, (err, doc) => {
+ if (err) {
+ cb(err, false)
+ }
+ else if (!doc || !Object.keys(doc || {}).length) {
+ cb(err, false, {}, 'Invalid login credentials. Please try again.')
+ }
+ else {
+ let user = User.fromJSON(doc);
+ cb(err, true, user)
+ User.incLoginCount(user, (err, cnt) => {
+ if (!err) {
+ console.log(`User loginCount updated to ${user.loginCount}`)
+ }
+ })
+ }
+ })
+ }
+
+ static update (user, cb) {
+ userDB.update(getQueryForUser(user), user, {}, (err, cnt) => {
+ console.log('Updates:', cnt)
+ if (err) {
+ cb(err)
+ }
+
+ cb(err, cnt)
+ })
+ }
+
+ static payForMonth (user, cb) {
+ userDB.update(getQueryForUser(user), {
+ $set: {
+ paymentValidTill: Date.now() + ms('31 days')
+ }
+ }, {}, (err, cnt) => {
+ console.log('Updates:', cnt)
+ if (err) {
+ cb(err)
+ }
+
+ cb(err, cnt)
+ })
+ }
+
+ static payForYear (user, cb) {
+ userDB.update(getQueryForUser(user), {
+ $set: {
+ paymentValidTill: Date.now() + ms('1 year')
+ }
+ }, {}, (err, cnt) => {
+ console.log('Updates:', cnt)
+ if (err) {
+ cb(err)
+ }
+
+ cb(err, cnt)
+ })
+ }
+
+ static incLoginCount (user, cb) {
+ userDB.update(getQueryForUser(user), {
+ $inc: {
+ loginCount: 1
+ }
+ }, {}, (err, cnt) => {
+ console.log('Updates:', cnt)
+ if (err) {
+ cb(err)
+ }
+ cb(err, cnt)
+ })
+ }
+
+ static findAll (cb) {
+ userDB.find({}, cb)
+ }
+}
+
+module.exports = User
\ No newline at end of file
diff --git a/airtime-rewards-backend/package-lock.json b/airtime-rewards-backend/package-lock.json
new file mode 100644
index 0000000..b299e41
--- /dev/null
+++ b/airtime-rewards-backend/package-lock.json
@@ -0,0 +1,4503 @@
+{
+ "name": "airtime-rewards-backend",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "accepts": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "requires": {
+ "mime-types": "2.1.17",
+ "negotiator": "0.6.1"
+ }
+ },
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ },
+ "acorn-globals": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
+ "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
+ "requires": {
+ "acorn": "4.0.13"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+ }
+ }
+ },
+ "africastalking": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/africastalking/-/africastalking-0.3.2.tgz",
+ "integrity": "sha512-qOaTOu7cgPBBXzP8duCvAyAjncASUYJU6ihXZpM9zwR4HQnJYqezrMcoTGOQLyZJvsaS/c2FJoEBRamRiv2a6g==",
+ "requires": {
+ "body-parser": "1.18.3",
+ "grpc": "1.15.1",
+ "install": "0.10.4",
+ "lodash": "4.17.11",
+ "unirest": "0.5.1",
+ "validate.js": "0.12.0"
+ },
+ "dependencies": {
+ "body-parser": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
+ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.3",
+ "iconv-lite": "0.4.23",
+ "on-finished": "2.3.0",
+ "qs": "6.5.2",
+ "raw-body": "2.3.3",
+ "type-is": "1.6.16"
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "requires": {
+ "depd": "1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": "1.5.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "mime-db": {
+ "version": "1.37.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+ "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
+ },
+ "mime-types": {
+ "version": "2.1.21",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+ "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+ "requires": {
+ "mime-db": "1.37.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "raw-body": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+ "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.3",
+ "iconv-lite": "0.4.23",
+ "unpipe": "1.0.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.21"
+ }
+ }
+ }
+ },
+ "ajv": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz",
+ "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=",
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "requires": {
+ "kind-of": "3.2.2",
+ "longest": "1.0.1",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+ },
+ "ansi-align": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+ "requires": {
+ "string-width": "2.1.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "requires": {
+ "micromatch": "3.1.9",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "append-field": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz",
+ "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo="
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "ascli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz",
+ "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=",
+ "requires": {
+ "colour": "0.7.1",
+ "optjs": "3.2.2"
+ }
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+ },
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "atob": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
+ "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.1",
+ "pascalcase": "0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ }
+ }
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "binary-extensions": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU="
+ },
+ "binary-search-tree": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz",
+ "integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=",
+ "requires": {
+ "underscore": "1.4.4"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
+ "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
+ }
+ }
+ },
+ "bl": {
+ "version": "1.1.2",
+ "resolved": "http://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
+ "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=",
+ "requires": {
+ "readable-stream": "2.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "readable-stream": {
+ "version": "2.0.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "string_decoder": "0.10.31",
+ "util-deprecate": "1.0.2"
+ }
+ }
+ }
+ },
+ "body-parser": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.15.2.tgz",
+ "integrity": "sha1-11eM9PHRHV9uqATO813Hp/9trmc=",
+ "requires": {
+ "bytes": "2.4.0",
+ "content-type": "1.0.4",
+ "debug": "2.2.0",
+ "depd": "1.1.1",
+ "http-errors": "1.5.1",
+ "iconv-lite": "0.4.13",
+ "on-finished": "2.3.0",
+ "qs": "6.2.0",
+ "raw-body": "2.1.7",
+ "type-is": "1.6.15"
+ }
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "boxen": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
+ "requires": {
+ "ansi-align": "2.0.0",
+ "camelcase": "4.1.0",
+ "chalk": "2.3.1",
+ "cli-boxes": "1.0.0",
+ "string-width": "2.1.1",
+ "term-size": "1.2.0",
+ "widest-line": "2.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
+ "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "kind-of": "6.0.2",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.1",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "busboy": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
+ "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
+ "requires": {
+ "dicer": "0.2.5",
+ "readable-stream": "1.1.14"
+ }
+ },
+ "bytebuffer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz",
+ "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=",
+ "requires": {
+ "long": "3.2.0"
+ }
+ },
+ "bytes": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
+ "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ }
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
+ },
+ "capture-stack-trace": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
+ "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0="
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ }
+ },
+ "chalk": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz",
+ "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "5.2.0"
+ }
+ },
+ "character-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
+ "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
+ "requires": {
+ "is-regex": "1.0.4"
+ }
+ },
+ "chokidar": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz",
+ "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==",
+ "requires": {
+ "anymatch": "2.0.0",
+ "async-each": "1.0.1",
+ "braces": "2.3.1",
+ "glob-parent": "3.1.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "4.0.0",
+ "normalize-path": "2.1.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0",
+ "upath": "1.0.2"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "clean-css": {
+ "version": "3.4.28",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
+ "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=",
+ "requires": {
+ "commander": "2.8.1",
+ "source-map": "0.4.4"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "cli-boxes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "colour": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz",
+ "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g="
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+ "requires": {
+ "graceful-readlink": "1.0.1"
+ }
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ },
+ "compressible": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz",
+ "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=",
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "compression": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz",
+ "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=",
+ "requires": {
+ "accepts": "1.3.4",
+ "bytes": "3.0.0",
+ "compressible": "2.0.11",
+ "debug": "2.6.9",
+ "on-headers": "1.0.1",
+ "safe-buffer": "5.1.1",
+ "vary": "1.1.2"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "typedarray": "0.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "configstore": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz",
+ "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==",
+ "requires": {
+ "dot-prop": "4.2.0",
+ "graceful-fs": "4.1.11",
+ "make-dir": "1.2.0",
+ "unique-string": "1.0.0",
+ "write-file-atomic": "2.3.0",
+ "xdg-basedir": "3.0.0"
+ }
+ },
+ "constantinople": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.0.tgz",
+ "integrity": "sha1-dWnKqKo/jVk11i4fqW+fcCzYHHk=",
+ "requires": {
+ "acorn": "3.3.0",
+ "is-expression": "2.1.0"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.1.tgz",
+ "integrity": "sha1-h0dsamfI2qh+Muh2Ft+IO6f7Bxs="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-parser": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
+ "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
+ "requires": {
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6"
+ }
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "create-error-class": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+ "requires": {
+ "capture-stack-trace": "1.0.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "requires": {
+ "lru-cache": "4.1.1",
+ "shebang-command": "1.2.0",
+ "which": "1.3.0"
+ }
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "requires": {
+ "boom": "5.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ }
+ }
+ },
+ "crypto-random-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
+ },
+ "css-parse": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
+ "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs="
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
+ "deep-extend": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "dicer": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
+ "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
+ "requires": {
+ "readable-stream": "1.1.14",
+ "streamsearch": "0.1.2"
+ }
+ },
+ "doctypes": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
+ "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "requires": {
+ "is-obj": "1.0.1"
+ }
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+ "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "etag": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz",
+ "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg="
+ },
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+ "requires": {
+ "duplexer": "0.1.1",
+ "from": "0.1.7",
+ "map-stream": "0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3.3",
+ "stream-combiner": "0.0.4",
+ "through": "2.3.8"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "express": {
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.14.0.tgz",
+ "integrity": "sha1-we4/Qs3Ikfs9xlCoki1R7IR9DWY=",
+ "requires": {
+ "accepts": "1.3.4",
+ "array-flatten": "1.1.1",
+ "content-disposition": "0.5.1",
+ "content-type": "1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.2.0",
+ "depd": "1.1.1",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.7.0",
+ "finalhandler": "0.5.0",
+ "fresh": "0.3.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "1.1.5",
+ "qs": "6.2.0",
+ "range-parser": "1.2.0",
+ "send": "0.14.1",
+ "serve-static": "1.11.2",
+ "type-is": "1.6.15",
+ "utils-merge": "1.0.0",
+ "vary": "1.1.2"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz",
+ "integrity": "sha1-6VCKvs6bbbqHGmlCodeRG5GRGsc=",
+ "requires": {
+ "debug": "2.2.0",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+ "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz",
+ "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8="
+ },
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "requires": {
+ "is-glob": "3.1.0",
+ "path-dirname": "1.0.2"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ }
+ }
+ },
+ "global-dirs": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+ "requires": {
+ "ini": "1.3.5"
+ }
+ },
+ "got": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+ "requires": {
+ "create-error-class": "3.0.2",
+ "duplexer3": "0.1.4",
+ "get-stream": "3.0.0",
+ "is-redirect": "1.0.0",
+ "is-retry-allowed": "1.1.0",
+ "is-stream": "1.1.0",
+ "lowercase-keys": "1.0.0",
+ "safe-buffer": "5.1.1",
+ "timed-out": "4.0.1",
+ "unzip-response": "2.0.1",
+ "url-parse-lax": "1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
+ },
+ "grpc": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.15.1.tgz",
+ "integrity": "sha512-BfJ6BpFE93xQW69oYfgVQDxSb7LqdQbnddvhFq4tUsj7s0NAIRrrN3fmN2Bi3qpGFRemsKsWPIchw3YNNq2Xjg==",
+ "requires": {
+ "lodash": "4.17.11",
+ "nan": "2.11.1",
+ "node-pre-gyp": "0.10.3",
+ "protobufjs": "5.0.3"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "bundled": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "bundled": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "bundled": true,
+ "requires": {
+ "delegates": "1.0.0",
+ "readable-stream": "2.3.6"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "bundled": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "bundled": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "bundled": true
+ },
+ "fs-minipass": {
+ "version": "1.2.5",
+ "bundled": true,
+ "requires": {
+ "minipass": "2.3.3"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "requires": {
+ "aproba": "1.2.0",
+ "console-control-strings": "1.1.0",
+ "has-unicode": "2.0.1",
+ "object-assign": "4.1.1",
+ "signal-exit": "3.0.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wide-align": "1.1.3"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "bundled": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "bundled": true,
+ "requires": {
+ "safer-buffer": "2.1.2"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.1",
+ "bundled": true,
+ "requires": {
+ "minimatch": "3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "bundled": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true
+ },
+ "minipass": {
+ "version": "2.3.3",
+ "bundled": true,
+ "requires": {
+ "safe-buffer": "5.1.2",
+ "yallist": "3.0.2"
+ }
+ },
+ "minizlib": {
+ "version": "1.1.0",
+ "bundled": true,
+ "requires": {
+ "minipass": "2.3.3"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "bundled": true
+ },
+ "needle": {
+ "version": "2.2.2",
+ "bundled": true,
+ "requires": {
+ "debug": "2.6.9",
+ "iconv-lite": "0.4.23",
+ "sax": "1.2.4"
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.10.3",
+ "bundled": true,
+ "requires": {
+ "detect-libc": "1.0.3",
+ "mkdirp": "0.5.1",
+ "needle": "2.2.2",
+ "nopt": "4.0.1",
+ "npm-packlist": "1.1.11",
+ "npmlog": "4.1.2",
+ "rc": "1.2.8",
+ "rimraf": "2.6.2",
+ "semver": "5.5.0",
+ "tar": "4.4.6"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "bundled": true,
+ "requires": {
+ "abbrev": "1.1.1",
+ "osenv": "0.1.5"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.3",
+ "bundled": true
+ },
+ "npm-packlist": {
+ "version": "1.1.11",
+ "bundled": true,
+ "requires": {
+ "ignore-walk": "3.0.1",
+ "npm-bundled": "1.0.3"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "bundled": true,
+ "requires": {
+ "are-we-there-yet": "1.1.5",
+ "console-control-strings": "1.1.0",
+ "gauge": "2.7.4",
+ "set-blocking": "2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "bundled": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "bundled": true
+ },
+ "rc": {
+ "version": "1.2.8",
+ "bundled": true,
+ "requires": {
+ "deep-extend": "0.6.0",
+ "ini": "1.3.5",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "bundled": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.2",
+ "string_decoder": "1.1.1",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "bundled": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "bundled": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true
+ },
+ "semver": {
+ "version": "5.5.0",
+ "bundled": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "bundled": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "bundled": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true
+ },
+ "tar": {
+ "version": "4.4.6",
+ "bundled": true,
+ "requires": {
+ "chownr": "1.0.1",
+ "fs-minipass": "1.2.5",
+ "minipass": "2.3.3",
+ "minizlib": "1.1.0",
+ "mkdirp": "0.5.1",
+ "safe-buffer": "5.1.2",
+ "yallist": "3.0.2"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "bundled": true,
+ "requires": {
+ "string-width": "1.0.2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "yallist": {
+ "version": "3.0.2",
+ "bundled": true
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "requires": {
+ "ajv": "5.3.0",
+ "har-schema": "2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+ "requires": {
+ "function-bind": "1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ }
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.0",
+ "sntp": "2.1.0"
+ }
+ },
+ "hoek": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+ "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
+ },
+ "http-errors": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
+ "integrity": "sha1-eIwNLB3iyBuebowBhDtrl+uSB1A=",
+ "requires": {
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.2",
+ "statuses": "1.3.1"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.13",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
+ "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
+ },
+ "ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk="
+ },
+ "immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+ },
+ "install": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/install/-/install-0.10.4.tgz",
+ "integrity": "sha512-+IRyOastuPmLVx9zlVXJoKErSqz1Ma5at9A7S8yfsj3W+Kg95faPoh3bPDtMrZ/grz4PRmXzrswmlzfLlYyLOw=="
+ },
+ "ipaddr.js": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
+ "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA="
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "requires": {
+ "binary-extensions": "1.11.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "is-expression": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-2.1.0.tgz",
+ "integrity": "sha1-kb6dR968/vB3l36XIr5tz7RGXvA=",
+ "requires": {
+ "acorn": "3.3.0",
+ "object-assign": "4.1.1"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ },
+ "is-installed-globally": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+ "requires": {
+ "global-dirs": "0.1.1",
+ "is-path-inside": "1.0.1"
+ }
+ },
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ=="
+ },
+ "is-my-json-valid": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz",
+ "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==",
+ "requires": {
+ "generate-function": "2.3.1",
+ "generate-object-property": "1.2.0",
+ "is-my-ip-valid": "1.0.0",
+ "jsonpointer": "4.0.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "is-npm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+ "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ="
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
+ },
+ "is-odd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+ "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+ "requires": {
+ "is-number": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+ }
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
+ },
+ "is-redirect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "requires": {
+ "has": "1.0.1"
+ }
+ },
+ "is-retry-allowed": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "js-stringify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
+ "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "jstransformer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
+ "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
+ "requires": {
+ "is-promise": "2.1.0",
+ "promise": "7.3.1"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ },
+ "latest-version": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+ "requires": {
+ "package-json": "4.0.1"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
+ },
+ "lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
+ "requires": {
+ "immediate": "3.0.6"
+ }
+ },
+ "localforage": {
+ "version": "1.5.6",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.5.6.tgz",
+ "integrity": "sha1-0DTRXlNy7pfGQXPpqa65aBX13QY=",
+ "requires": {
+ "lie": "3.1.1"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+ },
+ "lodash.endswith": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz",
+ "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk="
+ },
+ "lodash.isfunction": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
+ "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="
+ },
+ "lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
+ },
+ "lodash.startswith": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz",
+ "integrity": "sha1-xZjErc4YiiflMUVzHNxsDnF3YAw="
+ },
+ "long": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
+ "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+ },
+ "lowercase-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+ "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY="
+ },
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "make-dir": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
+ "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
+ "requires": {
+ "pify": "3.0.0"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+ },
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ="
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "requires": {
+ "object-visit": "1.0.1"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "micromatch": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz",
+ "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.1",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.9",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "mime": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ },
+ "mime-db": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ },
+ "mime-types": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
+ },
+ "multer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-1.2.1.tgz",
+ "integrity": "sha1-dZlZxsGff7A9Ajnx3wsezsiEc6M=",
+ "requires": {
+ "append-field": "0.1.0",
+ "busboy": "0.2.14",
+ "concat-stream": "1.6.0",
+ "mkdirp": "0.5.1",
+ "object-assign": "3.0.0",
+ "on-finished": "2.3.0",
+ "type-is": "1.6.15",
+ "xtend": "4.0.1"
+ }
+ },
+ "nan": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
+ "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA=="
+ },
+ "nanomatch": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+ "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "fragment-cache": "0.2.1",
+ "is-odd": "2.0.0",
+ "is-windows": "1.0.2",
+ "kind-of": "6.0.2",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
+ "nedb": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz",
+ "integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=",
+ "requires": {
+ "async": "0.2.10",
+ "binary-search-tree": "0.2.5",
+ "localforage": "1.5.6",
+ "mkdirp": "0.5.1",
+ "underscore": "1.4.4"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
+ "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "nib": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz",
+ "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=",
+ "requires": {
+ "stylus": "0.54.5"
+ }
+ },
+ "nodemon": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.15.1.tgz",
+ "integrity": "sha512-zWNke/X74j3ljDRCXnhURTLJaCxew31ax4azoPQyRYAoUBqNIlZGaNpMcyi/A/ylkGKWFiUzf7HHFyA/cveTcQ==",
+ "requires": {
+ "chokidar": "2.0.2",
+ "debug": "3.1.0",
+ "ignore-by-default": "1.0.1",
+ "minimatch": "3.0.4",
+ "pstree.remy": "1.1.0",
+ "semver": "5.5.0",
+ "touch": "3.1.0",
+ "undefsafe": "2.0.2",
+ "update-notifier": "2.3.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+ "requires": {
+ "abbrev": "1.1.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "requires": {
+ "path-key": "2.0.1"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+ },
+ "object-assign": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+ "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I="
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ }
+ }
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "optjs": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz",
+ "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4="
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "package-json": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+ "requires": {
+ "got": "6.7.1",
+ "registry-auth-token": "3.3.2",
+ "registry-url": "3.1.0",
+ "semver": "5.5.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "2.0.6"
+ }
+ },
+ "protobufjs": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz",
+ "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==",
+ "requires": {
+ "ascli": "1.0.1",
+ "bytebuffer": "5.0.1",
+ "glob": "7.0.6",
+ "yargs": "3.10.0"
+ }
+ },
+ "proxy-addr": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
+ "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
+ "requires": {
+ "forwarded": "0.1.2",
+ "ipaddr.js": "1.4.0"
+ }
+ },
+ "ps-tree": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
+ "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
+ "requires": {
+ "event-stream": "3.3.4"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ },
+ "pstree.remy": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
+ "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
+ "requires": {
+ "ps-tree": "1.1.0"
+ }
+ },
+ "pug": {
+ "version": "2.0.0-beta6",
+ "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-beta6.tgz",
+ "integrity": "sha1-nq0uWeVApGfvw3h8ywPkV0ul+uk=",
+ "requires": {
+ "pug-code-gen": "1.1.1",
+ "pug-filters": "1.2.4",
+ "pug-lexer": "2.3.2",
+ "pug-linker": "1.0.2",
+ "pug-load": "2.0.9",
+ "pug-parser": "2.0.2",
+ "pug-runtime": "2.0.3",
+ "pug-strip-comments": "1.0.2"
+ }
+ },
+ "pug-attrs": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.2.tgz",
+ "integrity": "sha1-i+KyIlVo/6ddG4Zpgr/59BEa/8s=",
+ "requires": {
+ "constantinople": "3.1.0",
+ "js-stringify": "1.0.2",
+ "pug-runtime": "2.0.3"
+ }
+ },
+ "pug-code-gen": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-1.1.1.tgz",
+ "integrity": "sha1-HPcnRO8qA56uajNAyqoRBYcSWOg=",
+ "requires": {
+ "constantinople": "3.1.0",
+ "doctypes": "1.1.0",
+ "js-stringify": "1.0.2",
+ "pug-attrs": "2.0.2",
+ "pug-error": "1.3.2",
+ "pug-runtime": "2.0.3",
+ "void-elements": "2.0.1",
+ "with": "5.1.1"
+ }
+ },
+ "pug-error": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz",
+ "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY="
+ },
+ "pug-filters": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-1.2.4.tgz",
+ "integrity": "sha1-kthSRyx0UIVyoNmwyR+dy5rgWDk=",
+ "requires": {
+ "clean-css": "3.4.28",
+ "constantinople": "3.1.0",
+ "jstransformer": "1.0.0",
+ "pug-error": "1.3.2",
+ "pug-walk": "1.1.5",
+ "resolve": "1.4.0",
+ "uglify-js": "2.8.29"
+ }
+ },
+ "pug-lexer": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-2.3.2.tgz",
+ "integrity": "sha1-aLGdlupdwOSoYUiwHLlmwXgVphQ=",
+ "requires": {
+ "character-parser": "2.2.0",
+ "is-expression": "3.0.0",
+ "pug-error": "1.3.2"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+ },
+ "is-expression": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
+ "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
+ "requires": {
+ "acorn": "4.0.13",
+ "object-assign": "4.1.1"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "pug-linker": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-1.0.2.tgz",
+ "integrity": "sha1-yjXdF+UO3nzCXM3FNKD9aPCJB1w=",
+ "requires": {
+ "pug-error": "1.3.2",
+ "pug-walk": "1.1.5"
+ }
+ },
+ "pug-load": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.9.tgz",
+ "integrity": "sha512-BDdZOCru4mg+1MiZwRQZh25+NTRo/R6/qArrdWIf308rHtWA5N9kpoUskRe4H6FslaQujC+DigH9LqlBA4gf6Q==",
+ "requires": {
+ "object-assign": "4.1.1",
+ "pug-walk": "1.1.5"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ }
+ }
+ },
+ "pug-parser": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-2.0.2.tgz",
+ "integrity": "sha1-U6aAz9BQOdywwn0CkJS8SnkmibA=",
+ "requires": {
+ "pug-error": "1.3.2",
+ "token-stream": "0.0.1"
+ }
+ },
+ "pug-runtime": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.3.tgz",
+ "integrity": "sha1-mBYmB7D86eJU1CfzOYelrucWi9o="
+ },
+ "pug-strip-comments": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz",
+ "integrity": "sha1-0xOvoBvMN0mA4TmeI+vy65vchRM=",
+ "requires": {
+ "pug-error": "1.3.2"
+ }
+ },
+ "pug-walk": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.5.tgz",
+ "integrity": "sha512-rJlH1lXerCIAtImXBze3dtKq/ykZMA4rpO9FnPcIgsWcxZLOvd8zltaoeOVFyBSSqCkhhJWbEbTMga8UxWUUSA=="
+ },
+ "qs": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz",
+ "integrity": "sha1-O3hIwDwt7OaalSKw+ujEEm10Xzs="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
+ "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=",
+ "requires": {
+ "bytes": "2.4.0",
+ "iconv-lite": "0.4.13",
+ "unpipe": "1.0.0"
+ }
+ },
+ "rc": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz",
+ "integrity": "sha1-J1zWh/bjs2zHVrqibf7oCnkDAf0=",
+ "requires": {
+ "deep-extend": "0.4.2",
+ "ini": "1.3.5",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "minimatch": "3.0.4",
+ "readable-stream": "2.3.4",
+ "set-immediate-shim": "1.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "readable-stream": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
+ "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "registry-auth-token": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
+ "requires": {
+ "rc": "1.2.5",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "registry-url": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+ "requires": {
+ "rc": "1.2.5"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "request": {
+ "version": "2.83.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.1",
+ "har-validator": "5.0.3",
+ "hawk": "6.0.2",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "performance-now": "2.1.0",
+ "qs": "6.5.1",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.2.1"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ }
+ }
+ },
+ "resolve": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
+ "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
+ "requires": {
+ "path-parse": "1.0.5"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "requires": {
+ "ret": "0.1.15"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
+ "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE="
+ },
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
+ },
+ "semver-diff": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "requires": {
+ "semver": "5.5.0"
+ }
+ },
+ "send": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.14.1.tgz",
+ "integrity": "sha1-qVSYQyU5L1FTKndgdg5FlZjIn3o=",
+ "requires": {
+ "debug": "2.2.0",
+ "depd": "1.1.1",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.7.0",
+ "fresh": "0.3.0",
+ "http-errors": "1.5.1",
+ "mime": "1.3.4",
+ "ms": "0.7.1",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ }
+ },
+ "serve-favicon": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz",
+ "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=",
+ "requires": {
+ "etag": "1.7.0",
+ "fresh": "0.3.0",
+ "ms": "0.7.2",
+ "parseurl": "1.3.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.11.2.tgz",
+ "integrity": "sha1-LPmIm9RDWjIMw2iVyapXvWYuasc=",
+ "requires": {
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.2",
+ "send": "0.14.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+ },
+ "send": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.14.2.tgz",
+ "integrity": "sha1-ObBDiz9RC+Xcb2Z6EfcWiTaM3u8=",
+ "requires": {
+ "debug": "2.2.0",
+ "depd": "1.1.1",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.7.0",
+ "fresh": "0.3.0",
+ "http-errors": "1.5.1",
+ "mime": "1.3.4",
+ "ms": "0.7.2",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ }
+ }
+ }
+ },
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
+ "integrity": "sha1-gaVSFB7BBLiOic44MQOtXGZWTQg="
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "requires": {
+ "shebang-regex": "1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "snapdragon": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz",
+ "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=",
+ "requires": {
+ "base": "0.11.2",
+ "debug": "2.2.0",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.1",
+ "use": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "source-map": {
+ "version": "0.1.43",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
+ "source-map-resolve": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+ "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+ "requires": {
+ "atob": "2.0.3",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
+ },
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "requires": {
+ "extend-shallow": "3.0.2"
+ }
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ },
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+ "requires": {
+ "duplexer": "0.1.1"
+ }
+ },
+ "streamsearch": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+ "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "stylus": {
+ "version": "0.54.5",
+ "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz",
+ "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=",
+ "requires": {
+ "css-parse": "1.7.0",
+ "debug": "2.2.0",
+ "glob": "7.0.6",
+ "mkdirp": "0.5.1",
+ "sax": "0.5.8",
+ "source-map": "0.1.43"
+ }
+ },
+ "supports-color": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz",
+ "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==",
+ "requires": {
+ "has-flag": "3.0.0"
+ }
+ },
+ "term-size": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+ "requires": {
+ "execa": "0.7.0"
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "requires": {
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "token-stream": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
+ "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+ },
+ "touch": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+ "requires": {
+ "nopt": "1.0.10"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "requires": {
+ "punycode": "1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "optional": true
+ },
+ "type-is": {
+ "version": "1.6.15",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+ "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.17"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "requires": {
+ "source-map": "0.5.7",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "optional": true
+ },
+ "undefsafe": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
+ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
+ "requires": {
+ "debug": "2.2.0"
+ }
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ }
+ }
+ },
+ "unique-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "requires": {
+ "crypto-random-string": "1.0.0"
+ }
+ },
+ "unirest": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/unirest/-/unirest-0.5.1.tgz",
+ "integrity": "sha1-nfV2YYcoDyRbTpp1zh+tMTM31u0=",
+ "requires": {
+ "form-data": "0.2.0",
+ "mime": "1.3.4",
+ "request": "2.74.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
+ },
+ "async": {
+ "version": "0.9.2",
+ "resolved": "http://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "combined-stream": {
+ "version": "0.0.7",
+ "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
+ "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
+ "requires": {
+ "delayed-stream": "0.0.5"
+ }
+ },
+ "commander": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "delayed-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
+ "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8="
+ },
+ "form-data": {
+ "version": "0.2.0",
+ "resolved": "http://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
+ "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
+ "requires": {
+ "async": "0.9.2",
+ "combined-stream": "0.0.7",
+ "mime-types": "2.0.14"
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.19.0",
+ "is-my-json-valid": "2.19.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "mime-db": {
+ "version": "1.12.0",
+ "resolved": "http://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
+ "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc="
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "resolved": "http://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
+ "requires": {
+ "mime-db": "1.12.0"
+ }
+ },
+ "node-uuid": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
+ "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
+ },
+ "request": {
+ "version": "2.74.0",
+ "resolved": "http://registry.npmjs.org/request/-/request-2.74.0.tgz",
+ "integrity": "sha1-dpPKdou7DqXIzgjAhKRe+gW4kqs=",
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "bl": "1.1.2",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.7",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "1.0.1",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.21",
+ "node-uuid": "1.4.8",
+ "oauth-sign": "0.8.2",
+ "qs": "6.2.0",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.4.3"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+ "requires": {
+ "lodash": "4.17.11"
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "form-data": {
+ "version": "1.0.1",
+ "resolved": "http://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz",
+ "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=",
+ "requires": {
+ "async": "2.6.1",
+ "combined-stream": "1.0.7",
+ "mime-types": "2.1.21"
+ }
+ },
+ "mime-db": {
+ "version": "1.37.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+ "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
+ },
+ "mime-types": {
+ "version": "2.1.21",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+ "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+ "requires": {
+ "mime-db": "1.37.0"
+ }
+ }
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us="
+ }
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ }
+ }
+ },
+ "unzip-response": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
+ },
+ "upath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.2.tgz",
+ "integrity": "sha512-fCmij7T5LnwUme3dbnVSejvOHHlARjB3ikJFwgZfz386pHmf/gueuTLRFU94FZEaeCLlbQrweiUU700gG41tUw==",
+ "requires": {
+ "lodash.endswith": "4.2.1",
+ "lodash.isfunction": "3.0.9",
+ "lodash.isstring": "4.0.1",
+ "lodash.startswith": "4.2.1"
+ }
+ },
+ "update-notifier": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz",
+ "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=",
+ "requires": {
+ "boxen": "1.3.0",
+ "chalk": "2.3.1",
+ "configstore": "3.1.1",
+ "import-lazy": "2.1.0",
+ "is-installed-globally": "0.1.0",
+ "is-npm": "1.0.0",
+ "latest-version": "3.1.0",
+ "semver-diff": "2.1.0",
+ "xdg-basedir": "3.0.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "1.0.4"
+ }
+ },
+ "use": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz",
+ "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=",
+ "requires": {
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "lazy-cache": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ },
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+ },
+ "validate.js": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/validate.js/-/validate.js-0.12.0.tgz",
+ "integrity": "sha512-/x2RJSvbqEyxKj0RPN4xaRquK+EggjeVXiDDEyrJzsJogjtiZ9ov7lj/svVb4DM5Q5braQF4cooAryQbUwOxlA=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ }
+ },
+ "void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "widest-line": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz",
+ "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=",
+ "requires": {
+ "string-width": "2.1.1"
+ }
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
+ },
+ "with": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
+ "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+ "requires": {
+ "acorn": "3.3.0",
+ "acorn-globals": "3.1.0"
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write-file-atomic": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "imurmurhash": "0.1.4",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "xdg-basedir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+}
diff --git a/airtime-rewards-backend/package.json b/airtime-rewards-backend/package.json
new file mode 100644
index 0000000..3099799
--- /dev/null
+++ b/airtime-rewards-backend/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "airtime-rewards-backend",
+ "version": "1.0.0",
+ "private": true,
+ "main": "app.js",
+ "scripts": {
+ "start": "NODE_ENV=production node app.js",
+ "debug": "NODE_ENV=development node app.js"
+ },
+ "dependencies": {
+ "africastalking": "^0.3.2",
+ "body-parser": "1.15.2",
+ "compression": "^1.7.1",
+ "cookie-parser": "1.4.3",
+ "express": "4.14.0",
+ "ms": "0.7.1",
+ "multer": "1.2.1",
+ "nedb": "^1.8.0",
+ "nib": "1.1.2",
+ "nodemon": "^1.15.1",
+ "pug": "2.0.0-beta6",
+ "request": "^2.83.0",
+ "serve-favicon": "2.3.2",
+ "stylus": "0.54.5",
+ "underscore": "^1.8.3",
+ "uuid": "^3.2.1"
+ }
+}
diff --git a/app-debug.apk b/app-debug.apk
new file mode 100644
index 0000000..720f8ad
Binary files /dev/null and b/app-debug.apk differ