diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb
index 4b79893..43e0c55 100644
--- a/app/controllers/roles_controller.rb
+++ b/app/controllers/roles_controller.rb
@@ -9,21 +9,22 @@
access_level = params[:role][:access_level].to_i
set_access_level(access_level)
+ message = ''
if params[:user].present?
if @role.plan.owner.present? && @role.plan.owner.email == params[:user]
flash[:notice] = _('Cannot share plan with %{email} since that email matches with the owner of the plan.') % {email: params[:user]}
else
- if Role.find_by(plan: @role.plan, user: User.find_by(email: params[:user])) # role already exists
+ user = User.where_case_insensitive('email',params[:user]).first
+ if Role.find_by(plan: @role.plan, user: user) # role already exists
flash[:notice] = _('Plan is already shared with %{email}.') % {email: params[:user]}
- else
- message = _('Plan shared with %{email}.') % {email: params[:user]}
- user = User.find_by(email: params[:user])
+ else
if user.nil?
registered = false
User.invite!(email: params[:user])
- message = _('Invitation to %{email} issued successfully.') % {email: params[:user]}
+ message = _('Invitation to %{email} issued successfully. \n') % {email: params[:user]}
user = User.find_by(email: params[:user])
end
+ message += _('Plan shared with %{email}.') % {email: user.email}
@role.user = user
if @role.save
if registered then UserMailer.sharing_notification(@role, current_user).deliver_now end
diff --git a/app/models/settings/template.rb b/app/models/settings/template.rb
index 59ac3de..a9fd6f8 100644
--- a/app/models/settings/template.rb
+++ b/app/models/settings/template.rb
@@ -1,11 +1,11 @@
module Settings
class Template < RailsSettings::SettingObject
-
+
#attr_accessible :var, :target, :target_id, :target_type
VALID_FONT_FACES = [
- 'Arial, Helvetica, Sans-Serif',
- '"Times New Roman", Times, Serif'
+ '"Times New Roman", Times, Serif',
+ 'Arial, Helvetica, Sans-Serif'
]
VALID_FONT_SIZE_RANGE = (8..14)
@@ -17,13 +17,13 @@
DEFAULT_SETTINGS = {
formatting: {
margin: { # in millimeters
- top: 20,
- bottom: 20,
- left: 20,
- right: 20
+ top: 10,
+ bottom: 10,
+ left: 10,
+ right: 10
},
font_face: VALID_FONT_FACES.first,
- font_size: 12 # pt
+ font_size: 10 # pt
},
max_pages: 3,
fields: {
diff --git a/app/models/user.rb b/app/models/user.rb
index d4e0543..79f5be7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -276,5 +276,13 @@
def deliver_invitation(options = {})
super(options.merge(subject: _('A Data Management Plan in %{application_name} has been shared with you') % {application_name: Rails.configuration.branding[:application][:name]}))
end
+ ##
+ # Case insensitive search over User model
+ # @param field [string] The name of the field being queried
+ # @param val [string] The string to search for, case insensitive
+ # @return [ActiveRecord::Relation] The result of the search
+ def self.where_case_insensitive(field, val)
+ User.where("lower(#{field}) = ?", val.downcase)
+ end
end
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb
index 92d1218..c61c99d 100644
--- a/app/views/devise/passwords/edit.html.erb
+++ b/app/views/devise/passwords/edit.html.erb
@@ -12,11 +12,11 @@
<%= f.label(:password, _('New password'), class: 'control-label') %>
- <%= f.password_field(:password, class: 'form-control', "aria-required": true) %>
+ <%= f.password_field(:password, class: 'form-control', "aria-required": true %>
<%= f.label(:password_confirmation, _('Password confirmation'), class: 'control-label') %>
- <%= f.password_field(:password_confirmation, class: 'form-control', "aria-required": true) %>
+ <%= f.password_field(:password_confirmation, class: 'form-control', "aria-required": true %>
- <%= f.label :access_level, raw("#{f.radio_button :access_level, 3} #{_('Co-owner: can edit project details, change visibility, and add collaborators')}") %>
+ <%= f.label :access_level, raw("#{f.radio_button :access_level, 3, "aria-required": true} #{_('Co-owner: can edit project details, change visibility, and add collaborators')}") %>
<%= f.button(_('Submit'), class: "btn btn-default", type: "submit") %>
diff --git a/db/migrate/20170702012742_ensure_indexes_in_place.rb b/db/migrate/20170702012742_ensure_indexes_in_place.rb
index 6bd9410..367ce5f 100644
--- a/db/migrate/20170702012742_ensure_indexes_in_place.rb
+++ b/db/migrate/20170702012742_ensure_indexes_in_place.rb
@@ -1,8 +1,12 @@
class EnsureIndexesInPlace < ActiveRecord::Migration
def change
#users_perms
+ remove_foreign_key :users_perms, :perms
+ remove_foreign_key :users_perms, :users
remove_index :users_perms, name: 'index_users_perms_on_user_id_and_perm_id'
add_index :users_perms, :user_id
+ add_foreign_key :users_perms, :perms
+ add_foreign_key :users_perms, :users
#user_identifiers
add_index :user_identifiers, :user_id
#roles
@@ -27,14 +31,22 @@
#annotations
add_index :annotations, :question_id
#question_themes
+ remove_foreign_key :questions_themes, :questions
+ remove_foreign_key :questions_themes, :themes
remove_index :questions_themes, name: 'question_theme_index'
remove_index :questions_themes, name: 'theme_question_index'
add_index :questions_themes, :question_id
+ add_foreign_key :questions_themes, :questions
+ add_foreign_key :questions_themes, :themes
#question_options
add_index :question_options, :question_id
#answers_question_options
+ remove_foreign_key :answers_question_options, :answers
+ remove_foreign_key :answers_question_options, :question_options
remove_index :answers_question_options, name: 'answer_question_option_index'
remove_index :answers_question_options, name: 'question_option_answer_index'
add_index :answers_question_options, :answer_id
+ add_foreign_key :answers_question_options, :answers
+ add_foreign_key :answers_question_options, :question_options
end
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 6c4aded..fabb9a8 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -8,7 +8,7 @@
{name: 'orcid', description: 'ORCID', active: true,
logo_url:'http://orcid.org/sites/default/files/images/orcid_16x16.png',
user_landing_url:'https://orcid.org' },
- {name: 'shibboleth', description: 'your institutional credentials', active: true,
+ {name: 'shibboleth', description: 'Your institutional credentials', active: true,
},
]
identifier_schemes.map{ |is| IdentifierScheme.create!(is) if IdentifierScheme.find_by(name: is[:name]).nil? }
@@ -16,13 +16,13 @@
# Question Formats
# -------------------------------------------------------
question_formats = [
- {title: "Text area", option_based: false},
- {title: "Text field", option_based: false},
- {title: "Radio buttons", option_based: true},
- {title: "Check box", option_based: true},
- {title: "Dropdown", option_based: true},
- {title: "Multi select box", option_based: true},
- {title: "Date", option_based: false}
+ {title: "Text area", option_based: false, formattype: 0},
+ {title: "Text field", option_based: false, formattype: 1},
+ {title: "Radio buttons", option_based: true, formattype: 2},
+ {title: "Check box", option_based: true, formattype: 3},
+ {title: "Dropdown", option_based: true, formattype: 4},
+ {title: "Multi select box", option_based: true, formattype: 5},
+ {title: "Date", option_based: true, formattype: 6}
]
question_formats.map{ |qf| QuestionFormat.create!(qf) if QuestionFormat.find_by(title: qf[:title]).nil? }
@@ -154,7 +154,9 @@
# -------------------------------------------------------
token_permission_types = [
{token_type: 'guidances', text_description: 'allows a user access to the guidances api endpoint'},
- {token_type: 'plans', text_description: 'allows a user access to the plans api endpoint'}
+ {token_type: 'plans', text_description: 'allows a user access to the plans api endpoint'},
+ {token_type: 'templates', text_description: 'allows a user access to the templates api endpoint'},
+ {token_type: 'statistics', text_description: 'allows a user access to the statistics api endpoint'}
]
token_permission_types.map{ |tpt| TokenPermissionType.create!(tpt) if TokenPermissionType.find_by(token_type: tpt[:token_type]).nil? }
diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js
index 262a25d..9328f23 100644
--- a/lib/assets/javascripts/application.js
+++ b/lib/assets/javascripts/application.js
@@ -1,3 +1,6 @@
-import './views/devise/devise';
import './views/contacts/new';
+import './views/devise/invitations/edit';
+import './views/devise/passwords/edit';
+import './views/devise/passwords/new';
import './views/plans/edit_details';
+import './views/plans/share';
diff --git a/lib/assets/javascripts/constants.js b/lib/assets/javascripts/constants.js
index eabe1db..1ac6267 100644
--- a/lib/assets/javascripts/constants.js
+++ b/lib/assets/javascripts/constants.js
@@ -6,6 +6,7 @@
export const VALIDATION_MESSAGE_NUMBER = 'Please enter a valid number.';
export const VALIDATION_MESSAGE_PASSWORD = 'The password must be between 8 and 128 characters.';
export const VALIDATION_MESSAGE_PASSWORDS_MATCH = 'The passwords must match.';
+export const VALIDATION_MESSAGE_RADIO = 'Please choose one of the options.';
export const VALIDATION_MESSAGE_TEXT = 'This field is required.';
export const SHOW_PASSWORD_MESSAGE = 'Show password';
diff --git a/lib/assets/javascripts/spec/ariatiseFormSpec.js b/lib/assets/javascripts/spec/ariatiseFormSpec.js
new file mode 100644
index 0000000..439753d
--- /dev/null
+++ b/lib/assets/javascripts/spec/ariatiseFormSpec.js
@@ -0,0 +1,105 @@
+import ariatiseForm from '../utils/ariatiseForm';
+
+describe('ariatiseForm test suite', () => {
+ beforeAll(() => fixture.setBase('javascripts/spec/fixtures'));
+
+ beforeEach(() => {
+ this.submitButton = '[type="submit"]';
+ this.form = fixture.load('form.html');
+ ariatiseForm({ selector: `#${$('form').attr('id')}` });
+ // Override the form submission, we are just going to validate the ariatisation of the form
+ $('form').submit((e) => { e.preventDefault(); });
+ });
+
+ afterEach(() => {
+ fixture.cleanup();
+ });
+
+ it('adds an error message section to fields with `aria-required="true"` or `data-validation="[type]"`', () => {
+ $.each($('input'), (idx, el) => {
+ const block = $(`#${$(el).attr('aria-describedby')}`);
+ if ($(el).attr('aria-required') === 'true' || $(el).attr('data-validation')) {
+ // The error message should be present but not visible yet
+ expect(block.length).toEqual(1);
+ expect($(block)).not.toBeVisible();
+ } else {
+ expect(block.length).toEqual(0);
+ }
+ });
+ });
+
+ it('invalid data causes errors to appear', () => {
+ // const spyEvent = spyOnEvent(this.submitButton, 'click');
+ $(this.submitButton).click();
+
+ // TODO: For some reason the Spy does not catch the button click :/
+ // expect('click').toHaveBeenPreventedOn(this.submitButton);
+ // expect(spyEvent).toHaveBeenPrevented();
+
+ // Only the aria-required="true" errors should be visible
+ $.each($('input[aria-required="true"]'), (idx, el) => {
+ const block = $(`#${$(el).attr('aria-describedby')}`);
+ // The error message should be present but not visible yet
+ expect($(block)).toBeVisible();
+ });
+
+ // Inputs without aria-required="true" errors should not be visible
+ $.each($('input').not('[aria-required="true"]').not('[type="radio"]'), (idx, el) => {
+ const block = $(`#${$(el).attr('aria-describedby')}`);
+ // The error message should be present but not visible yet
+ expect($(block)).not.toBeVisible();
+ });
+ });
+
+ it('text validation is working', () => {
+ ['#text-required'].forEach((selector) => {
+ const block = $(`#${$(selector).attr('aria-describedby')}`);
+ $(selector).val('');
+ $(this.submitButton).click();
+ expect(block).toBeVisible();
+
+ $(selector).val('testing');
+ $(this.submitButton).click();
+ expect(block).not.toBeVisible();
+ });
+ });
+
+ it('email validation is working', () => {
+ ['#email-required', '#email-not-required-with-validation'].forEach((selector) => {
+ const block = $(`#${$(selector).attr('aria-describedby')}`);
+ $(selector).val('abcd1234');
+ $(this.submitButton).click();
+ expect(block).toBeVisible();
+
+ $(selector).val('abcd1234@test.org');
+ $(this.submitButton).click();
+ expect(block).not.toBeVisible();
+ });
+ });
+
+ it('password validation is working', () => {
+ ['#password-required', '#password-not-required-with-validation'].forEach((selector) => {
+ const block = $(`#${$(selector).attr('aria-describedby')}`);
+ $(selector).val('abc');
+ $(this.submitButton).click();
+ expect(block).toBeVisible();
+
+ $(selector).val('abcd1234');
+ $(this.submitButton).click();
+ expect(block).not.toBeVisible();
+ });
+ });
+
+ it('radio validation is working', () => {
+ ['[name="radio-required"][aria-required="true"]'].forEach((selector) => {
+ const block = $(`#${$(selector).attr('aria-describedby')}`);
+ $(`[name="${$(selector).attr('name')}"][value="a"]`).removeAttr('checked');
+ $(this.submitButton).click();
+ expect(block).toBeVisible();
+
+ $(`[name="${$(selector).attr('name')}"][value="a"]`).attr('checked', true);
+ $(this.submitButton).click();
+ expect(block).not.toBeVisible();
+ });
+ });
+});
diff --git a/lib/assets/javascripts/spec/debounceSpec.js b/lib/assets/javascripts/spec/debounceSpec.js
new file mode 100644
index 0000000..0aa8640
--- /dev/null
+++ b/lib/assets/javascripts/spec/debounceSpec.js
@@ -0,0 +1,68 @@
+import debounce from '../utils/debounce';
+
+describe('debounce test suite', () => {
+ let functionToDebounce;
+
+ beforeEach(() => {
+ functionToDebounce = jasmine.createSpy('My function to debounce');
+ jasmine.clock().install();
+ });
+
+ afterEach(() => {
+ jasmine.clock().uninstall();
+ });
+
+ it('functionToDebounce gets called after the time specified', () => {
+ const debounced = debounce(functionToDebounce, 1000);
+
+ debounced('foo', 'bar');
+
+ expect(functionToDebounce).not.toHaveBeenCalled();
+
+ jasmine.clock().tick(1001);
+
+ expect(functionToDebounce).toHaveBeenCalled();
+ expect(functionToDebounce.calls.first().args[0]).toBe('foo');
+ expect(functionToDebounce.calls.first().args[1]).toBe('bar');
+ });
+
+ it('functionToDebounce gets cancelled before time elapses', () => {
+ const debounced = debounce(functionToDebounce, 1000);
+
+ debounced('foo', 'bar');
+
+ jasmine.clock().tick(999);
+ debounced.cancel();
+ jasmine.clock().tick(2);
+
+ expect(functionToDebounce).not.toHaveBeenCalled();
+ });
+
+ it('functionToDebounce gets called once after the time specified', () => {
+ const debounced = debounce(functionToDebounce, 1000);
+
+ debounced('foo', 'bar');
+ jasmine.clock().tick(999);
+ debounced('foo', 'bar');
+ jasmine.clock().tick(999);
+ debounced('foo', 'bar');
+ jasmine.clock().tick(1001);
+
+ expect(functionToDebounce.calls.count()).toBe(1);
+ });
+
+ it('functionToDebounce gets called once after the time specified with args of last invocation', () => {
+ const debounced = debounce(functionToDebounce, 1000);
+
+ debounced('foo', 'bar');
+ jasmine.clock().tick(999);
+ debounced('foo2', 'bar2');
+ jasmine.clock().tick(999);
+ debounced('foo3', 'bar3');
+ jasmine.clock().tick(1001);
+
+ expect(functionToDebounce.calls.count()).toBe(1);
+ expect(functionToDebounce.calls.first().args[0]).toBe('foo3');
+ expect(functionToDebounce.calls.first().args[1]).toBe('bar3');
+ });
+});
diff --git a/lib/assets/javascripts/spec/fixtures/form.html b/lib/assets/javascripts/spec/fixtures/form.html
new file mode 100644
index 0000000..bf06e68
--- /dev/null
+++ b/lib/assets/javascripts/spec/fixtures/form.html
@@ -0,0 +1,68 @@
+
\ No newline at end of file
diff --git a/lib/assets/javascripts/spec/isTypeSpec.js b/lib/assets/javascripts/spec/isTypeSpec.js
new file mode 100644
index 0000000..fbfe768
--- /dev/null
+++ b/lib/assets/javascripts/spec/isTypeSpec.js
@@ -0,0 +1,146 @@
+import {
+ isArray,
+ isBoolean,
+ isDate,
+ isFunction,
+ isNumber,
+ isNull,
+ isObject,
+ isRegExp,
+ isString,
+ isUndefined } from '../utils/isType';
+
+describe('isArray test suite', () => {
+ it('expect true for []', () => expect(isArray([])).toBe(true));
+ it('expect false for Boolean', () => expect(isArray(true)).toBe(false));
+ it('expect false for Date', () => expect(isArray(new Date())).toBe(false));
+ it('expect false for Function', () => expect(isArray(() => {})).toBe(false));
+ it('expect false for Number', () => expect(isArray(1)).toBe(false));
+ it('expect false for Null', () => expect(isArray(null)).toBe(false));
+ it('expect false for Object', () => expect(isArray({})).toBe(false));
+ it('expect false for RegExp', () => expect(isArray(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isArray('Hello World!')).toBe(false));
+ it('expect false for Undefined', () => expect(isArray(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isArray()).toBe(false));
+});
+
+describe('isBoolean test suite', () => {
+ it('expect true for true', () => expect(isBoolean(true)).toBe(true));
+ it('expect true for false', () => expect(isBoolean(true)).toBe(true));
+ it('expect false for []', () => expect(isBoolean([])).toBe(false));
+ it('expect false for Date', () => expect(isBoolean(new Date())).toBe(false));
+ it('expect false for Function', () => expect(isBoolean(() => {})).toBe(false));
+ it('expect false for Number', () => expect(isBoolean(1)).toBe(false));
+ it('expect false for Null', () => expect(isBoolean(null)).toBe(false));
+ it('expect false for Object', () => expect(isBoolean({})).toBe(false));
+ it('expect false for RegExp', () => expect(isBoolean(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isBoolean('Hello World!')).toBe(false));
+ it('expect false for Undefined', () => expect(isBoolean(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isBoolean()).toBe(false));
+});
+
+describe('isDate test suite', () => {
+ it('expect true for Date', () => expect(isDate(new Date())).toBe(true));
+ it('expect fase for []', () => expect(isDate([])).toBe(false));
+ it('expect fase for Boolean', () => expect(isDate(true)).toBe(false));
+ it('expect fase for Function', () => expect(isDate(() => {})).toBe(false));
+ it('expect fase for Number', () => expect(isDate(1)).toBe(false));
+ it('expect fase for Null', () => expect(isDate(null)).toBe(false));
+ it('expect fase for Object', () => expect(isDate({})).toBe(false));
+ it('expect fase for RegExp', () => expect(isDate(/foo/)).toBe(false));
+ it('expect fase for String', () => expect(isDate('Hello World!')).toBe(false));
+ it('expect fase for zero args', () => expect(isDate(undefined)).toBe(false));
+});
+
+describe('isFunction test suite', () => {
+ it('expect true for Function', () => expect(isFunction(() => {})).toBe(true));
+ it('expect false for []', () => expect(isFunction([])).toBe(false));
+ it('expect false for Boolean', () => expect(isFunction(true)).toBe(false));
+ it('expect false for Date', () => expect(isFunction(new Date())).toBe(false));
+ it('expect false for Number', () => expect(isFunction(1)).toBe(false));
+ it('expect false for Null', () => expect(isFunction(null)).toBe(false));
+ it('expect false for Object', () => expect(isFunction({})).toBe(false));
+ it('expect false for RegExp', () => expect(isFunction(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isFunction('Hello World!')).toBe(false));
+ it('expect false for undefined', () => expect(isFunction(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isFunction()).toBe(false));
+});
+
+describe('isNumber test suite', () => {
+ it('expect true for 1', () => expect(isNumber(1)).toBe(true));
+ it('expect true for NaN', () => expect(isNumber(NaN)).toBe(true));
+ it('expect true for Infinity', () => expect(isNumber(Infinity)).toBe(true));
+ it('expect false for []', () => expect(isNumber([])).toBe(false));
+ it('expect false for Boolean', () => expect(isNumber(true)).toBe(false));
+ it('expect false for Date', () => expect(isNumber(new Date())).toBe(false));
+ it('expect false for Null', () => expect(isNumber(null)).toBe(false));
+ it('expect false for Object', () => expect(isNumber({})).toBe(false));
+ it('expect false for RegExp', () => expect(isNumber(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isNumber('Hello World!')).toBe(false));
+ it('expect false for undefined', () => expect(isNumber(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isNumber()).toBe(false));
+});
+
+describe('isNull test suite', () => {
+ it('expect true for Null', () => expect(isNull(null)).toBe(true));
+ it('expect false for []', () => expect(isNull([])).toBe(false));
+ it('expect false for Boolean', () => expect(isNull(true)).toBe(false));
+ it('expect false for Date', () => expect(isNull(new Date())).toBe(false));
+ it('expect false for Number', () => expect(isNull(1)).toBe(false));
+ it('expect false for Object', () => expect(isNull(Object.create(null))).toBe(false));
+ it('expect false for RegExp', () => expect(isNull(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isNull('null')).toBe(false));
+ it('expect false for undefined', () => expect(isNull(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isNull()).toBe(false));
+});
+
+describe('isObject test suite', () => {
+ it('expect true for {}', () => expect(isObject({})).toBe(true));
+ it('expect true for []', () => expect(isObject([])).toBe(true));
+ it('expect true for Date', () => expect(isObject(new Date())).toBe(true));
+ it('expect true for RegExp', () => expect(isObject(/foo/)).toBe(true));
+ it('expect false for Number', () => expect(isObject(1)).toBe(false));
+ it('expect false for Null', () => expect(isObject(null)).toBe(false));
+ it('expect false for String', () => expect(isObject('Hello World!')).toBe(false));
+ it('expect false for undefined', () => expect(isObject(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isObject()).toBe(false));
+});
+
+describe('isRegExp test suite', () => {
+ it('expect true for RegExp', () => expect(isRegExp(/foo/)).toBe(true));
+ it('expect true for RegExp', () => expect(isRegExp(new RegExp('foo'))).toBe(true));
+ it('expect false for []', () => expect(isRegExp([])).toBe(false));
+ it('expect false for Boolean', () => expect(isRegExp(true)).toBe(false));
+ it('expect false for Date', () => expect(isRegExp(new Date())).toBe(false));
+ it('expect false for Number', () => expect(isRegExp(1)).toBe(false));
+ it('expect false for Null', () => expect(isRegExp(null)).toBe(false));
+ it('expect false for String', () => expect(isRegExp('Hello World!')).toBe(false));
+ it('expect false for undefined', () => expect(isRegExp(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isRegExp()).toBe(false));
+});
+
+describe('isString test suite', () => {
+ it('expect true for String', () => expect(isString('Hello World!')).toBe(true));
+ it('expect false for []', () => expect(isString([])).toBe(false));
+ it('expect false for Boolean', () => expect(isString(true)).toBe(false));
+ it('expect false for Date', () => expect(isString(new Date())).toBe(false));
+ it('expect false for Function', () => expect(isString(() => {})).toBe(false));
+ it('expect false for Number', () => expect(isString(1)).toBe(false));
+ it('expect false for Null', () => expect(isString(null)).toBe(false));
+ it('expect false for RegExp', () => expect(isString(/foo/)).toBe(false));
+ it('expect false for Undefined', () => expect(isString(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isString()).toBe(false));
+});
+
+describe('isUndefined test suite', () => {
+ it('expect true for Undefined', () => expect(isUndefined(undefined)).toBe(true));
+ it('expect false for zero args', () => expect(isUndefined()).toBe(true));
+ it('expect false for []', () => expect(isUndefined([])).toBe(false));
+ it('expect false for Boolean', () => expect(isUndefined(true)).toBe(false));
+ it('expect false for Date', () => expect(isUndefined(new Date())).toBe(false));
+ it('expect false for Function', () => expect(isUndefined(() => {})).toBe(false));
+ it('expect false for Number', () => expect(isUndefined(1)).toBe(false));
+ it('expect false for Null', () => expect(isUndefined(null)).toBe(false));
+ it('expect false for RegExp', () => expect(isUndefined(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isUndefined('Hello World!')).toBe(false));
+});
diff --git a/lib/assets/javascripts/spec/isValidInputTypeSpec.js b/lib/assets/javascripts/spec/isValidInputTypeSpec.js
new file mode 100644
index 0000000..c90235f
--- /dev/null
+++ b/lib/assets/javascripts/spec/isValidInputTypeSpec.js
@@ -0,0 +1,43 @@
+import {
+ isValidEmail,
+ isValidNumber,
+ isValidPassword,
+ isValidText,
+} from '../utils/isValidInputType';
+
+describe('isValidEmail test suite', () => {
+ it('expect true for someone@somewhere.com', () => expect(isValidEmail('someone@somewhere.com')).toBe(true));
+ it('expect true for s@somewhere.ac.uk', () => expect(isValidEmail('s@somewhere.ac.uk')).toBe(true));
+ it('expect true for someone@somewhere.gov.ac.uk', () => expect(isValidEmail('someone@somewhere.gov.ac.uk')).toBe(true));
+ it('expect false for @somewhere.com', () => expect(isValidEmail('@somewhere.com')).toBe(false));
+ it('expect false for s@somewhere.ac.u', () => expect(isValidEmail('s@somewhere.ac.u')).toBe(false));
+ it('expect false for someone@somewhere.gov.ac.u', () => expect(isValidEmail('someone@somewhere.gov.ac.u')).toBe(false));
+});
+
+describe('isValidNumber test suite', () => {
+ it('expect true for 1', () => expect(isValidNumber(1)).toBe(true));
+ it('expect true for \'1\'', () => expect(isValidNumber('1')).toBe(true));
+ it('expect true for Infinity', () => expect(isValidNumber(Infinity)).toBe(true));
+ it('expect false for Array', () => expect(isValidNumber([])).toBe(false));
+ it('expect false for Boolean', () => expect(isValidNumber(true)).toBe(false));
+ it('expect false for Date', () => expect(isValidNumber(new Date())).toBe(false));
+ it('expect false for Function', () => expect(isValidNumber(() => {})).toBe(false));
+ it('expect false for Object', () => expect(isValidNumber({})).toBe(false));
+ it('expect false for RegExp', () => expect(isValidNumber(/foo/)).toBe(false));
+ it('expect false for String', () => expect(isValidNumber('Hello World!')).toBe(false));
+ it('expect false for Null', () => expect(isValidNumber(null)).toBe(false));
+ it('expect false for Array', () => expect(isValidNumber(undefined)).toBe(false));
+ it('expect false for zero args', () => expect(isValidNumber()).toBe(false));
+});
+
+describe('isValidPassword test suite', () => {
+ it('expect true for hjkl7890', () => expect(isValidPassword('hjkl7890')).toBe(true));
+ it('expect false for hjkl', () => expect(isValidPassword('hjkl')).toBe(false));
+ it('expect false for \' abcd \'', () => expect(isValidPassword(' abcd ')).toBe(false));
+ it('expect false for non-string', () => expect(isValidPassword(null)).toBe(false));
+});
+
+describe('isValid test suite', () => {
+ it('expect true for h', () => expect(isValidText('h')).toBe(true));
+ it('expect false for \' \'', () => expect(isValidText(' ')).toBe(false));
+});
diff --git a/lib/assets/javascripts/utils/ariatiseForm.js b/lib/assets/javascripts/utils/ariatiseForm.js
index a1f9264..2471742 100644
--- a/lib/assets/javascripts/utils/ariatiseForm.js
+++ b/lib/assets/javascripts/utils/ariatiseForm.js
@@ -1,3 +1,29 @@
+/*
+ This module allows you to add the necessary aria tags to your form elements to
+ make them accessible and wire up client-side error handling. Usage:
+
+ Required Fields
+ ------------------------
+ To make a field required just add the `aria-required="true"` attribute to the
+ input element. The element's `type` attribute will be used to determine what
+ validation method will be used.
+ Example: ``
+
+ Validation for fields that are not required
+ ------------------------
+ To add validation to a field that is not required, just add the
+ `data-validation=""` to the input element. Validation checks will only
+ be run if the field has a value.
+ Example: ``
+
+ Validation for radio buttons
+ ------------------------
+ To add validation to a set of `radio` buttons, use the rules listed above,
+ but you should only attach them to the last `` in the set.
+ Example: `
+ `
+*/
+
import { isObject, isString, isBoolean } from './isType';
import * as constants from '../constants';
import * as validator from './isValidInputType';
@@ -51,6 +77,15 @@
return false;
};
+const getValue = (type, el) => {
+ switch (type) {
+ case 'radio':
+ return $(el).closest('form').find(`input[name="${$(el).attr('name')}"]:checked`).val();
+ default:
+ return $(el).val();
+ }
+};
+
const isValid = (type, value) => {
// TODO add more validation for each new type coming along by:
// 1. defining a function at dmproadmap.utils.validate
@@ -66,6 +101,8 @@
return validator.isValidEmail(value);
case 'password':
return validator.isValidPassword(value);
+ case 'radio':
+ return validator.isValidText(value);
default:
return false;
}
@@ -81,6 +118,8 @@
return constants.VALIDATION_MESSAGE_EMAIL;
case 'password':
return constants.VALIDATION_MESSAGE_PASSWORD;
+ case 'radio':
+ return constants.VALIDATION_MESSAGE_RADIO;
default:
return constants.VALIDATION_MESSAGE_DEFAULT;
}
@@ -116,7 +155,7 @@
// If the field is required OR its not empty
if (required || $(el).val().trim() !== '') {
- if (isValid(type, $(el).val())) {
+ if (isValid(type, getValue(type, el))) {
valid(el);
} else {
e.preventDefault();
diff --git a/lib/assets/javascripts/utils/debounceSpec.js b/lib/assets/javascripts/utils/debounceSpec.js
deleted file mode 100644
index c5803df..0000000
--- a/lib/assets/javascripts/utils/debounceSpec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import debounce from './debounce';
-
-describe('debounce test suite', () => {
- let functionToDebounce;
-
- beforeEach(() => {
- functionToDebounce = jasmine.createSpy('My function to debounce');
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- it('functionToDebounce gets called after the time specified', () => {
- const debounced = debounce(functionToDebounce, 1000);
-
- debounced('foo', 'bar');
-
- expect(functionToDebounce).not.toHaveBeenCalled();
-
- jasmine.clock().tick(1001);
-
- expect(functionToDebounce).toHaveBeenCalled();
- expect(functionToDebounce.calls.first().args[0]).toBe('foo');
- expect(functionToDebounce.calls.first().args[1]).toBe('bar');
- });
-
- it('functionToDebounce gets cancelled before time elapses', () => {
- const debounced = debounce(functionToDebounce, 1000);
-
- debounced('foo', 'bar');
-
- jasmine.clock().tick(999);
- debounced.cancel();
- jasmine.clock().tick(2);
-
- expect(functionToDebounce).not.toHaveBeenCalled();
- });
-
- it('functionToDebounce gets called once after the time specified', () => {
- const debounced = debounce(functionToDebounce, 1000);
-
- debounced('foo', 'bar');
- jasmine.clock().tick(999);
- debounced('foo', 'bar');
- jasmine.clock().tick(999);
- debounced('foo', 'bar');
- jasmine.clock().tick(1001);
-
- expect(functionToDebounce.calls.count()).toBe(1);
- });
-
- it('functionToDebounce gets called once after the time specified with args of last invocation', () => {
- const debounced = debounce(functionToDebounce, 1000);
-
- debounced('foo', 'bar');
- jasmine.clock().tick(999);
- debounced('foo2', 'bar2');
- jasmine.clock().tick(999);
- debounced('foo3', 'bar3');
- jasmine.clock().tick(1001);
-
- expect(functionToDebounce.calls.count()).toBe(1);
- expect(functionToDebounce.calls.first().args[0]).toBe('foo3');
- expect(functionToDebounce.calls.first().args[1]).toBe('bar3');
- });
-});
diff --git a/lib/assets/javascripts/utils/isTypeSpec.js b/lib/assets/javascripts/utils/isTypeSpec.js
deleted file mode 100644
index f85ef1a..0000000
--- a/lib/assets/javascripts/utils/isTypeSpec.js
+++ /dev/null
@@ -1,146 +0,0 @@
-import {
- isArray,
- isBoolean,
- isDate,
- isFunction,
- isNumber,
- isNull,
- isObject,
- isRegExp,
- isString,
- isUndefined } from './isType';
-
-describe('isArray test suite', () => {
- it('expect true for []', () => expect(isArray([])).toBe(true));
- it('expect false for Boolean', () => expect(isArray(true)).toBe(false));
- it('expect false for Date', () => expect(isArray(new Date())).toBe(false));
- it('expect false for Function', () => expect(isArray(() => {})).toBe(false));
- it('expect false for Number', () => expect(isArray(1)).toBe(false));
- it('expect false for Null', () => expect(isArray(null)).toBe(false));
- it('expect false for Object', () => expect(isArray({})).toBe(false));
- it('expect false for RegExp', () => expect(isArray(/foo/)).toBe(false));
- it('expect false for String', () => expect(isArray('Hello World!')).toBe(false));
- it('expect false for Undefined', () => expect(isArray(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isArray()).toBe(false));
-});
-
-describe('isBoolean test suite', () => {
- it('expect true for true', () => expect(isBoolean(true)).toBe(true));
- it('expect true for false', () => expect(isBoolean(true)).toBe(true));
- it('expect false for []', () => expect(isBoolean([])).toBe(false));
- it('expect false for Date', () => expect(isBoolean(new Date())).toBe(false));
- it('expect false for Function', () => expect(isBoolean(() => {})).toBe(false));
- it('expect false for Number', () => expect(isBoolean(1)).toBe(false));
- it('expect false for Null', () => expect(isBoolean(null)).toBe(false));
- it('expect false for Object', () => expect(isBoolean({})).toBe(false));
- it('expect false for RegExp', () => expect(isBoolean(/foo/)).toBe(false));
- it('expect false for String', () => expect(isBoolean('Hello World!')).toBe(false));
- it('expect false for Undefined', () => expect(isBoolean(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isBoolean()).toBe(false));
-});
-
-describe('isDate test suite', () => {
- it('expect true for Date', () => expect(isDate(new Date())).toBe(true));
- it('expect fase for []', () => expect(isDate([])).toBe(false));
- it('expect fase for Boolean', () => expect(isDate(true)).toBe(false));
- it('expect fase for Function', () => expect(isDate(() => {})).toBe(false));
- it('expect fase for Number', () => expect(isDate(1)).toBe(false));
- it('expect fase for Null', () => expect(isDate(null)).toBe(false));
- it('expect fase for Object', () => expect(isDate({})).toBe(false));
- it('expect fase for RegExp', () => expect(isDate(/foo/)).toBe(false));
- it('expect fase for String', () => expect(isDate('Hello World!')).toBe(false));
- it('expect fase for zero args', () => expect(isDate(undefined)).toBe(false));
-});
-
-describe('isFunction test suite', () => {
- it('expect true for Function', () => expect(isFunction(() => {})).toBe(true));
- it('expect false for []', () => expect(isFunction([])).toBe(false));
- it('expect false for Boolean', () => expect(isFunction(true)).toBe(false));
- it('expect false for Date', () => expect(isFunction(new Date())).toBe(false));
- it('expect false for Number', () => expect(isFunction(1)).toBe(false));
- it('expect false for Null', () => expect(isFunction(null)).toBe(false));
- it('expect false for Object', () => expect(isFunction({})).toBe(false));
- it('expect false for RegExp', () => expect(isFunction(/foo/)).toBe(false));
- it('expect false for String', () => expect(isFunction('Hello World!')).toBe(false));
- it('expect false for undefined', () => expect(isFunction(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isFunction()).toBe(false));
-});
-
-describe('isNumber test suite', () => {
- it('expect true for 1', () => expect(isNumber(1)).toBe(true));
- it('expect true for NaN', () => expect(isNumber(NaN)).toBe(true));
- it('expect true for Infinity', () => expect(isNumber(Infinity)).toBe(true));
- it('expect false for []', () => expect(isNumber([])).toBe(false));
- it('expect false for Boolean', () => expect(isNumber(true)).toBe(false));
- it('expect false for Date', () => expect(isNumber(new Date())).toBe(false));
- it('expect false for Null', () => expect(isNumber(null)).toBe(false));
- it('expect false for Object', () => expect(isNumber({})).toBe(false));
- it('expect false for RegExp', () => expect(isNumber(/foo/)).toBe(false));
- it('expect false for String', () => expect(isNumber('Hello World!')).toBe(false));
- it('expect false for undefined', () => expect(isNumber(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isNumber()).toBe(false));
-});
-
-describe('isNull test suite', () => {
- it('expect true for Null', () => expect(isNull(null)).toBe(true));
- it('expect false for []', () => expect(isNull([])).toBe(false));
- it('expect false for Boolean', () => expect(isNull(true)).toBe(false));
- it('expect false for Date', () => expect(isNull(new Date())).toBe(false));
- it('expect false for Number', () => expect(isNull(1)).toBe(false));
- it('expect false for Object', () => expect(isNull(Object.create(null))).toBe(false));
- it('expect false for RegExp', () => expect(isNull(/foo/)).toBe(false));
- it('expect false for String', () => expect(isNull('null')).toBe(false));
- it('expect false for undefined', () => expect(isNull(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isNull()).toBe(false));
-});
-
-describe('isObject test suite', () => {
- it('expect true for {}', () => expect(isObject({})).toBe(true));
- it('expect true for []', () => expect(isObject([])).toBe(true));
- it('expect true for Date', () => expect(isObject(new Date())).toBe(true));
- it('expect true for RegExp', () => expect(isObject(/foo/)).toBe(true));
- it('expect false for Number', () => expect(isObject(1)).toBe(false));
- it('expect false for Null', () => expect(isObject(null)).toBe(false));
- it('expect false for String', () => expect(isObject('Hello World!')).toBe(false));
- it('expect false for undefined', () => expect(isObject(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isObject()).toBe(false));
-});
-
-describe('isRegExp test suite', () => {
- it('expect true for RegExp', () => expect(isRegExp(/foo/)).toBe(true));
- it('expect true for RegExp', () => expect(isRegExp(new RegExp('foo'))).toBe(true));
- it('expect false for []', () => expect(isRegExp([])).toBe(false));
- it('expect false for Boolean', () => expect(isRegExp(true)).toBe(false));
- it('expect false for Date', () => expect(isRegExp(new Date())).toBe(false));
- it('expect false for Number', () => expect(isRegExp(1)).toBe(false));
- it('expect false for Null', () => expect(isRegExp(null)).toBe(false));
- it('expect false for String', () => expect(isRegExp('Hello World!')).toBe(false));
- it('expect false for undefined', () => expect(isRegExp(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isRegExp()).toBe(false));
-});
-
-describe('isString test suite', () => {
- it('expect true for String', () => expect(isString('Hello World!')).toBe(true));
- it('expect false for []', () => expect(isString([])).toBe(false));
- it('expect false for Boolean', () => expect(isString(true)).toBe(false));
- it('expect false for Date', () => expect(isString(new Date())).toBe(false));
- it('expect false for Function', () => expect(isString(() => {})).toBe(false));
- it('expect false for Number', () => expect(isString(1)).toBe(false));
- it('expect false for Null', () => expect(isString(null)).toBe(false));
- it('expect false for RegExp', () => expect(isString(/foo/)).toBe(false));
- it('expect false for Undefined', () => expect(isString(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isString()).toBe(false));
-});
-
-describe('isUndefined test suite', () => {
- it('expect true for Undefined', () => expect(isUndefined(undefined)).toBe(true));
- it('expect false for zero args', () => expect(isUndefined()).toBe(true));
- it('expect false for []', () => expect(isUndefined([])).toBe(false));
- it('expect false for Boolean', () => expect(isUndefined(true)).toBe(false));
- it('expect false for Date', () => expect(isUndefined(new Date())).toBe(false));
- it('expect false for Function', () => expect(isUndefined(() => {})).toBe(false));
- it('expect false for Number', () => expect(isUndefined(1)).toBe(false));
- it('expect false for Null', () => expect(isUndefined(null)).toBe(false));
- it('expect false for RegExp', () => expect(isUndefined(/foo/)).toBe(false));
- it('expect false for String', () => expect(isUndefined('Hello World!')).toBe(false));
-});
diff --git a/lib/assets/javascripts/utils/isValidInputType.js b/lib/assets/javascripts/utils/isValidInputType.js
index 6073730..5fcfc94 100644
--- a/lib/assets/javascripts/utils/isValidInputType.js
+++ b/lib/assets/javascripts/utils/isValidInputType.js
@@ -53,4 +53,3 @@
}
return false;
};
-
diff --git a/lib/assets/javascripts/utils/isValidInputTypeSpec.js b/lib/assets/javascripts/utils/isValidInputTypeSpec.js
deleted file mode 100644
index 6eaf31f..0000000
--- a/lib/assets/javascripts/utils/isValidInputTypeSpec.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import {
- isValidEmail,
- isValidNumber,
- isValidPassword,
- isValidText,
-} from './isValidInputType';
-
-describe('isValidEmail test suite', () => {
- it('expect true for someone@somewhere.com', () => expect(isValidEmail('someone@somewhere.com')).toBe(true));
- it('expect true for s@somewhere.ac.uk', () => expect(isValidEmail('s@somewhere.ac.uk')).toBe(true));
- it('expect true for someone@somewhere.gov.ac.uk', () => expect(isValidEmail('someone@somewhere.gov.ac.uk')).toBe(true));
- it('expect false for @somewhere.com', () => expect(isValidEmail('@somewhere.com')).toBe(false));
- it('expect false for s@somewhere.ac.u', () => expect(isValidEmail('s@somewhere.ac.u')).toBe(false));
- it('expect false for someone@somewhere.gov.ac.u', () => expect(isValidEmail('someone@somewhere.gov.ac.u')).toBe(false));
-});
-
-describe('isValidNumber test suite', () => {
- it('expect true for 1', () => expect(isValidNumber(1)).toBe(true));
- it('expect true for \'1\'', () => expect(isValidNumber('1')).toBe(true));
- it('expect true for Infinity', () => expect(isValidNumber(Infinity)).toBe(true));
- it('expect false for Array', () => expect(isValidNumber([])).toBe(false));
- it('expect false for Boolean', () => expect(isValidNumber(true)).toBe(false));
- it('expect false for Date', () => expect(isValidNumber(new Date())).toBe(false));
- it('expect false for Function', () => expect(isValidNumber(() => {})).toBe(false));
- it('expect false for Object', () => expect(isValidNumber({})).toBe(false));
- it('expect false for RegExp', () => expect(isValidNumber(/foo/)).toBe(false));
- it('expect false for String', () => expect(isValidNumber('Hello World!')).toBe(false));
- it('expect false for Null', () => expect(isValidNumber(null)).toBe(false));
- it('expect false for Array', () => expect(isValidNumber(undefined)).toBe(false));
- it('expect false for zero args', () => expect(isValidNumber()).toBe(false));
-});
-
-describe('isValidPassword test suite', () => {
- it('expect true for hjkl7890', () => expect(isValidPassword('hjkl7890')).toBe(true));
- it('expect false for hjkl', () => expect(isValidPassword('hjkl')).toBe(false));
- it('expect false for \' abcd \'', () => expect(isValidPassword(' abcd ')).toBe(false));
- it('expect false for non-string', () => expect(isValidPassword(null)).toBe(false));
-});
-
-describe('isValid test suite', () => {
- it('expect true for h', () => expect(isValidText('h')).toBe(true));
- it('expect false for \' \'', () => expect(isValidText(' ')).toBe(false));
-});
diff --git a/lib/assets/javascripts/views/devise/devise.js b/lib/assets/javascripts/views/devise/devise.js
deleted file mode 100644
index 695b5ba..0000000
--- a/lib/assets/javascripts/views/devise/devise.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import ariatiseForm from '../../utils/ariatiseForm';
-import { addMatchingPasswordValidator, togglisePasswords } from '../../utils/passwordHelper';
-import { SHOW_SELECT_ORG_MESSAGE, SHOW_OTHER_ORG_MESSAGE } from '../../constants';
-
-/*
- Ariatise all of the devise forms
-*/
-$(() => {
- ariatiseForm({ selector: '#sign_in_form' });
- ariatiseForm({ selector: '#create_account_form' });
- ariatiseForm({ selector: '#user_request_reset_password_form' });
- ariatiseForm({ selector: '#user_reset_password_form' });
- ariatiseForm({ selector: '#invitation_create_account_form' });
-
- addMatchingPasswordValidator({ selector: '#user_reset_password_form' });
-
- togglisePasswords({ selector: '#sign_in_form' });
- togglisePasswords({ selector: '#create_account_form' });
- togglisePasswords({ selector: '#user_reset_password_form' });
-
- $('#other_org_link').click((e) => {
- e.preventDefault();
- const other = $('#user_other_organisation');
- const selector = $('.combobox-container');
- if ($(other).css('display') === 'none') {
- $('#other_org_link').text(SHOW_SELECT_ORG_MESSAGE);
- $(selector).hide();
- $(other).show();
- } else {
- $('#other_org_link').text(SHOW_OTHER_ORG_MESSAGE);
- $(selector).show();
- $(other).val('').hide();
- }
- });
-});
-
diff --git a/lib/assets/javascripts/views/devise/invitations/edit.js b/lib/assets/javascripts/views/devise/invitations/edit.js
new file mode 100644
index 0000000..3ad30db
--- /dev/null
+++ b/lib/assets/javascripts/views/devise/invitations/edit.js
@@ -0,0 +1,5 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+
+$(() => {
+ ariatiseForm({ selector: '#invitation_create_account_form' });
+});
diff --git a/lib/assets/javascripts/views/devise/passwords/edit.js b/lib/assets/javascripts/views/devise/passwords/edit.js
new file mode 100644
index 0000000..b4b91a5
--- /dev/null
+++ b/lib/assets/javascripts/views/devise/passwords/edit.js
@@ -0,0 +1,8 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+import { addMatchingPasswordValidator, togglisePasswords } from '../../../utils/passwordHelper';
+
+$(() => {
+ ariatiseForm({ selector: '#user_reset_password_form' });
+ addMatchingPasswordValidator({ selector: '#user_reset_password_form' });
+ togglisePasswords({ selector: '#user_reset_password_form' });
+});
diff --git a/lib/assets/javascripts/views/devise/passwords/new.js b/lib/assets/javascripts/views/devise/passwords/new.js
new file mode 100644
index 0000000..0abfa4b
--- /dev/null
+++ b/lib/assets/javascripts/views/devise/passwords/new.js
@@ -0,0 +1,5 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+
+$(() => {
+ ariatiseForm({ selector: '#user_request_reset_password_form' });
+});
diff --git a/lib/assets/javascripts/views/plans/share.js b/lib/assets/javascripts/views/plans/share.js
index b221b47..7b54f68 100644
--- a/lib/assets/javascripts/views/plans/share.js
+++ b/lib/assets/javascripts/views/plans/share.js
@@ -1,43 +1,6 @@
-$(document).ready(function(){
- /*----------------
- Listener for changes in access-level for a plan shared with a user
- TODO partial update instead of forcing a page reload
- ------------------*/
- $(".toggle-existing-user-access").change(function(){
- var params = {role: {access_level: $(this).find("option:checked").val()}};
- asyncRequest({
- url: "/roles/" + $(this).closest("form").find("#role_id").val(),
- type: 'PUT',
- data: JSON.stringify(params)
- });
- });
-
- // Run the input validations when the focus changes
- $("#role_user_email").on('blur', function(){
- toggleFormElementError(this, validateEmail($(this).val().trim()));
- });
-
- // See if we should enable the add collaborator button
- $("#role_user_email").on('change keyup', function(){
- toggleAddCollaboratorSubmit();
- });
- $("input[name='role[access_level]']").on('click', function(){
- toggleAddCollaboratorSubmit();
- });
-
- $("input[name='plan[visibility]']").on('click, change', function(e){
- var params = {plan: {visibility: $("input[name='plan[visibility]']:checked").val()}};
- asyncRequest({
- url: "/plans/" + $("#plan_id").val() + "/visibility",
- type: 'POST',
- data: JSON.stringify(params)
- });
- });
-
- // Display the submit button only if there is a valid email and password
- function toggleAddCollaboratorSubmit(){
- var disabled = (validateEmail($("#role_user_email").val()) != '' ||
- $("input[name='role[access_level]']:checked").val() == undefined);
- $("#add-collaborator-button").attr('aria-disabled', disabled);
- }
+import ariatiseForm from '../../utils/ariatiseForm';
+
+$().ready(() => {
+ // Invite Collaborators form on the Share page
+ ariatiseForm({ selector: '#new_role' });
});
diff --git a/lib/assets/javascripts/views/shared/create_account_form.js b/lib/assets/javascripts/views/shared/create_account_form.js
new file mode 100644
index 0000000..da63fd1
--- /dev/null
+++ b/lib/assets/javascripts/views/shared/create_account_form.js
@@ -0,0 +1,23 @@
+import ariatiseForm from '../../utils/ariatiseForm';
+import togglisePasswords from '../../utils/passwordHelper';
+import { SHOW_SELECT_ORG_MESSAGE, SHOW_OTHER_ORG_MESSAGE } from '../../constants';
+
+$(() => {
+ ariatiseForm({ selector: '#create_account_form' });
+ togglisePasswords({ selector: '#create_account_form' });
+
+ $('#other_org_link').click((e) => {
+ e.preventDefault();
+ const other = $('#user_other_organisation');
+ const selector = $('.combobox-container');
+ if ($(other).css('display') === 'none') {
+ $('#other_org_link').text(SHOW_SELECT_ORG_MESSAGE);
+ $(selector).hide();
+ $(other).show();
+ } else {
+ $('#other_org_link').text(SHOW_OTHER_ORG_MESSAGE);
+ $(selector).show();
+ $(other).val('').hide();
+ }
+ });
+});
diff --git a/lib/assets/javascripts/views/shared/login_form.js b/lib/assets/javascripts/views/shared/login_form.js
deleted file mode 100644
index c081110..0000000
--- a/lib/assets/javascripts/views/shared/login_form.js
+++ /dev/null
@@ -1,52 +0,0 @@
-$(document).ready(function(){
- if($("form.login-form").length > 0){
- // If the hidden valid-form field is set to true then enable the submit button
- $("form.login-form #valid-form").change(function(){
- $(this).siblings(".form-submit").attr('aria-disabled', $(this).val() != "true");
- });
-
- // See if we should enable the submit button when a required input changes
- $("form.login-form input[class*='required']").on('change keyup', function(){
- toggleLogInSubmit();
- });
-
- // Run the input validations when the focus changes
- $("form.login-form #user_email").on('blur', function(){
- toggleFormElementError(this, validateEmail($(this).val().trim()));
- });
- $("form.login-form #user_password").on('blur', function(){
- toggleFormElementError(this, validatePassword($(this).val().trim()));
- });
-
- // Toggle the password field so that its visible/masked
- $("form.login-form #password_show").click(function(){
- var typ = $("form.login-form #user_password").attr('type');
- $("form.login-form #user_password").attr('type', (typ === 'password' ? 'text' : 'password'));
- });
-
- // Run the validations in case the page was refreshed
- toggleFormElementError($("form.login-form #user_email"),
- validateEmail($("form.login-form #user_email").val().trim()));
- toggleFormElementError($("form.login-form #user_password"),
- validatePassword($("form.login-form #user_password").val().trim()));
-
- // Make sure the show password checkbox is unchecked on load
- $("form.login-form #password_show").attr("checked", false);
-
- // Pressing enter should submit the login form NOT the omniauth buttons!
- $("form.login-form").keypress(function(e){
- if(e.keyCode == 13){
- $("#sign-in-button").click();
- return false;
- }
- });
-
- // Display the submit button only if there is a valid email and password
- function toggleLogInSubmit(){
- var disabled = (validateEmail($("form.login-form #user_email").val()) != '' ||
- validatePassword($("form.login-form #user_password").val()) != '');
- $("form.login-form #sign-in-button").attr('aria-disabled', disabled);
- }
- }
-});
-
diff --git a/lib/assets/javascripts/views/shared/register_form.js b/lib/assets/javascripts/views/shared/register_form.js
deleted file mode 100644
index f3e9824..0000000
--- a/lib/assets/javascripts/views/shared/register_form.js
+++ /dev/null
@@ -1,79 +0,0 @@
-$(document).ready(function(){
- if($("form.register-form").length > 0){
- // If the hidden valid-form field is set to true then enable the submit button
- $("form.register-form #valid-form").change(function(){
- $(this).siblings(".form-submit").attr('aria-disabled', $(this).val() != "true");
- });
-
- // See if we should enable the submit button when a required input changes
- $("form.register-form input[class*='required'], #other-org-name, #user_org_name").on('change keyup', function(){
- toggleRegisterSubmit();
- });
-
- // Run the input validations when the focus changes
- $("form.register-form #user_email, form.register-form #user_recovery_email").on('blur change', function(){
- var msg = validateEmail($(this).val().trim());
- // If the standard email validation was successful validate that they do not match
- toggleFormElementError(this, (msg != '' ? msg : validateEmailsDoNotMatch()));
- });
- $("form.register-form #user_password").on('blur change', function(){
- toggleFormElementError(this, validatePassword($(this).val().trim()));
- });
-
- // Toggle the password field so that its visible/masked
- $("form.register-form #password_show").click(function(){
- var typ = $("form.register-form #user_password").attr('type');
- $("form.register-form #user_password").attr('type', (typ === 'password' ? 'text' : 'password'));
- });
-
- $('#user_org_name').on("change", function(e) {
- e.preventDefault();
- var selected_org = $(this).val();
- var other_orgs = $("#other-org-name").attr("data-orgs").split(",");
- var index = $.inArray(selected_org, other_orgs);
- if (index > -1) {
- $("#other-org-name").show();
- $("#user_other_organisation").focus();
- }
- else {
- $("#other-org-name").hide();
- $("#user_other_organisation").val("");
- }
- });
- $("#other-org-link > a").click(function(e){
- e.preventDefault();
- var other_org = $("#other-org-name").attr("data-orgs").split(",");
- $("#user_org_name").val("");
- $("#user_org_id").val("");
- $("#user_org_name").change();
- });
-
- // Run the validations in case the page was refreshed
- toggleFormElementError($("form.register-form #user_email"),
- validateEmail($("form.register-form #user_email").val().trim()));
- toggleFormElementError($("form.register-form #user_recovery_email"),
- validateEmail($("form.register-form #user_recovery_email").val().trim()));
- toggleFormElementError($("form.register-form #user_password"),
- validatePassword($("form.register-form #user_password").val().trim()));
-
- // Make sure the show password checkbox is unchecked on load
- $("form.register-form #password_show").attr("checked", false);
-
- function validateEmailsDoNotMatch(){
- var email = $("form.register-form #user_email").val().trim();
- var recovery = $("form.register-form #user_recovery_email").val().trim();
- return (email === recovery ? (email != '' ? __('Emails must be different') : '') : '');
- }
-
- function toggleRegisterSubmit(){
- var disabled = ($("form.register-form #user_firstname").val().trim().length <= 0 ||
- $("form.register-form #user_surname").val().trim().length <= 0 ||
- validateEmail($("form.register-form #user_email").val()) != '' ||
- validateEmail($("form.register-form #user_recovery_email").val()) != '' ||
- !$("form.register-form #user_accept_terms").prop('checked') ||
- $("form.register-form #user_email").val() === $("form.register-form #user_recovery_email").val() ||
- ($("form.register-form #user_org_name").val().trim().length <=0 && $("form.register-form #user_other_organisation").val().trim().length <= 0));
- $("form.register-form #register-button").attr('aria-disabled', disabled);
- }
- }
-});
diff --git a/lib/assets/javascripts/views/shared/sign_in_form.js b/lib/assets/javascripts/views/shared/sign_in_form.js
new file mode 100644
index 0000000..c906dd3
--- /dev/null
+++ b/lib/assets/javascripts/views/shared/sign_in_form.js
@@ -0,0 +1,7 @@
+import ariatiseForm from '../../utils/ariatiseForm';
+import togglisePasswords from '../../utils/passwordHelper';
+
+$(() => {
+ ariatiseForm({ selector: '#sign_in_form' });
+ togglisePasswords({ selector: '#sign_in_form' });
+});
diff --git a/lib/assets/karma.conf.js b/lib/assets/karma.conf.js
index 6e5f5d4..a48ab6e 100644
--- a/lib/assets/karma.conf.js
+++ b/lib/assets/karma.conf.js
@@ -7,15 +7,15 @@
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
-
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
- frameworks: ['jasmine', 'jquery-3.2.1'],
+ frameworks: ['fixture', 'jquery-3.2.1', 'jasmine-jquery', 'jasmine'],
// list of files / patterns to load in the browser
files: [
'./node_modules/phantomjs-polyfill/bind-polyfill.js',
'./javascripts/**/*Spec.js',
+ 'javascripts/spec/fixtures/**/*',
],
@@ -28,6 +28,8 @@
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'./javascripts/**/*Spec.js': ['webpack'],
+ '**/*.html': ['html2js'],
+ '**/*.json': ['json_fixtures'],
},
webpack: webpackConfig,
@@ -67,5 +69,9 @@
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
+
+ jsonFixturesPreprocessor: {
+ variableName: '__json__',
+ },
});
};
diff --git a/lib/assets/package-lock.json b/lib/assets/package-lock.json
index baa18ec..8c8ace3 100644
--- a/lib/assets/package-lock.json
+++ b/lib/assets/package-lock.json
@@ -141,6 +141,12 @@
"integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==",
"dev": true
},
+ "archy": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-0.0.2.tgz",
+ "integrity": "sha1-kQ9Dv2YUH8M1VkWXq8GJ30Sz014=",
+ "dev": true
+ },
"are-we-there-yet": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
@@ -175,12 +181,30 @@
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+ "dev": true
+ },
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
"dev": true
},
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+ "dev": true
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+ "dev": true
+ },
"array-slice": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
@@ -922,12 +946,57 @@
"integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=",
"dev": true
},
+ "binary": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
+ "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
+ "dev": true,
+ "requires": {
+ "buffers": "0.1.1",
+ "chainsaw": "0.1.0"
+ }
+ },
"binary-extensions": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
"integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
"dev": true
},
+ "bl": {
+ "version": "0.9.5",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz",
+ "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
"blob": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
@@ -1004,6 +1073,806 @@
"resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz",
"integrity": "sha1-ZZbHq0D2Y3OTMjqwvIDQZPxjBJg="
},
+ "bower": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.0.tgz",
+ "integrity": "sha1-Vdvr7wrZFVOC2enT5JfBNyNFtEo=",
+ "dev": true
+ },
+ "bower-config": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-0.5.2.tgz",
+ "integrity": "sha1-H30uiZ6ZtwwpphPnDUxkWQQUsi4=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "2.0.3",
+ "mout": "0.9.1",
+ "optimist": "0.6.1",
+ "osenv": "0.0.3"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
+ "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
+ "dev": true
+ },
+ "osenv": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.0.3.tgz",
+ "integrity": "sha1-zWrY3bKQkVrZ4idlV2Al1BHynLY=",
+ "dev": true
+ }
+ }
+ },
+ "bower-endpoint-parser": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz",
+ "integrity": "sha1-ALVlrb+rby01rd3pd+l5Yqy8s/Y=",
+ "dev": true
+ },
+ "bower-installer": {
+ "version": "git://github.com/bessdsv/bower-installer.git#7f9cece1e6fada50f44dc0851e1d85815cd1b4a7",
+ "dev": true,
+ "requires": {
+ "async": "0.2.10",
+ "bower": "1.3.12",
+ "colors": "0.6.2",
+ "glob": "3.2.11",
+ "lodash": "0.9.2",
+ "mkdirp": "0.3.5",
+ "node-fs": "0.1.7",
+ "nopt": "2.1.2"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+ "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+ "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.1.11",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz",
+ "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=",
+ "dev": true,
+ "optional": true
+ },
+ "assert-plus": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
+ "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=",
+ "dev": true,
+ "optional": true
+ },
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz",
+ "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=",
+ "dev": true,
+ "optional": true
+ },
+ "boom": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz",
+ "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=",
+ "dev": true,
+ "requires": {
+ "hoek": "0.9.1"
+ }
+ },
+ "bower": {
+ "version": "1.3.12",
+ "resolved": "https://registry.npmjs.org/bower/-/bower-1.3.12.tgz",
+ "integrity": "sha1-N94O2zkEuvkK7hM4Sho3mgXuIUw=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9",
+ "archy": "0.0.2",
+ "bower-config": "0.5.2",
+ "bower-endpoint-parser": "0.2.2",
+ "bower-json": "0.4.0",
+ "bower-logger": "0.2.2",
+ "bower-registry-client": "0.2.4",
+ "cardinal": "0.4.0",
+ "chalk": "0.5.0",
+ "chmodr": "0.1.0",
+ "decompress-zip": "0.0.8",
+ "fstream": "1.0.11",
+ "fstream-ignore": "1.0.5",
+ "glob": "4.0.6",
+ "graceful-fs": "3.0.11",
+ "handlebars": "2.0.0",
+ "inquirer": "0.7.1",
+ "insight": "0.4.3",
+ "is-root": "1.0.0",
+ "junk": "1.0.3",
+ "lockfile": "1.0.3",
+ "lru-cache": "2.5.2",
+ "mkdirp": "0.5.0",
+ "mout": "0.9.1",
+ "nopt": "3.0.6",
+ "opn": "1.0.2",
+ "osenv": "0.1.0",
+ "p-throttler": "0.1.0",
+ "promptly": "0.2.0",
+ "q": "1.0.1",
+ "request": "2.42.0",
+ "request-progress": "0.3.0",
+ "retry": "0.6.0",
+ "rimraf": "2.2.8",
+ "semver": "2.3.2",
+ "shell-quote": "1.4.3",
+ "stringify-object": "1.0.1",
+ "tar-fs": "0.5.2",
+ "tmp": "0.0.23",
+ "update-notifier": "0.2.0",
+ "which": "1.0.9"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.6.tgz",
+ "integrity": "sha1-aVxQvdTi+1xdNwsJHziNNwfikac=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "3.0.11",
+ "inherits": "2.0.3",
+ "minimatch": "1.0.0",
+ "once": "1.4.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9"
+ }
+ }
+ }
+ },
+ "caseless": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz",
+ "integrity": "sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.0.tgz",
+ "integrity": "sha1-N138y8IcCmCothvFt489wqVcIS8=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "1.1.0",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "0.1.0",
+ "strip-ansi": "0.3.0",
+ "supports-color": "0.2.0"
+ }
+ },
+ "colors": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
+ "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delayed-stream": "0.0.5"
+ }
+ },
+ "cryptiles": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz",
+ "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boom": "0.4.2"
+ }
+ },
+ "delayed-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
+ "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=",
+ "dev": true,
+ "optional": true
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "1.0.5",
+ "object-assign": "4.1.1"
+ }
+ },
+ "forever-agent": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz",
+ "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz",
+ "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "async": "0.9.2",
+ "combined-stream": "0.0.7",
+ "mime": "1.2.11"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "glob": {
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "minimatch": "0.3.0"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2.5.2",
+ "sigmund": "1.0.1"
+ }
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
+ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
+ "dev": true,
+ "requires": {
+ "natives": "1.1.0"
+ }
+ },
+ "has-ansi": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+ "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "hawk": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz",
+ "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boom": "0.4.2",
+ "cryptiles": "0.2.2",
+ "hoek": "0.9.1",
+ "sntp": "0.2.4"
+ }
+ },
+ "hoek": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz",
+ "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
+ "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asn1": "0.1.11",
+ "assert-plus": "0.1.5",
+ "ctype": "0.5.3"
+ }
+ },
+ "inquirer": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.7.1.tgz",
+ "integrity": "sha1-uKzxQBZb1YGGLtEZj7bSZDAJH6w=",
+ "dev": true,
+ "requires": {
+ "chalk": "0.5.0",
+ "cli-color": "0.3.3",
+ "figures": "1.7.0",
+ "lodash": "2.4.2",
+ "mute-stream": "0.0.4",
+ "readline2": "0.1.1",
+ "rx": "2.5.3",
+ "through": "2.3.8"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+ "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz",
+ "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.2.tgz",
+ "integrity": "sha1-H92tk4quEmPOE4aAvhs/WRwKtBw=",
+ "dev": true
+ },
+ "mime": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
+ "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=",
+ "dev": true,
+ "optional": true
+ },
+ "mime-types": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz",
+ "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
+ "integrity": "sha1-4N0hILSeG3JM6NcUxSCCKpQ4V20=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2.5.2",
+ "sigmund": "1.0.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
+ "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz",
+ "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34=",
+ "dev": true
+ },
+ "node-uuid": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
+ "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
+ "dev": true
+ },
+ "nopt": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
+ "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz",
+ "integrity": "sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k=",
+ "dev": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.0.tgz",
+ "integrity": "sha1-YWaBIe7FhJVQMLn0cLHSMJUEv8s=",
+ "dev": true
+ },
+ "q": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz",
+ "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ=",
+ "dev": true
+ },
+ "qs": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz",
+ "integrity": "sha1-GbV/8k3CqZzh+L32r82ln472H4g=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.42.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.42.0.tgz",
+ "integrity": "sha1-VyvQFIk4VkBArHqxSLlkI6BjMEo=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.5.0",
+ "bl": "0.9.5",
+ "caseless": "0.6.0",
+ "forever-agent": "0.5.2",
+ "form-data": "0.1.4",
+ "hawk": "1.1.1",
+ "http-signature": "0.10.1",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "1.0.2",
+ "node-uuid": "1.4.8",
+ "oauth-sign": "0.4.0",
+ "qs": "1.2.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.4.3"
+ }
+ },
+ "rimraf": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+ "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+ "dev": true
+ },
+ "semver": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz",
+ "integrity": "sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI=",
+ "dev": true
+ },
+ "sntp": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz",
+ "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "hoek": "0.9.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+ "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.23",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.23.tgz",
+ "integrity": "sha1-3odKpel0qF8KMs39vXRmPLO9nHQ=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ },
+ "which": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz",
+ "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=",
+ "dev": true
+ }
+ }
+ },
+ "bower-json": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz",
+ "integrity": "sha1-qZw8z0Fu8FkO0N7SUsdg8cbZN2Y=",
+ "dev": true,
+ "requires": {
+ "deep-extend": "0.2.11",
+ "graceful-fs": "2.0.3",
+ "intersect": "0.0.3"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
+ "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
+ "dev": true
+ }
+ }
+ },
+ "bower-logger": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz",
+ "integrity": "sha1-Ob4H6Xmy/I4DqUY0IF7ZQiNz04E=",
+ "dev": true
+ },
+ "bower-registry-client": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/bower-registry-client/-/bower-registry-client-0.2.4.tgz",
+ "integrity": "sha1-Jp/H6Ji2J/uTnRFEpZMlTX+77rw=",
+ "dev": true,
+ "requires": {
+ "async": "0.2.10",
+ "bower-config": "0.5.2",
+ "graceful-fs": "2.0.3",
+ "lru-cache": "2.3.1",
+ "mkdirp": "0.3.5",
+ "request": "2.51.0",
+ "request-replay": "0.2.0",
+ "rimraf": "2.2.8"
+ },
+ "dependencies": {
+ "asn1": {
+ "version": "0.1.11",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz",
+ "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
+ "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=",
+ "dev": true
+ },
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz",
+ "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=",
+ "dev": true
+ },
+ "boom": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz",
+ "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=",
+ "dev": true,
+ "requires": {
+ "hoek": "0.9.1"
+ }
+ },
+ "caseless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.8.0.tgz",
+ "integrity": "sha1-W8oogdQUN/VLJAfr40iIx7mtT30=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
+ "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "0.0.5"
+ }
+ },
+ "cryptiles": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz",
+ "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=",
+ "dev": true,
+ "requires": {
+ "boom": "0.4.2"
+ }
+ },
+ "delayed-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
+ "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz",
+ "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
+ "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
+ "dev": true,
+ "requires": {
+ "async": "0.9.2",
+ "combined-stream": "0.0.7",
+ "mime-types": "2.0.14"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.12.0"
+ }
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
+ "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
+ "dev": true
+ },
+ "hawk": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz",
+ "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=",
+ "dev": true,
+ "requires": {
+ "boom": "0.4.2",
+ "cryptiles": "0.2.2",
+ "hoek": "0.9.1",
+ "sntp": "0.2.4"
+ }
+ },
+ "hoek": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz",
+ "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
+ "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.1.11",
+ "assert-plus": "0.1.5",
+ "ctype": "0.5.3"
+ }
+ },
+ "lru-cache": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.3.1.tgz",
+ "integrity": "sha1-s632s9hW6VTiw5DmzvIggSRaU9Y=",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
+ "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz",
+ "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
+ "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
+ "dev": true
+ },
+ "node-uuid": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
+ "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.5.0.tgz",
+ "integrity": "sha1-12f1FpMlYg6rLgh+8MRy53PbZGE=",
+ "dev": true
+ },
+ "qs": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz",
+ "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.51.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.51.0.tgz",
+ "integrity": "sha1-NdALvswBLlX5B7G9ng29V3v+8m4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.5.0",
+ "bl": "0.9.5",
+ "caseless": "0.8.0",
+ "combined-stream": "0.0.7",
+ "forever-agent": "0.5.2",
+ "form-data": "0.2.0",
+ "hawk": "1.1.1",
+ "http-signature": "0.10.1",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "1.0.2",
+ "node-uuid": "1.4.8",
+ "oauth-sign": "0.5.0",
+ "qs": "2.3.3",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.4.3"
+ }
+ },
+ "rimraf": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+ "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+ "dev": true
+ },
+ "sntp": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz",
+ "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=",
+ "dev": true,
+ "requires": {
+ "hoek": "0.9.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ }
+ }
+ },
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
@@ -1127,6 +1996,12 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"dev": true
},
+ "buffers": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
+ "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
+ "dev": true
+ },
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
@@ -1200,6 +2075,15 @@
"integrity": "sha1-J931/szdM4yZpiyXiMJpT5n2ftc=",
"dev": true
},
+ "cardinal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.0.tgz",
+ "integrity": "sha1-fRCq+yCDe94EPEXkOgyMKM2q5F4=",
+ "dev": true,
+ "requires": {
+ "redeyed": "0.4.4"
+ }
+ },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -1224,6 +2108,15 @@
}
}
},
+ "chainsaw": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
+ "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
+ "dev": true,
+ "requires": {
+ "traverse": "0.3.9"
+ }
+ },
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
@@ -1237,6 +2130,12 @@
"supports-color": "2.0.0"
}
},
+ "chmodr": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-0.1.0.tgz",
+ "integrity": "sha1-4JIVodUVQtsqJXaWl2W89hJVg+s=",
+ "dev": true
+ },
"chokidar": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -1296,6 +2195,29 @@
"chalk": "1.1.3"
}
},
+ "cli-color": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.3.3.tgz",
+ "integrity": "sha1-EtW90Vj/igsNtAEZiRPAPfBp9vU=",
+ "dev": true,
+ "requires": {
+ "d": "0.1.1",
+ "es5-ext": "0.10.29",
+ "memoizee": "0.3.10",
+ "timers-ext": "0.1.2"
+ },
+ "dependencies": {
+ "d": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
+ "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.29"
+ }
+ }
+ }
+ },
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -1494,6 +2416,55 @@
"typedarray": "0.0.6"
}
},
+ "config-chain": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
+ "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
+ "dev": true,
+ "requires": {
+ "ini": "1.3.4",
+ "proto-list": "1.2.4"
+ }
+ },
+ "configstore": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz",
+ "integrity": "sha1-JeTBbDdoq/dcWmW8YXYfSVBVtFk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "3.0.11",
+ "js-yaml": "3.7.0",
+ "mkdirp": "0.5.1",
+ "object-assign": "2.1.1",
+ "osenv": "0.1.4",
+ "user-home": "1.1.1",
+ "uuid": "2.0.3",
+ "xdg-basedir": "1.0.1"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
+ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
+ "dev": true,
+ "requires": {
+ "natives": "1.1.0"
+ }
+ },
+ "object-assign": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
+ "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+ "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
+ "dev": true
+ }
+ }
+ },
"connect": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/connect/-/connect-3.6.3.tgz",
@@ -1775,6 +2746,12 @@
"source-map": "0.5.7"
}
},
+ "ctype": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz",
+ "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=",
+ "dev": true
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -1837,6 +2814,77 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true
},
+ "decompress-zip": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.0.8.tgz",
+ "integrity": "sha1-SiZbIseyCdeyT6ZvKy37ztWQRPM=",
+ "dev": true,
+ "requires": {
+ "binary": "0.3.0",
+ "graceful-fs": "3.0.11",
+ "mkpath": "0.1.0",
+ "nopt": "2.2.1",
+ "q": "1.0.1",
+ "readable-stream": "1.1.14",
+ "touch": "0.0.2"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
+ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
+ "dev": true,
+ "requires": {
+ "natives": "1.1.0"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "nopt": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
+ "integrity": "sha1-KqCbfRdoSHs7ianFqlIzW/8Lrqc=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.1.0"
+ }
+ },
+ "q": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz",
+ "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "deep-extend": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz",
+ "integrity": "sha1-eha6aXKRMjQFBhcElLyD9wdv4I8=",
+ "dev": true
+ },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -1995,6 +3043,26 @@
"integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
"dev": true
},
+ "end-of-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz",
+ "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=",
+ "dev": true,
+ "requires": {
+ "once": "1.3.3"
+ },
+ "dependencies": {
+ "once": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ }
+ }
+ },
"engine.io": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
@@ -3629,14 +4697,6 @@
}
}
},
- "string_decoder": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "safe-buffer": "5.0.1"
- }
- },
"string-width": {
"version": "1.0.2",
"bundled": true,
@@ -3647,6 +4707,14 @@
"strip-ansi": "3.0.1"
}
},
+ "string_decoder": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.0.1"
+ }
+ },
"stringstream": {
"version": "0.0.5",
"bundled": true,
@@ -3771,6 +4839,17 @@
"rimraf": "2.6.1"
}
},
+ "fstream-ignore": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
+ "dev": true,
+ "requires": {
+ "fstream": "1.0.11",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4"
+ }
+ },
"function-bind": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
@@ -3994,12 +5073,85 @@
}
}
},
+ "got": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-0.3.0.tgz",
+ "integrity": "sha1-iI7GbKS8c1qwidvpWUltD3lIVJM=",
+ "dev": true,
+ "requires": {
+ "object-assign": "0.3.1"
+ },
+ "dependencies": {
+ "object-assign": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-0.3.1.tgz",
+ "integrity": "sha1-Bg4qKifXwNd+x3t48Rqkf9iACNI=",
+ "dev": true
+ }
+ }
+ },
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
"dev": true
},
+ "handlebars": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz",
+ "integrity": "sha1-bp1/hRSjRn+l6fgswVjs/B1ax28=",
+ "dev": true,
+ "requires": {
+ "optimist": "0.3.7",
+ "uglify-js": "2.3.6"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true,
+ "optional": true
+ },
+ "optimist": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+ "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
+ "dev": true,
+ "requires": {
+ "wordwrap": "0.0.3"
+ }
+ },
+ "source-map": {
+ "version": "0.1.43",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
+ "uglify-js": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz",
+ "integrity": "sha1-+gmEdwtCi3qbKoBY9GNV0U/vIRo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "async": "0.2.10",
+ "optimist": "0.3.7",
+ "source-map": "0.1.43"
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ }
+ }
+ },
"har-schema": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
@@ -4320,6 +5472,12 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "dev": true
+ },
"inquirer": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.2.tgz",
@@ -4394,12 +5552,134 @@
}
}
},
+ "insight": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/insight/-/insight-0.4.3.tgz",
+ "integrity": "sha1-dtZTxcDYBIsDzbpjhaaUj3RhSvA=",
+ "dev": true,
+ "requires": {
+ "async": "0.9.2",
+ "chalk": "0.5.1",
+ "configstore": "0.3.2",
+ "inquirer": "0.6.0",
+ "lodash.debounce": "2.4.1",
+ "object-assign": "1.0.0",
+ "os-name": "1.0.3",
+ "request": "2.81.0",
+ "tough-cookie": "0.12.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+ "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+ "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+ "dev": true
+ },
+ "async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+ "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "1.1.0",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "0.1.0",
+ "strip-ansi": "0.3.0",
+ "supports-color": "0.2.0"
+ }
+ },
+ "has-ansi": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+ "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "inquirer": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.6.0.tgz",
+ "integrity": "sha1-YU17s+SPnmqAKOlKDDjyPvKYI9M=",
+ "dev": true,
+ "requires": {
+ "chalk": "0.5.1",
+ "cli-color": "0.3.3",
+ "lodash": "2.4.2",
+ "mute-stream": "0.0.4",
+ "readline2": "0.1.1",
+ "rx": "2.5.3",
+ "through": "2.3.8"
+ }
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+ "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz",
+ "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz",
+ "integrity": "sha1-5l3Idm07R7S4MHRlyDEdoDCwcKY=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+ "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz",
+ "integrity": "sha1-giDH4hq9WxPZaAQlS9WoHr8sfWI=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ }
+ }
+ },
"interpret": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz",
"integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=",
"dev": true
},
+ "intersect": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz",
+ "integrity": "sha1-waSl5erG7eSvdQTMB+Ctp7yfSSA=",
+ "dev": true
+ },
"invariant": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
@@ -4577,6 +5857,12 @@
"tryit": "1.0.3"
}
},
+ "is-root": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz",
+ "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=",
+ "dev": true
+ },
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -4787,6 +6073,12 @@
}
}
},
+ "junk": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz",
+ "integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI=",
+ "dev": true
+ },
"karma": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/karma/-/karma-1.7.0.tgz",
@@ -4860,12 +6152,46 @@
"which": "1.3.0"
}
},
+ "karma-fixture": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/karma-fixture/-/karma-fixture-0.2.6.tgz",
+ "integrity": "sha1-lxzqjCFtc/BwQ5ZMtz8Q4IMAGO8=",
+ "dev": true
+ },
+ "karma-html2js-preprocessor": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/karma-html2js-preprocessor/-/karma-html2js-preprocessor-1.1.0.tgz",
+ "integrity": "sha1-/Ant8Eu+K7bu6boZaPgmtziAIL0=",
+ "dev": true
+ },
"karma-jasmine": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.0.tgz",
"integrity": "sha1-IuTAa/mhguUpTR9wXjczgRuBCs8=",
"dev": true
},
+ "karma-jasmine-jquery": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/karma-jasmine-jquery/-/karma-jasmine-jquery-0.1.1.tgz",
+ "integrity": "sha1-icG3VP6kElsfiTghOSwRuc5ddFY=",
+ "dev": true,
+ "requires": {
+ "bower": "1.8.0",
+ "bower-installer": "git://github.com/bessdsv/bower-installer.git#7f9cece1e6fada50f44dc0851e1d85815cd1b4a7"
+ }
+ },
+ "karma-jquery": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/karma-jquery/-/karma-jquery-0.2.2.tgz",
+ "integrity": "sha1-a+6TRU2LCWvMeBVXCoHnP93bXW8=",
+ "dev": true
+ },
+ "karma-json-fixtures-preprocessor": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/karma-json-fixtures-preprocessor/-/karma-json-fixtures-preprocessor-0.0.6.tgz",
+ "integrity": "sha1-T3ii6800OH+OVaur/2NGVRZMTHY=",
+ "dev": true
+ },
"karma-webpack": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.4.tgz",
@@ -4932,6 +6258,15 @@
"graceful-fs": "4.1.11"
}
},
+ "latest-version": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-0.2.0.tgz",
+ "integrity": "sha1-ra+JjV8iOA0/nEU4bv3/ChtbdQE=",
+ "dev": true,
+ "requires": {
+ "package-json": "0.2.0"
+ }
+ },
"lazy-cache": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
@@ -5047,12 +6382,30 @@
"path-exists": "3.0.0"
}
},
+ "lockfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.3.tgz",
+ "integrity": "sha1-Jjj8OaAzHpysGgS3F5mTHJxQ33k=",
+ "dev": true
+ },
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
"dev": true
},
+ "lodash._isnative": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
+ "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=",
+ "dev": true
+ },
+ "lodash._objecttypes": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+ "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+ "dev": true
+ },
"lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
@@ -5077,6 +6430,32 @@
"integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
"dev": true
},
+ "lodash.debounce": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-2.4.1.tgz",
+ "integrity": "sha1-2M6tJG7EuSbouFZ4/Dlr/rqMxvw=",
+ "dev": true,
+ "requires": {
+ "lodash.isfunction": "2.4.1",
+ "lodash.isobject": "2.4.1",
+ "lodash.now": "2.4.1"
+ }
+ },
+ "lodash.isfunction": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz",
+ "integrity": "sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE=",
+ "dev": true
+ },
+ "lodash.isobject": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
+ "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
+ "dev": true,
+ "requires": {
+ "lodash._objecttypes": "2.4.1"
+ }
+ },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -5089,6 +6468,15 @@
"integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=",
"dev": true
},
+ "lodash.now": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/lodash.now/-/lodash.now-2.4.1.tgz",
+ "integrity": "sha1-aHIVZQBSUYX6+WeFu3/n/hW1YsY=",
+ "dev": true,
+ "requires": {
+ "lodash._isnative": "2.4.1"
+ }
+ },
"lodash.tail": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
@@ -5178,6 +6566,15 @@
"yallist": "2.1.2"
}
},
+ "lru-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.29"
+ }
+ },
"macaddress": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
@@ -5242,6 +6639,65 @@
"mimic-fn": "1.1.0"
}
},
+ "memoizee": {
+ "version": "0.3.10",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.3.10.tgz",
+ "integrity": "sha1-TsoNiu057J0Bf0xcLy9kMvQuXI8=",
+ "dev": true,
+ "requires": {
+ "d": "0.1.1",
+ "es5-ext": "0.10.29",
+ "es6-weak-map": "0.1.4",
+ "event-emitter": "0.3.5",
+ "lru-queue": "0.1.0",
+ "next-tick": "0.2.2",
+ "timers-ext": "0.1.2"
+ },
+ "dependencies": {
+ "d": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
+ "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.29"
+ }
+ },
+ "es6-iterator": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz",
+ "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=",
+ "dev": true,
+ "requires": {
+ "d": "0.1.1",
+ "es5-ext": "0.10.29",
+ "es6-symbol": "2.0.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz",
+ "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=",
+ "dev": true,
+ "requires": {
+ "d": "0.1.1",
+ "es5-ext": "0.10.29"
+ }
+ },
+ "es6-weak-map": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz",
+ "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=",
+ "dev": true,
+ "requires": {
+ "d": "0.1.1",
+ "es5-ext": "0.10.29",
+ "es6-iterator": "0.1.3",
+ "es6-symbol": "2.0.1"
+ }
+ }
+ }
+ },
"memory-fs": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@@ -5480,6 +6936,18 @@
"minimist": "0.0.8"
}
},
+ "mkpath": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz",
+ "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=",
+ "dev": true
+ },
+ "mout": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/mout/-/mout-0.9.1.tgz",
+ "integrity": "sha1-hPDz/WrMcxf2PeKv/cwM7gCbBHc=",
+ "dev": true
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -5498,6 +6966,12 @@
"integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=",
"dev": true
},
+ "natives": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz",
+ "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=",
+ "dev": true
+ },
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -5510,6 +6984,12 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
"dev": true
},
+ "next-tick": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz",
+ "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=",
+ "dev": true
+ },
"node-dir": {
"version": "0.1.17",
"resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz",
@@ -5519,6 +6999,12 @@
"minimatch": "3.0.4"
}
},
+ "node-fs": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz",
+ "integrity": "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs=",
+ "dev": true
+ },
"node-gyp": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
@@ -5710,6 +7196,40 @@
"path-key": "2.0.1"
}
},
+ "npmconf": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/npmconf/-/npmconf-2.1.2.tgz",
+ "integrity": "sha1-ZmBqSnNvHnegWaoHGnnJSreBhTo=",
+ "dev": true,
+ "requires": {
+ "config-chain": "1.1.11",
+ "inherits": "2.0.3",
+ "ini": "1.3.4",
+ "mkdirp": "0.5.1",
+ "nopt": "3.0.6",
+ "once": "1.3.3",
+ "osenv": "0.1.4",
+ "semver": "4.3.6",
+ "uid-number": "0.0.5"
+ },
+ "dependencies": {
+ "once": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "semver": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
+ "dev": true
+ }
+ }
+ },
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
@@ -5812,6 +7332,12 @@
"mimic-fn": "1.1.0"
}
},
+ "opn": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz",
+ "integrity": "sha1-uQlkM0bQChq8l3qLlvPOPFPVz18=",
+ "dev": true
+ },
"optimist": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
@@ -5871,6 +7397,16 @@
"lcid": "1.0.0"
}
},
+ "os-name": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz",
+ "integrity": "sha1-GzefZINa98Wn9JizV8uVIVwVnt8=",
+ "dev": true,
+ "requires": {
+ "osx-release": "1.1.0",
+ "win-release": "1.1.1"
+ }
+ },
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -5887,6 +7423,23 @@
"os-tmpdir": "1.0.2"
}
},
+ "osx-release": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz",
+ "integrity": "sha1-8heRGigTaUmvG/kwiyQeJzfTzWw=",
+ "dev": true,
+ "requires": {
+ "minimist": "1.2.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
@@ -5908,6 +7461,33 @@
"p-limit": "1.1.0"
}
},
+ "p-throttler": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.0.tgz",
+ "integrity": "sha1-GxaQeULDM+bx3eq8s0eSBLjEF8Q=",
+ "dev": true,
+ "requires": {
+ "q": "0.9.7"
+ },
+ "dependencies": {
+ "q": {
+ "version": "0.9.7",
+ "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz",
+ "integrity": "sha1-TeLmyzspCIyeTLwDv51C+5bOL3U=",
+ "dev": true
+ }
+ }
+ },
+ "package-json": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-0.2.0.tgz",
+ "integrity": "sha1-Axbhd7jrFJmF009wa0pVQ7J0vsU=",
+ "dev": true,
+ "requires": {
+ "got": "0.3.0",
+ "registry-url": "0.1.1"
+ }
+ },
"pako": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
@@ -6683,6 +8263,21 @@
"integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
"dev": true
},
+ "promptly": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz",
+ "integrity": "sha1-c+8gD6gynV06jfQXmJULhkbKRtk=",
+ "dev": true,
+ "requires": {
+ "read": "1.0.7"
+ }
+ },
+ "proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+ "dev": true
+ },
"prr": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
@@ -6708,6 +8303,24 @@
"randombytes": "2.0.5"
}
},
+ "pump": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-0.3.5.tgz",
+ "integrity": "sha1-rl/4wfk+2HrcZTCpdWWxJvWFRUs=",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.0.0",
+ "once": "1.2.0"
+ },
+ "dependencies": {
+ "once": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.2.0.tgz",
+ "integrity": "sha1-3hkFxjavh0qPuoYtmqvd0fkgRhw=",
+ "dev": true
+ }
+ }
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@@ -6829,6 +8442,15 @@
}
}
},
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+ "dev": true,
+ "requires": {
+ "mute-stream": "0.0.7"
+ }
+ },
"read-pkg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
@@ -6877,6 +8499,39 @@
"set-immediate-shim": "1.0.1"
}
},
+ "readline2": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-0.1.1.tgz",
+ "integrity": "sha1-mUQ7pug7gw7zBRv9fcJBqCco1Wg=",
+ "dev": true,
+ "requires": {
+ "mute-stream": "0.0.4",
+ "strip-ansi": "2.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz",
+ "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz",
+ "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz",
+ "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "1.1.1"
+ }
+ }
+ }
+ },
"redent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
@@ -6887,6 +8542,23 @@
"strip-indent": "1.0.1"
}
},
+ "redeyed": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz",
+ "integrity": "sha1-N+mQpvKyGyoRwuakj9QTVpjLqX8=",
+ "dev": true,
+ "requires": {
+ "esprima": "1.0.4"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+ "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
+ "dev": true
+ }
+ }
+ },
"reduce-css-calc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
@@ -6967,6 +8639,15 @@
"regjsparser": "0.1.5"
}
},
+ "registry-url": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-0.1.1.tgz",
+ "integrity": "sha1-FzlCe4GxELMCSCocfNcn/8yC1b4=",
+ "dev": true,
+ "requires": {
+ "npmconf": "2.1.2"
+ }
+ },
"regjsgen": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
@@ -7047,6 +8728,24 @@
"uuid": "3.1.0"
}
},
+ "request-progress": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.0.tgz",
+ "integrity": "sha1-vfIGK/wZfF1JJQDUTLOv94ZbSS4=",
+ "dev": true,
+ "requires": {
+ "throttleit": "0.0.2"
+ }
+ },
+ "request-replay": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz",
+ "integrity": "sha1-m2k6XRGLOfXFlurV7ZGiZEQFf2A=",
+ "dev": true,
+ "requires": {
+ "retry": "0.6.0"
+ }
+ },
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -7100,6 +8799,12 @@
"signal-exit": "3.0.2"
}
},
+ "retry": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.0.tgz",
+ "integrity": "sha1-HAEHEyeab9Ho3vKK8MP/GHHKpTc=",
+ "dev": true
+ },
"right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -7153,6 +8858,12 @@
"is-promise": "2.1.0"
}
},
+ "rx": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-2.5.3.tgz",
+ "integrity": "sha1-Ia3H2A8CACr1Da6X/Z2/JIdV9WY=",
+ "dev": true
+ },
"rx-lite": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
@@ -7265,6 +8976,23 @@
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
},
+ "semver-diff": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-0.1.0.tgz",
+ "integrity": "sha1-T2BXyj66I8xIS1H2Sq+IsTGjhV0=",
+ "dev": true,
+ "requires": {
+ "semver": "2.3.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz",
+ "integrity": "sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI=",
+ "dev": true
+ }
+ }
+ },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -7336,6 +9064,24 @@
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true
},
+ "shell-quote": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz",
+ "integrity": "sha1-lSxE4LHtkBPvU5WBecxkPod3Rms=",
+ "dev": true,
+ "requires": {
+ "array-filter": "0.0.1",
+ "array-map": "0.0.0",
+ "array-reduce": "0.0.0",
+ "jsonify": "0.0.0"
+ }
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@@ -7630,13 +9376,30 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"dev": true
},
- "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==",
+ "string-length": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-0.1.2.tgz",
+ "integrity": "sha1-qwS7M4Z+50vu1/uJu38InTkngPI=",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "strip-ansi": "0.2.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.1.0.tgz",
+ "integrity": "sha1-Vcpg22kAhXxCOukpeYACb5Qe2QM=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.2.2.tgz",
+ "integrity": "sha1-hU0pDJgVJfyMOXqRCwJa4tVP/Ag=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.1.0"
+ }
+ }
}
},
"string-width": {
@@ -7666,6 +9429,21 @@
}
}
},
+ "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==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stringify-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz",
+ "integrity": "sha1-htNefb+86apFY31+zdeEfhWduKI=",
+ "dev": true
+ },
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
@@ -7790,12 +9568,67 @@
"inherits": "2.0.3"
}
},
+ "tar-fs": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-0.5.2.tgz",
+ "integrity": "sha1-D1lCS+fu7kUjIxbjAvZtP26m2z4=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "0.5.1",
+ "pump": "0.3.5",
+ "tar-stream": "0.4.7"
+ }
+ },
+ "tar-stream": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-0.4.7.tgz",
+ "integrity": "sha1-Hx0s6evHtCdlJDyg6PG3v9oKrc0=",
+ "dev": true,
+ "requires": {
+ "bl": "0.9.5",
+ "end-of-stream": "1.0.0",
+ "readable-stream": "1.1.14",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
+ "throttleit": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
+ "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
+ "dev": true
+ },
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -7825,6 +9658,24 @@
"setimmediate": "1.0.5"
}
},
+ "timers-ext": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz",
+ "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.29",
+ "next-tick": "1.0.0"
+ },
+ "dependencies": {
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
+ }
+ }
+ },
"tinymce": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.6.5.tgz",
@@ -7857,6 +9708,26 @@
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
"dev": true
},
+ "touch": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.2.tgz",
+ "integrity": "sha1-plp3d5Xly74SmUmb3EIoH/shtfQ=",
+ "dev": true,
+ "requires": {
+ "nopt": "1.0.10"
+ },
+ "dependencies": {
+ "nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.1.0"
+ }
+ }
+ }
+ },
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
@@ -7866,6 +9737,12 @@
"punycode": "1.4.1"
}
},
+ "traverse": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
+ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=",
+ "dev": true
+ },
"trim-newlines": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
@@ -7997,6 +9874,12 @@
"webpack-sources": "1.0.1"
}
},
+ "uid-number": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz",
+ "integrity": "sha1-Wj2yPvXb1VuB/ODsmirG/M3ruB4=",
+ "dev": true
+ },
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
@@ -8030,6 +9913,70 @@
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
"dev": true
},
+ "update-notifier": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.2.0.tgz",
+ "integrity": "sha1-oBDJKK3PAgkLjgzn/vb7Cnysw0o=",
+ "dev": true,
+ "requires": {
+ "chalk": "0.5.1",
+ "configstore": "0.3.2",
+ "latest-version": "0.2.0",
+ "semver-diff": "0.1.0",
+ "string-length": "0.1.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+ "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+ "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+ "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "1.1.0",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "0.1.0",
+ "strip-ansi": "0.3.0",
+ "supports-color": "0.2.0"
+ }
+ },
+ "has-ansi": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+ "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+ "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+ "dev": true
+ }
+ }
+ },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -8048,6 +9995,12 @@
}
}
},
+ "user-home": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
+ "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
+ "dev": true
+ },
"useragent": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz",
@@ -8343,6 +10296,15 @@
}
}
},
+ "win-release": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz",
+ "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=",
+ "dev": true,
+ "requires": {
+ "semver": "5.4.1"
+ }
+ },
"window-size": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -8418,6 +10380,15 @@
"integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
"dev": true
},
+ "xdg-basedir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz",
+ "integrity": "sha1-FP+PY6T9vLBdW27qIrNvMDO58E4=",
+ "dev": true,
+ "requires": {
+ "user-home": "1.1.1"
+ }
+ },
"xmlhttprequest-ssl": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
diff --git a/lib/assets/package.json b/lib/assets/package.json
index 9324098..2d0a2b5 100644
--- a/lib/assets/package.json
+++ b/lib/assets/package.json
@@ -45,8 +45,12 @@
"jasmine-core": "^2.7.0",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.2.0",
+ "karma-fixture": "^0.2.6",
+ "karma-html2js-preprocessor": "^1.1.0",
"karma-jasmine": "^1.1.0",
+ "karma-jasmine-jquery": "^0.1.1",
"karma-jquery": "^0.2.2",
+ "karma-json-fixtures-preprocessor": "0.0.6",
"karma-webpack": "^2.0.4",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
diff --git a/lib/tasks/bugfix.rake b/lib/tasks/bugfix.rake
new file mode 100644
index 0000000..5fc6bf1
--- /dev/null
+++ b/lib/tasks/bugfix.rake
@@ -0,0 +1,49 @@
+namespace :bugfix do
+
+ desc "Bug fixes for version v0.3.3"
+ task v0_3_3: :environment do
+ Rake::Task['bugfix:fix_question_formats'].execute
+ Rake::Task['bugfix:add_missing_token_permission_types'].execute
+ end
+
+ desc "Add the missing formattype to the question_formats table"
+ task fix_question_formats: :environment do
+ QuestionFormat.all.each do |qf|
+ case qf.title.downcase
+ when 'text area'
+ qf.formattype = :textarea
+ when 'text field'
+ qf.formattype = :textfield
+ when 'radio buttons'
+ qf.formattype = :radiobuttons
+ when 'check box'
+ qf.formattype = :checkbox
+ when 'dropdown'
+ qf.formattype = :dropdown
+ when 'multi select box'
+ qf.formattype = :multiselectbox
+ when 'date'
+ qf.formattype = :date
+ end
+
+ qf.save!
+ end
+
+ if QuestionFormat.find_by(formattype: :date).nil?
+ QuestionFormat.create!({title: "Date", option_based: true, formattype: 6})
+ end
+ end
+
+ desc "Add the missing token_permission_types"
+ task add_missing_token_permission_types: :environment do
+ if TokenPermissionType.find_by(token_type: 'templates').nil?
+ TokenPermissionType.create!({token_type: 'templates',
+ text_description: 'allows a user access to the templates api endpoint'})
+ end
+ if TokenPermissionType.find_by(token_type: 'statistics').nil?
+ TokenPermissionType.create!({token_type: 'statistics',
+ text_description: 'allows a user access to the statistics api endpoint'})
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/test/functional/roles_controller_test.rb b/test/functional/roles_controller_test.rb
index 6a61b79..7d2f9f0 100644
--- a/test/functional/roles_controller_test.rb
+++ b/test/functional/roles_controller_test.rb
@@ -7,10 +7,10 @@
setup do
scaffold_plan
scaffold_org_admin(@plan.template.org)
-
+
# This should NOT be unnecessary! Owner should have full access
@plan.roles << Role.create(user: @user, plan: @plan, access: 15)
-
+
end
# TODO: Cleanup routes for this one. The controller currently only responds to create, update, destroy
@@ -21,19 +21,19 @@
# role PATCH /roles/:id roles#update
# PUT /roles/:id roles#update
# DELETE /roles/:id roles#destroy
-
+
# POST /roles (roles_path)
# ----------------------------------------------------------
test "create a new role" do
params = {plan_id: @plan.id, access_level: 4}
-
+
# Should redirect user to the root path if they are not logged in!
post roles_path, {role: params}
assert_unauthorized_redirect_to_root_path
sign_in @user
-
+
# Known user
@invitee = User.where.not(id: [@plan.owner.id, @user.id]).first
post roles_path, {user: @invitee.email, role: params}
@@ -50,15 +50,15 @@
assert_redirected_to share_plan_path(@plan)
assert_equal @invitee.id, Role.last.user_id, "expected no record to have been created!"
assert assigns(:role)
-
+
# Unknown user
post roles_path, {user: 'unknown_user@org.org', role: params}
- assert_equal _('Invitation to unknown_user@org.org issued successfully.'), flash[:notice]
+ assert_equal _('Invitation to unknown_user@org.org issued successfully. \nPlan shared with unknown_user@org.org.'), flash[:notice]
assert_response :redirect
assert_redirected_to share_plan_path(@plan)
assert_equal User.find_by(email:'unknown_user@org.org').id, Role.last.user_id, "expected the record to have been created!"
assert assigns(:role)
-
+
# Invite owner
@invitee = User.find_by(id: @plan.owner.id)
post roles_path, {user: @invitee.email, role: params}
@@ -67,32 +67,32 @@
assert_redirected_to share_plan_path(@plan)
assert_not_equal @invitee.id, Role.last.user_id, "expected no record to have been created!"
assert assigns(:role)
-
+
# Missing email
post roles_path, {role: {plan_id: @plan.id, access_level: 4}}
assert_equal _('Please enter an email address'), flash[:notice]
assert_response :redirect
assert_redirected_to share_plan_path(@plan)
assert assigns(:role)
- end
-
+ end
+
# PUT /role/:id (role_path)
# ----------------------------------------------------------
test "update the role" do
@invitee = User.last
role = Role.create(user: @invitee, plan: @plan, access: 1)
params = {access_level: 2}
-
+
# Should redirect user to the root path if they are not logged in!
put role_path(role), {role: params}
assert_unauthorized_redirect_to_root_path
-
+
sign_in @user
# Valid save
put role_path(role, format: :json), {role: params}
assert_equal 13, role.reload.access, "expected the record to have been updated"
-
+
# TODO: Role should require a user, plan and an access level :/
# Invalid save
# put role_path(role), {role: {user: nil}}
@@ -101,26 +101,26 @@
# assert_redirected_to share_plan_path(@plan)
# assert assigns(:role)
end
-
+
# DELETE /role/:id (role_path)
# ----------------------------------------------------------
test "delete the section" do
@invitee = User.last
role = Role.create(user: @invitee, plan: @plan, access: 1)
-
+
# Should redirect user to the root path if they are not logged in!
delete role_path(role)
assert_unauthorized_redirect_to_root_path
-
+
sign_in @user
-
+
delete role_path(role)
assert_equal _('Access removed'), flash[:notice]
assert_response :redirect
assert_redirected_to share_plan_path(@plan)
- assert_raise ActiveRecord::RecordNotFound do
+ assert_raise ActiveRecord::RecordNotFound do
Role.find(role.id).nil?
end
end
-
+
end