From 29c9d8f36a44e5859564c1abd4d9cf6467f8ec2f Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 8 Nov 2018 14:26:05 -0600 Subject: [PATCH 01/62] Privs wip --- .../javascripts/app/controllers/footer.js | 25 +++- .../javascripts/app/controllers/home.js | 3 +- .../javascripts/app/controllers/lockScreen.js | 1 - .../app/directives/views/accountMenu.js | 14 ++- .../directives/views/privilegesAuthModal.js | 60 ++++++++++ .../javascripts/app/services/authManager.js | 7 ++ .../app/services/passcodeManager.js | 12 ++ .../app/services/privilegesManager.js | 107 ++++++++++++++++++ .../privileges-auth-modal.html.haml | 17 +++ app/assets/templates/footer.html.haml | 2 +- 10 files changed, 241 insertions(+), 7 deletions(-) create mode 100644 app/assets/javascripts/app/directives/views/privilegesAuthModal.js create mode 100644 app/assets/javascripts/app/services/privilegesManager.js create mode 100644 app/assets/templates/directives/privileges-auth-modal.html.haml diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index d408d1be4..3131e7c36 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -23,7 +23,8 @@ angular.module('app') } }) .controller('FooterCtrl', function ($rootScope, authManager, modelManager, $timeout, dbManager, - syncManager, storageManager, passcodeManager, componentManager, singletonManager, nativeExtManager) { + syncManager, storageManager, passcodeManager, componentManager, singletonManager, nativeExtManager, + privilegesManager) { authManager.checkForSecurityUpdate().then((available) => { this.securityUpdateAvailable = available; @@ -173,6 +174,26 @@ angular.module('app') } this.selectRoom = function(room) { - room.showRoom = !room.showRoom; + let run = () => { + room.showRoom = !room.showRoom; + } + + if(!room.showRoom) { + // About to show, check if has privileges + if(privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageExtensions)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageExtensions, () => { + run(); + }); + } + } else { + run(); + } + } + + this.clickOutsideAccountMenu = function() { + if(privilegesManager.authenticationInProgress()) { + return; + } + this.showAccountMenu = false; } }); diff --git a/app/assets/javascripts/app/controllers/home.js b/app/assets/javascripts/app/controllers/home.js index 6d8805094..c83a1c0a4 100644 --- a/app/assets/javascripts/app/controllers/home.js +++ b/app/assets/javascripts/app/controllers/home.js @@ -1,6 +1,7 @@ angular.module('app') .controller('HomeCtrl', function ($scope, $location, $rootScope, $timeout, modelManager, - dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager) { + dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager, + privilegesManager) { storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession()); diff --git a/app/assets/javascripts/app/controllers/lockScreen.js b/app/assets/javascripts/app/controllers/lockScreen.js index e38eff9f6..8f3a9efd0 100644 --- a/app/assets/javascripts/app/controllers/lockScreen.js +++ b/app/assets/javascripts/app/controllers/lockScreen.js @@ -41,7 +41,6 @@ class LockScreen { }) } } - } angular.module('app').directive('lockScreen', () => new LockScreen); diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index d24684515..b49dfff81 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -10,7 +10,7 @@ class AccountMenu { } controller($scope, $rootScope, authManager, modelManager, syncManager, storageManager, dbManager, passcodeManager, - $timeout, $compile, archiveManager) { + $timeout, $compile, archiveManager, privilegesManager) { 'ngInject'; $scope.formData = {mergeLocal: true, ephemeral: false}; @@ -317,7 +317,17 @@ class AccountMenu { */ $scope.downloadDataArchive = function() { - archiveManager.downloadBackup($scope.archiveFormData.encrypted); + let run = () => { + archiveManager.downloadBackup($scope.archiveFormData.encrypted); + } + + if(privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDownloadBackup)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDownloadBackup, () => { + run(); + }); + } else { + run(); + } } /* diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js new file mode 100644 index 000000000..56dd04aba --- /dev/null +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -0,0 +1,60 @@ +/* + The purpose of the conflict resoltion modal is to present two versions of a conflicted item, + and allow the user to choose which to keep (or to keep both.) +*/ + +class PrivilegesAuthModal { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/privileges-auth-modal.html"; + this.scope = { + action: "=", + onSuccess: "=", + onCancel: "=", + }; + } + + link($scope, el, attrs) { + $scope.dismiss = function() { + el.remove(); + } + } + + controller($scope, privilegesManager, $timeout) { + 'ngInject'; + + $scope.privileges = privilegesManager.privilegesForAction($scope.action); + + $scope.cancel = function() { + $scope.dismiss(); + $scope.onCancel && $scope.onCancel(); + } + + $scope.doesPrivHaveFail = function(priv) { + if(!$scope.failedPrivs) { + return false; + } + return $scope.failedPrivs.find((failedPriv) => { + return failedPriv.name == priv.name; + }) != null; + } + + $scope.submit = function() { + privilegesManager.verifyPrivilegesForAction($scope.action, $scope.privileges).then((result) => { + console.log("Result", result); + $timeout(() => { + if(result.success) { + $scope.onSuccess(); + $scope.dismiss(); + } else { + $scope.failedPrivs = result.failedPrivs; + } + }) + }) + } + + } +} + +angular.module('app').directive('privilegesAuthModal', () => new PrivilegesAuthModal); diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 6787d3709..47e169a68 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -92,6 +92,13 @@ class AuthManager extends SFAuthManager { } } + async verifyAccountPassword(password) { + let authParams = await this.getAuthParams(); + let keys = await SFJS.crypto.computeEncryptionKeysForUser(password, authParams); + let success = keys.mk === (await this.keys()).mk; + return success; + } + async checkForSecurityUpdate() { if(this.offline()) { return false; diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 47c9e763b..8d6fad7fa 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -36,6 +36,18 @@ angular.module('app') return authParams; } + this.verifyPasscode = async function(passcode) { + return new Promise(async (resolve, reject) => { + var params = this.passcodeAuthParams(); + let keys = await SFJS.crypto.computeEncryptionKeysForUser(passcode, params); + if(keys.pw !== params.hash) { + resolve(false); + } else { + resolve(true); + } + }) + } + this.unlock = function(passcode, callback) { var params = this.passcodeAuthParams(); SFJS.crypto.computeEncryptionKeysForUser(passcode, params).then((keys) => { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js new file mode 100644 index 000000000..a621e6d5b --- /dev/null +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -0,0 +1,107 @@ +class PrivilegesManager { + + constructor(passcodeManager, authManager, $rootScope, $compile) { + this.passcodeManager = passcodeManager; + this.authManager = authManager; + this.$rootScope = $rootScope; + this.$compile = $compile; + + PrivilegesManager.PrivilegeAccountPassword = "PrivilegeAccountPassword"; + PrivilegesManager.PrivilegeLocalPasscode = "PrivilegeLocalPasscode"; + + PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; + PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; + } + + presentPrivilegesModal(action, onSuccess, onCancel) { + + let customSuccess = () => { + onSuccess(); + this.currentAuthenticationElement = null; + } + + let customCancel = () => { + onCancel(); + this.currentAuthenticationElement = null; + } + + var scope = this.$rootScope.$new(true); + scope.action = action; + scope.onSuccess = customSuccess; + scope.onCancel = customCancel; + var el = this.$compile( "" )(scope); + angular.element(document.body).append(el); + + this.currentAuthenticationElement = el; + } + + authenticationInProgress() { + return this.currentAuthenticationElement != null; + } + + privilegesForAction(action) { + return [ + { + name: PrivilegesManager.PrivilegeAccountPassword, + label: "Account Password", + prompt: "Please enter your account password." + }, + { + name: PrivilegesManager.PrivilegeLocalPasscode, + label: "Local Passcode", + prompt: "Please enter your local passcode." + } + ] + } + + actionRequiresPrivilege(action) { + return this.privilegesForAction(action).length > 0; + } + + async verifyPrivilegesForAction(action, inputPrivs) { + + let findInputPriv = (name) => { + return inputPrivs.find((priv) => { + return priv.name == name; + }) + } + + var requiredPrivileges = this.privilegesForAction(action); + var successfulPrivs = [], failedPrivs = []; + for(let requiredPriv of requiredPrivileges) { + var matchingPriv = findInputPriv(requiredPriv.name); + var passesAuth = await this.verifyAuthenticationParameters(matchingPriv); + if(passesAuth) { + successfulPrivs.push(matchingPriv); + } else { + failedPrivs.push(matchingPriv); + } + } + + return { + success: failedPrivs.length == 0, + successfulPrivs: successfulPrivs, + failedPrivs: failedPrivs + } + } + + async verifyAuthenticationParameters(parameters) { + + let verifyAccountPassword = async (password) => { + return this.authManager.verifyAccountPassword(password); + } + + let verifyLocalPasscode = async (passcode) => { + return this.passcodeManager.verifyPasscode(passcode); + } + + if(parameters.name == PrivilegesManager.PrivilegeAccountPassword) { + return verifyAccountPassword(parameters.authenticationValue); + } else if(parameters.name == PrivilegesManager.PrivilegeLocalPasscode) { + return verifyLocalPasscode(parameters.authenticationValue); + } + } + +} + +angular.module('app').service('privilegesManager', PrivilegesManager); diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml new file mode 100644 index 000000000..a83f99b80 --- /dev/null +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -0,0 +1,17 @@ +.background{"ng-click" => "cancel()"} + +.content#privileges-modal + .sn-component + .panel + .header + %h1.title Authentication Required + %a.close-button.info{"ng-click" => "cancel()"} Cancel + .content + .panel-section + .panel-row{"ng-repeat" => "priv in privileges"} + %p {{priv.prompt}} + %input{"type" => "password", "ng-model" => "priv.authenticationValue"} + %label.danger{"ng-if" => "doesPrivHaveFail(priv)"} Invalid authentication. Please try again. + + .footer + .button.info.big.block.bold{"ng-click" => "submit()"} Submit diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index c4dfd0171..8ba4a11cf 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -1,7 +1,7 @@ .sn-component #footer-bar.app-bar.no-edges .left - .item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} + .item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.clickOutsideAccountMenu()", "is-open" => "ctrl.showAccountMenu"} .column .circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} .column From 0410391fc5721ca6a71d2c47e2c0398c63d32432 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 9 Nov 2018 13:49:49 -0600 Subject: [PATCH 02/62] Privileges modal --- .../javascripts/app/controllers/footer.js | 9 +- .../app/directives/views/accountMenu.js | 11 +- .../directives/views/privilegesAuthModal.js | 8 +- .../views/privilegesManagementModal.js | 61 ++++++++ .../app/services/privilegesManager.js | 142 ++++++++++++++---- .../directives/account-menu.html.haml | 5 +- .../privileges-management-modal.html.haml | 25 +++ 7 files changed, 225 insertions(+), 36 deletions(-) create mode 100644 app/assets/javascripts/app/directives/views/privilegesManagementModal.js create mode 100644 app/assets/templates/directives/privileges-management-modal.html.haml diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index 3131e7c36..47ac00b76 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -173,14 +173,17 @@ angular.module('app') } } - this.selectRoom = function(room) { + this.selectRoom = async function(room) { let run = () => { - room.showRoom = !room.showRoom; + $timeout(() => { + room.showRoom = !room.showRoom; + }) } if(!room.showRoom) { // About to show, check if has privileges - if(privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageExtensions)) { + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageExtensions)) { privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageExtensions, () => { run(); }); diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index b49dfff81..c59f7267d 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -167,10 +167,13 @@ class AccountMenu { $scope.openPasswordWizard = function(type) { // Close the account menu $scope.close(); - authManager.presentPasswordWizard(type); } + $scope.openPrivilegesModal = function() { + privilegesManager.presentPrivilegesManagementModal(); + } + // Allows indexeddb unencrypted logs to be deleted // clearAllModels will remove data from backing store, but not from working memory // See: https://github.com/standardnotes/desktop/issues/131 @@ -316,12 +319,12 @@ class AccountMenu { Export */ - $scope.downloadDataArchive = function() { + $scope.downloadDataArchive = async function() { let run = () => { archiveManager.downloadBackup($scope.archiveFormData.encrypted); } - - if(privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDownloadBackup)) { + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDownloadBackup)) { privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDownloadBackup, () => { run(); }); diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 56dd04aba..087d1ae04 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -24,7 +24,11 @@ class PrivilegesAuthModal { controller($scope, privilegesManager, $timeout) { 'ngInject'; - $scope.privileges = privilegesManager.privilegesForAction($scope.action); + privilegesManager.requiredCredentialsForAction($scope.action).then((privs) => { + $timeout(() => { + $scope.privileges = privs; + }) + }) $scope.cancel = function() { $scope.dismiss(); @@ -41,7 +45,7 @@ class PrivilegesAuthModal { } $scope.submit = function() { - privilegesManager.verifyPrivilegesForAction($scope.action, $scope.privileges).then((result) => { + privilegesManager.authenticateAction($scope.action, $scope.privileges).then((result) => { console.log("Result", result); $timeout(() => { if(result.success) { diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js new file mode 100644 index 000000000..a1c4aaa45 --- /dev/null +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -0,0 +1,61 @@ +class PrivilegesManagementModal { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/privileges-management-modal.html"; + this.scope = { + + }; + } + + link($scope, el, attrs) { + $scope.dismiss = function() { + el.remove(); + } + } + + controller($scope, privilegesManager, $timeout) { + 'ngInject'; + + $scope.reloadPrivileges = async function() { + console.log("Reloading privs"); + $scope.availableActions = privilegesManager.getAvailableActions(); + $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + + let metadata = {}; + for(let action of $scope.availableActions) { + var requiredCreds = await privilegesManager.requiredCredentialsForAction(action); + metadata[action] = { + displayInfo: privilegesManager.displayInfoForAction(action), + requiredCredentials: requiredCreds + } + + metadata[action]["credentialValues"] = {}; + for(var availableCred of $scope.availableCredentials) { + metadata[action]["credentialValues"][availableCred] = requiredCreds.includes(availableCred); + } + } + + $timeout(() => { + $scope.metadata = metadata; + }) + } + + $scope.checkboxValueChanged = function(action) { + let credentialValues = $scope.metadata[action]["credentialValues"]; + let keys = Object.keys(credentialValues).filter((key) => { + return credentialValues[key] == true; + }); + privilegesManager.setCredentialsForAction(action, keys); + } + + $scope.reloadPrivileges(); + + $scope.cancel = function() { + $scope.dismiss(); + $scope.onCancel && $scope.onCancel(); + } + } +} + +angular.module('app').directive('privilegesManagementModal', () => new PrivilegesManagementModal); diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index a621e6d5b..857a55d9f 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -1,27 +1,49 @@ class PrivilegesManager { - constructor(passcodeManager, authManager, $rootScope, $compile) { + constructor(passcodeManager, authManager, singletonManager, modelManager, $rootScope, $compile) { this.passcodeManager = passcodeManager; this.authManager = authManager; + this.singletonManager = singletonManager; + this.modelManager = modelManager; this.$rootScope = $rootScope; this.$compile = $compile; - PrivilegesManager.PrivilegeAccountPassword = "PrivilegeAccountPassword"; - PrivilegesManager.PrivilegeLocalPasscode = "PrivilegeLocalPasscode"; + this.loadPrivileges(); + + PrivilegesManager.CredentialAccountPassword = "CredentialAccountPassword"; + PrivilegesManager.CredentialLocalPasscode = "CredentialLocalPasscode"; PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; + + this.availableActions = [ + PrivilegesManager.ActionManageExtensions, + PrivilegesManager.ActionDownloadBackup + ] + + this.availableCredentials = [ + PrivilegesManager.CredentialAccountPassword, + PrivilegesManager.CredentialLocalPasscode + ]; + } + + getAvailableActions() { + return this.availableActions; + } + + getAvailableCredentials() { + return this.availableCredentials; } presentPrivilegesModal(action, onSuccess, onCancel) { let customSuccess = () => { - onSuccess(); + onSuccess && onSuccess(); this.currentAuthenticationElement = null; } let customCancel = () => { - onCancel(); + onCancel && onCancel(); this.currentAuthenticationElement = null; } @@ -35,30 +57,98 @@ class PrivilegesManager { this.currentAuthenticationElement = el; } + presentPrivilegesManagementModal() { + var scope = this.$rootScope.$new(true); + var el = this.$compile( "")(scope); + angular.element(document.body).append(el); + } + authenticationInProgress() { return this.currentAuthenticationElement != null; } - privilegesForAction(action) { - return [ - { - name: PrivilegesManager.PrivilegeAccountPassword, - label: "Account Password", - prompt: "Please enter your account password." - }, - { - name: PrivilegesManager.PrivilegeLocalPasscode, - label: "Local Passcode", - prompt: "Please enter your local passcode." - } - ] + async loadPrivileges() { + return new Promise((resolve, reject) => { + let prefsContentType = "SN|Privileges"; + let contentTypePredicate = new SFPredicate("content_type", "=", prefsContentType); + this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { + this.privileges = resolvedSingleton; + if(!this.privileges.content.desktopPrivileges) { + this.privileges.content.desktopPrivileges = []; + } + resolve(resolvedSingleton); + }, (valueCallback) => { + // Safe to create. Create and return object. + var privs = new SFItem({content_type: prefsContentType}); + this.modelManager.addItem(privs); + privs.setDirty(true); + this.$rootScope.sync(); + valueCallback(privs); + resolve(privs); + }); + }); } - actionRequiresPrivilege(action) { - return this.privilegesForAction(action).length > 0; + async getPrivileges() { + if(this.privileges) { + return this.privileges; + } else { + return this.loadPrivileges(); + } } - async verifyPrivilegesForAction(action, inputPrivs) { + async requiredCredentialsForAction(action) { + let privs = await this.getPrivileges(); + return privs.content.desktopPrivileges[action] || []; + } + + displayInfoForCredential(credential) { + let metadata = {} + + metadata[PrivilegesManager.CredentialAccountPassword] = { + label: "Account Password", + prompt: "Please enter your account password." + } + + metadata[PrivilegesManager.CredentialLocalPasscode] = { + label: "Local Passcode", + prompt: "Please enter your local passcode." + } + + return metadata[credential]; + } + + displayInfoForAction(action) { + let metadata = {}; + + metadata[PrivilegesManager.ActionManageExtensions] = { + label: "Manage Extensions" + } + metadata[PrivilegesManager.ActionDownloadBackup] = { + label: "Download Backups" + }; + + return metadata[action]; + } + + async actionRequiresPrivilege(action) { + return (await this.requiredCredentialsForAction(action)).length > 0; + } + + async setCredentialsForAction(action, credentials) { + console.log("Setting credentials for action", action, credentials); + let privs = await this.getPrivileges(); + privs.content.desktopPrivileges[action] = credentials; + this.savePrivileges(); + } + + async savePrivileges() { + let privs = await this.getPrivileges(); + privs.setDirty(true); + this.$rootScope.sync(); + } + + async authenticateAction(action, inputPrivs) { let findInputPriv = (name) => { return inputPrivs.find((priv) => { @@ -66,11 +156,11 @@ class PrivilegesManager { }) } - var requiredPrivileges = this.privilegesForAction(action); + var requiredPrivileges = await this.requiredCredentialsForAction(action); var successfulPrivs = [], failedPrivs = []; for(let requiredPriv of requiredPrivileges) { var matchingPriv = findInputPriv(requiredPriv.name); - var passesAuth = await this.verifyAuthenticationParameters(matchingPriv); + var passesAuth = await this._verifyAuthenticationParameters(matchingPriv); if(passesAuth) { successfulPrivs.push(matchingPriv); } else { @@ -85,7 +175,7 @@ class PrivilegesManager { } } - async verifyAuthenticationParameters(parameters) { + async _verifyAuthenticationParameters(parameters) { let verifyAccountPassword = async (password) => { return this.authManager.verifyAccountPassword(password); @@ -95,9 +185,9 @@ class PrivilegesManager { return this.passcodeManager.verifyPasscode(passcode); } - if(parameters.name == PrivilegesManager.PrivilegeAccountPassword) { + if(parameters.name == PrivilegesManager.CredentialAccountPassword) { return verifyAccountPassword(parameters.authenticationValue); - } else if(parameters.name == PrivilegesManager.PrivilegeLocalPasscode) { + } else if(parameters.name == PrivilegesManager.CredentialLocalPasscode) { return verifyLocalPasscode(parameters.authenticationValue); } } diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index f0fb6736c..ca512a6e4 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -85,7 +85,10 @@ .panel-row - %a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password + %a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} + Change Password + %a.panel-row.condensed{"ng-click" => "openPrivilegesModal('')"} + Manage Privileges %a.panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} .inline.circle.small.success.mr-8 .inline Security Update Available diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml new file mode 100644 index 000000000..028393d74 --- /dev/null +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -0,0 +1,25 @@ +.background{"ng-click" => "cancel()"} + +.content#privileges-modal + .sn-component + .panel + .header + %h1.title Manage Privileges + %a.close-button.info{"ng-click" => "cancel()"} Cancel + .content + .panel-section + %table + %thead + %tr + %th + %th{"ng-repeat" => "cred in availableCredentials"} + {{cred}} + %tbody + %tr{"ng-repeat" => "action in availableActions"} + %td + %p {{metadata[action].displayInfo.label}} + %th{"ng-repeat" => "cred in availableCredentials"} + %input{"type" => "checkbox", "ng-model" => "metadata[action]['credentialValues'][cred]", "ng-change" => "checkboxValueChanged(action)"} + + .footer + .button.info.big.block.bold{"ng-click" => "submit()"} Save From 9835992e166c03334f3106f104f939cdc8e88522 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 12 Nov 2018 15:16:50 -0600 Subject: [PATCH 03/62] Privs small refactor --- .../directives/functional/infiniteScroll.js | 3 - .../directives/views/privilegesAuthModal.js | 26 +++++---- .../views/privilegesManagementModal.js | 47 +++++++--------- .../javascripts/app/models/privileges.js | 34 ++++++++++++ .../javascripts/app/services/modelManager.js | 3 +- .../app/services/privilegesManager.js | 55 ++++++------------- .../privileges-auth-modal.html.haml | 8 +-- .../privileges-management-modal.html.haml | 13 ++--- 8 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 app/assets/javascripts/app/models/privileges.js diff --git a/app/assets/javascripts/app/directives/functional/infiniteScroll.js b/app/assets/javascripts/app/directives/functional/infiniteScroll.js index 3e1e633ef..21bacd325 100644 --- a/app/assets/javascripts/app/directives/functional/infiniteScroll.js +++ b/app/assets/javascripts/app/directives/functional/infiniteScroll.js @@ -2,9 +2,6 @@ angular.module('app').directive('infiniteScroll', [ '$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) { return { link: function(scope, elem, attrs) { - // elem.css('overflow-x', 'hidden'); - // elem.css('height', 'inherit'); - var offset = parseInt(attrs.threshold) || 0; var e = elem[0] diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 087d1ae04..99dad564d 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -24,35 +24,41 @@ class PrivilegesAuthModal { controller($scope, privilegesManager, $timeout) { 'ngInject'; - privilegesManager.requiredCredentialsForAction($scope.action).then((privs) => { + $scope.authenticationParameters = {}; + + privilegesManager.getPrivileges().then((privileges) => { $timeout(() => { - $scope.privileges = privs; + $scope.privileges = privileges; + $scope.requiredCredentials = privileges.getCredentialsForAction($scope.action); }) - }) + }); + + $scope.promptForCredential = function(credential) { + return privilegesManager.displayInfoForCredential(credential).prompt; + } $scope.cancel = function() { $scope.dismiss(); $scope.onCancel && $scope.onCancel(); } - $scope.doesPrivHaveFail = function(priv) { - if(!$scope.failedPrivs) { + $scope.isCredentialInFailureState = function(credential) { + if(!$scope.failedCredentials) { return false; } - return $scope.failedPrivs.find((failedPriv) => { - return failedPriv.name == priv.name; + return $scope.failedCredentials.find((candidate) => { + return candidate == credential; }) != null; } $scope.submit = function() { - privilegesManager.authenticateAction($scope.action, $scope.privileges).then((result) => { - console.log("Result", result); + privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => { $timeout(() => { if(result.success) { $scope.onSuccess(); $scope.dismiss(); } else { - $scope.failedPrivs = result.failedPrivs; + $scope.failedCredentials = result.failedCredentials; } }) }) diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js index a1c4aaa45..b792d3858 100644 --- a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -17,36 +17,29 @@ class PrivilegesManagementModal { controller($scope, privilegesManager, $timeout) { 'ngInject'; - $scope.reloadPrivileges = async function() { - console.log("Reloading privs"); - $scope.availableActions = privilegesManager.getAvailableActions(); - $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + $scope.dummy = {}; - let metadata = {}; - for(let action of $scope.availableActions) { - var requiredCreds = await privilegesManager.requiredCredentialsForAction(action); - metadata[action] = { - displayInfo: privilegesManager.displayInfoForAction(action), - requiredCredentials: requiredCreds - } - - metadata[action]["credentialValues"] = {}; - for(var availableCred of $scope.availableCredentials) { - metadata[action]["credentialValues"][availableCred] = requiredCreds.includes(availableCred); - } - } - - $timeout(() => { - $scope.metadata = metadata; - }) + $scope.displayInfoForCredential = function(credential) { + return privilegesManager.displayInfoForCredential(credential).label; } - $scope.checkboxValueChanged = function(action) { - let credentialValues = $scope.metadata[action]["credentialValues"]; - let keys = Object.keys(credentialValues).filter((key) => { - return credentialValues[key] == true; - }); - privilegesManager.setCredentialsForAction(action, keys); + $scope.displayInfoForAction = function(action) { + return privilegesManager.displayInfoForAction(action).label; + } + + $scope.isCredentialRequiredForAction = function(action, credential) { + return $scope.privileges.isCredentialRequiredForAction(action, credential); + } + + $scope.reloadPrivileges = async function() { + $scope.privileges = await privilegesManager.getPrivileges(); + $scope.availableActions = privilegesManager.getAvailableActions(); + $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + } + + $scope.checkboxValueChanged = function(action, credential) { + $scope.privileges.toggleCredentialForAction(action, credential); + privilegesManager.savePrivileges(); } $scope.reloadPrivileges(); diff --git a/app/assets/javascripts/app/models/privileges.js b/app/assets/javascripts/app/models/privileges.js new file mode 100644 index 000000000..3fb5f96fa --- /dev/null +++ b/app/assets/javascripts/app/models/privileges.js @@ -0,0 +1,34 @@ +class SNPrivileges extends SFItem { + + setCredentialsForAction(action, credentials) { + this.content.desktopPrivileges[action] = credentials; + } + + getCredentialsForAction(action) { + return this.content.desktopPrivileges[action] || []; + } + + toggleCredentialForAction(action, credential) { + if(this.isCredentialRequiredForAction(action, credential)) { + this.removeCredentialForAction(action, credential); + } else { + this.addCredentialForAction(action, credential); + } + } + + removeCredentialForAction(action, credential) { + _.pull(this.content.desktopPrivileges[action], credential); + } + + addCredentialForAction(action, credential) { + var credentials = this.getCredentialsForAction(action); + credentials.push(credential); + this.setCredentialsForAction(action, credentials); + } + + isCredentialRequiredForAction(action, credential) { + var credentialsRequired = this.getCredentialsForAction(action); + return credentialsRequired.includes(credential); + } + +} diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index c3f30c207..9af2df562 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -7,7 +7,8 @@ SFModelManager.ContentTypeClassMapping = { "SN|Theme" : SNTheme, "SN|Component" : SNComponent, "SF|Extension" : SNServerExtension, - "SF|MFA" : SNMfa + "SF|MFA" : SNMfa, + "SN|Privileges" : SNPrivileges }; SFItem.AppDomain = "org.standardnotes.sn"; diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 857a55d9f..18dd7c386 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -74,12 +74,12 @@ class PrivilegesManager { this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { this.privileges = resolvedSingleton; if(!this.privileges.content.desktopPrivileges) { - this.privileges.content.desktopPrivileges = []; + this.privileges.content.desktopPrivileges = {}; } resolve(resolvedSingleton); }, (valueCallback) => { // Safe to create. Create and return object. - var privs = new SFItem({content_type: prefsContentType}); + var privs = new Privilege({content_type: prefsContentType}); this.modelManager.addItem(privs); privs.setDirty(true); this.$rootScope.sync(); @@ -97,11 +97,6 @@ class PrivilegesManager { } } - async requiredCredentialsForAction(action) { - let privs = await this.getPrivileges(); - return privs.content.desktopPrivileges[action] || []; - } - displayInfoForCredential(credential) { let metadata = {} @@ -132,14 +127,7 @@ class PrivilegesManager { } async actionRequiresPrivilege(action) { - return (await this.requiredCredentialsForAction(action)).length > 0; - } - - async setCredentialsForAction(action, credentials) { - console.log("Setting credentials for action", action, credentials); - let privs = await this.getPrivileges(); - privs.content.desktopPrivileges[action] = credentials; - this.savePrivileges(); + return (await this.getPrivileges()).getCredentialsForAction(action).length > 0; } async savePrivileges() { @@ -148,34 +136,27 @@ class PrivilegesManager { this.$rootScope.sync(); } - async authenticateAction(action, inputPrivs) { + async authenticateAction(action, credentialAuthMapping) { + var requiredCredentials = (await this.getPrivileges()).getCredentialsForAction(action); + var successfulCredentials = [], failedCredentials = []; - let findInputPriv = (name) => { - return inputPrivs.find((priv) => { - return priv.name == name; - }) - } - - var requiredPrivileges = await this.requiredCredentialsForAction(action); - var successfulPrivs = [], failedPrivs = []; - for(let requiredPriv of requiredPrivileges) { - var matchingPriv = findInputPriv(requiredPriv.name); - var passesAuth = await this._verifyAuthenticationParameters(matchingPriv); + for(let requiredCredential of requiredCredentials) { + var passesAuth = await this._verifyAuthenticationParameters(requiredCredential, credentialAuthMapping[requiredCredential]); if(passesAuth) { - successfulPrivs.push(matchingPriv); + successfulCredentials.push(requiredCredential); } else { - failedPrivs.push(matchingPriv); + failedCredentials.push(requiredCredential); } } return { - success: failedPrivs.length == 0, - successfulPrivs: successfulPrivs, - failedPrivs: failedPrivs + success: failedCredentials.length == 0, + successfulCredentials: successfulCredentials, + failedCredentials: failedCredentials } } - async _verifyAuthenticationParameters(parameters) { + async _verifyAuthenticationParameters(credential, value) { let verifyAccountPassword = async (password) => { return this.authManager.verifyAccountPassword(password); @@ -185,10 +166,10 @@ class PrivilegesManager { return this.passcodeManager.verifyPasscode(passcode); } - if(parameters.name == PrivilegesManager.CredentialAccountPassword) { - return verifyAccountPassword(parameters.authenticationValue); - } else if(parameters.name == PrivilegesManager.CredentialLocalPasscode) { - return verifyLocalPasscode(parameters.authenticationValue); + if(credential == PrivilegesManager.CredentialAccountPassword) { + return verifyAccountPassword(value); + } else if(credential == PrivilegesManager.CredentialLocalPasscode) { + return verifyLocalPasscode(value); } } diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index a83f99b80..2603614a0 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -8,10 +8,10 @@ %a.close-button.info{"ng-click" => "cancel()"} Cancel .content .panel-section - .panel-row{"ng-repeat" => "priv in privileges"} - %p {{priv.prompt}} - %input{"type" => "password", "ng-model" => "priv.authenticationValue"} - %label.danger{"ng-if" => "doesPrivHaveFail(priv)"} Invalid authentication. Please try again. + .panel-row{"ng-repeat" => "credential in requiredCredentials"} + %p {{promptForCredential(credential)}} + %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} + %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. .footer .button.info.big.block.bold{"ng-click" => "submit()"} Submit diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 028393d74..94292cf7e 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -5,7 +5,7 @@ .panel .header %h1.title Manage Privileges - %a.close-button.info{"ng-click" => "cancel()"} Cancel + %a.close-button.info{"ng-click" => "cancel()"} Done .content .panel-section %table @@ -13,13 +13,10 @@ %tr %th %th{"ng-repeat" => "cred in availableCredentials"} - {{cred}} + {{displayInfoForCredential(cred)}} %tbody %tr{"ng-repeat" => "action in availableActions"} %td - %p {{metadata[action].displayInfo.label}} - %th{"ng-repeat" => "cred in availableCredentials"} - %input{"type" => "checkbox", "ng-model" => "metadata[action]['credentialValues'][cred]", "ng-change" => "checkboxValueChanged(action)"} - - .footer - .button.info.big.block.bold{"ng-click" => "submit()"} Save + %p {{displayInfoForAction(action)}} + %th{"ng-repeat" => "credential in availableCredentials"} + %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} From 091f4cff7f05bb8d8df1bf3bcd0473239279d8f2 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 13 Nov 2018 15:05:57 -0600 Subject: [PATCH 04/62] Autolock wip --- .../javascripts/app/controllers/notes.js | 29 +- .../app/directives/views/accountMenu.js | 19 +- .../javascripts/app/services/httpManager.js | 2 +- .../app/services/passcodeManager.js | 273 +++++++++++------- .../app/services/privilegesManager.js | 15 +- app/assets/stylesheets/app/_editor.scss | 11 +- app/assets/stylesheets/app/_modals.scss | 4 + .../directives/account-menu.html.haml | 7 +- .../privileges-management-modal.html.haml | 11 + app/assets/templates/footer.html.haml | 2 +- app/assets/templates/notes.html.haml | 4 +- 11 files changed, 258 insertions(+), 119 deletions(-) diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 1c33e0d1b..6c0f54644 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -31,7 +31,8 @@ angular.module('app') } } }) - .controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, storageManager, desktopManager) { + .controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, + storageManager, desktopManager, privilegesManager) { this.panelController = {}; @@ -198,19 +199,31 @@ angular.module('app') } } - this.selectNote = function(note, viaClick = false) { + this.selectNote = async function(note, viaClick = false) { if(!note) { this.createNewNote(); return; } - this.selectedNote = note; - note.conflict_of = null; // clear conflict - this.selectionMade()(note); - this.selectedIndex = Math.max(this.visibleNotes().indexOf(note), 0); + let run = () => { + $timeout(() => { + this.selectedNote = note; + note.conflict_of = null; // clear conflict + this.selectionMade()(note); + this.selectedIndex = Math.max(this.visibleNotes().indexOf(note), 0); - if(viaClick && this.isFiltering()) { - desktopManager.searchText(this.noteFilter.text); + if(viaClick && this.isFiltering()) { + desktopManager.searchText(this.noteFilter.text); + } + }) + } + + if(note.locked && await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionViewLockedNotes)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionViewLockedNotes, () => { + run(); + }); + } else { + run(); } } diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index c59f7267d..5a6c17450 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -38,7 +38,6 @@ class AccountMenu { } $scope.canAddPasscode = !authManager.isEphemeralSession(); - $scope.syncStatus = syncManager.syncStatus; $scope.submitMfaForm = function() { @@ -375,6 +374,24 @@ class AccountMenu { Passcode Lock */ + $scope.passcodeAutoLockOptions = passcodeManager.getAutoLockIntervalOptions(); + + $scope.reloadAutoLockInterval = function() { + passcodeManager.getAutoLockInterval().then((interval) => { + $timeout(() => { + $scope.selectedAutoLockInterval = interval; + console.log("selectedAutoLockInterval", $scope.selectedAutoLockInterval); + }) + }) + } + + $scope.reloadAutoLockInterval(); + + $scope.selectAutoLockInterval = async function(interval) { + await passcodeManager.setAutoLockInterval(interval); + $scope.reloadAutoLockInterval(); + } + $scope.hasPasscode = function() { return passcodeManager.hasPasscode(); } diff --git a/app/assets/javascripts/app/services/httpManager.js b/app/assets/javascripts/app/services/httpManager.js index 637db6041..a3415b4b5 100644 --- a/app/assets/javascripts/app/services/httpManager.js +++ b/app/assets/javascripts/app/services/httpManager.js @@ -5,7 +5,7 @@ class HttpManager extends SFHttpManager { super($timeout); this.setJWTRequestHandler(async () => { - return storageManager.getItem("jwt");; + return storageManager.getItem("jwt"); }) } } diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 8d6fad7fa..0210ee96b 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,112 +1,183 @@ -angular.module('app') - .provider('passcodeManager', function () { +class PasscodeManager { - this.$get = function($rootScope, $timeout, modelManager, dbManager, authManager, storageManager) { - return new PasscodeManager($rootScope, $timeout, modelManager, dbManager, authManager, storageManager); - } + constructor(authManager, storageManager) { + document.addEventListener('visibilitychange', () => { + this.documentVisibilityChanged(document.visibilityState); + }); - function PasscodeManager($rootScope, $timeout, modelManager, dbManager, authManager, storageManager) { + this.authManager = authManager; + this.storageManager = storageManager; - this._hasPasscode = storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; + this._hasPasscode = this.storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; this._locked = this._hasPasscode; - this.isLocked = function() { - return this._locked; - } + const MillisecondsPerSecond = 1000; + PasscodeManager.AutoLockIntervalNone = 0; + PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; - this.hasPasscode = function() { - return this._hasPasscode; - } + PasscodeManager.AutoLockIntervalKey = "AutoLockIntervalKey"; + } - this.keys = function() { - return this._keys; - } - - this.passcodeAuthParams = function() { - var authParams = JSON.parse(storageManager.getItemSync("offlineParams", StorageManager.Fixed)); - if(authParams && !authParams.version) { - var keys = this.keys(); - if(keys && keys.ak) { - // If there's no version stored, and there's an ak, it has to be 002. Newer versions would have thier version stored in authParams. - authParams.version = "002"; - } else { - authParams.version = "001"; - } + getAutoLockIntervalOptions() { + return [ + { + value: PasscodeManager.AutoLockIntervalNone, + label: "None" + }, + { + value: PasscodeManager.AutoLockIntervalOneMinute, + label: "1 Min" + }, + { + value: PasscodeManager.AutoLockIntervalFiveMinutes, + label: "5 Min" + }, + { + value: PasscodeManager.AutoLockIntervalOneHour, + label: "1 Hr" } - return authParams; - } + ] + } - this.verifyPasscode = async function(passcode) { - return new Promise(async (resolve, reject) => { - var params = this.passcodeAuthParams(); - let keys = await SFJS.crypto.computeEncryptionKeysForUser(passcode, params); - if(keys.pw !== params.hash) { - resolve(false); - } else { - resolve(true); - } - }) - } - - this.unlock = function(passcode, callback) { - var params = this.passcodeAuthParams(); - SFJS.crypto.computeEncryptionKeysForUser(passcode, params).then((keys) => { - if(keys.pw !== params.hash) { - callback(false); - return; - } - - this._keys = keys; - this._authParams = params; - this.decryptLocalStorage(keys, params).then(() => { - this._locked = false; - callback(true); - }) - }); - } - - this.setPasscode = (passcode, callback) => { - var uuid = SFJS.crypto.generateUUIDSync(); - - SFJS.crypto.generateInitialKeysAndAuthParamsForUser(uuid, passcode).then((results) => { - let keys = results.keys; - let authParams = results.authParams; - - authParams.hash = keys.pw; - this._keys = keys; - this._hasPasscode = true; - this._authParams = authParams; - - // Encrypting will initially clear localStorage - this.encryptLocalStorage(keys, authParams); - - // After it's cleared, it's safe to write to it - storageManager.setItem("offlineParams", JSON.stringify(authParams), StorageManager.Fixed); - callback(true); - }); - } - - this.changePasscode = (newPasscode, callback) => { - this.setPasscode(newPasscode, callback); - } - - this.clearPasscode = function() { - storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.Fixed); // Transfer from Ephemeral - storageManager.removeItem("offlineParams", StorageManager.Fixed); - this._keys = null; - this._hasPasscode = false; - } - - this.encryptLocalStorage = function(keys, authParams) { - storageManager.setKeys(keys, authParams); - // Switch to Ephemeral storage, wiping Fixed storage - // Last argument is `force`, which we set to true because in the case of changing passcode - storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted, true); - } - - this.decryptLocalStorage = async function(keys, authParams) { - storageManager.setKeys(keys, authParams); - return storageManager.decryptStorage(); + documentVisibilityChanged(visbility) { + let visible = document.visibilityState == "visible"; + if(!visible) { + this.beginAutoLockTimer(); + } else { + this.cancelAutoLockTimer(); } } -}); + + async beginAutoLockTimer() { + console.log("beginAutoLockTimer"); + var interval = await this.getAutoLockInterval(); + this.lockTimeout = setTimeout(() => { + this.lockApplication(); + }, interval); + } + + cancelAutoLockTimer() { + console.log("cancelAutoLockTimer"); + clearTimeout(this.lockTimeout); + } + + lockApplication() { + console.log("lockApplication"); + window.location.reload(); + this.cancelAutoLockTimer(); + } + + isLocked() { + return this._locked; + } + + hasPasscode() { + return this._hasPasscode; + } + + keys() { + return this._keys; + } + + async setAutoLockInterval(interval) { + console.log("Set autolock interval", interval); + return this.storageManager.setItem(PasscodeManager.AutoLockIntervalKey, JSON.stringify(interval), StorageManager.Fixed); + } + + async getAutoLockInterval() { + let interval = await this.storageManager.getItem(PasscodeManager.AutoLockIntervalKey, StorageManager.Fixed); + console.log("Got interval", interval); + return interval && JSON.parse(interval); + } + + passcodeAuthParams() { + var authParams = JSON.parse(this.storageManager.getItemSync("offlineParams", StorageManager.Fixed)); + if(authParams && !authParams.version) { + var keys = this.keys(); + if(keys && keys.ak) { + // If there's no version stored, and there's an ak, it has to be 002. Newer versions would have their version stored in authParams. + authParams.version = "002"; + } else { + authParams.version = "001"; + } + } + return authParams; + } + + async verifyPasscode(passcode) { + return new Promise(async (resolve, reject) => { + var params = this.passcodeAuthParams(); + let keys = await SFJS.crypto.computeEncryptionKeysForUser(passcode, params); + if(keys.pw !== params.hash) { + resolve(false); + } else { + resolve(true); + } + }) + } + + unlock(passcode, callback) { + var params = this.passcodeAuthParams(); + SFJS.crypto.computeEncryptionKeysForUser(passcode, params).then((keys) => { + if(keys.pw !== params.hash) { + callback(false); + return; + } + + this._keys = keys; + this._authParams = params; + this.decryptLocalStorage(keys, params).then(() => { + this._locked = false; + callback(true); + }) + }); + } + + setPasscode(passcode, callback) { + var uuid = SFJS.crypto.generateUUIDSync(); + + SFJS.crypto.generateInitialKeysAndAuthParamsForUser(uuid, passcode).then((results) => { + let keys = results.keys; + let authParams = results.authParams; + + authParams.hash = keys.pw; + this._keys = keys; + this._hasPasscode = true; + this._authParams = authParams; + + // Encrypting will initially clear localStorage + this.encryptLocalStorage(keys, authParams); + + // After it's cleared, it's safe to write to it + this.storageManager.setItem("offlineParams", JSON.stringify(authParams), StorageManager.Fixed); + callback(true); + }); + } + + changePasscode(newPasscode, callback) { + this.setPasscode(newPasscode, callback); + } + + clearPasscode() { + this.storageManager.setItemsMode(this.authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.Fixed); // Transfer from Ephemeral + this.storageManager.removeItem("offlineParams", StorageManager.Fixed); + this._keys = null; + this._hasPasscode = false; + } + + encryptLocalStorage(keys, authParams) { + this.storageManager.setKeys(keys, authParams); + // Switch to Ephemeral storage, wiping Fixed storage + // Last argument is `force`, which we set to true because in the case of changing passcode + this.storageManager.setItemsMode(this.authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted, true); + } + + async decryptLocalStorage(keys, authParams) { + this.storageManager.setKeys(keys, authParams); + return this.storageManager.decryptStorage(); + } +} + +angular.module('app').service('passcodeManager', PasscodeManager); diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 18dd7c386..8736057e4 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -15,10 +15,14 @@ class PrivilegesManager { PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; + PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; + PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; this.availableActions = [ PrivilegesManager.ActionManageExtensions, - PrivilegesManager.ActionDownloadBackup + PrivilegesManager.ActionDownloadBackup, + PrivilegesManager.ActionViewLockedNotes, + PrivilegesManager.ActionManagePrivileges ] this.availableCredentials = [ @@ -119,10 +123,19 @@ class PrivilegesManager { metadata[PrivilegesManager.ActionManageExtensions] = { label: "Manage Extensions" } + metadata[PrivilegesManager.ActionDownloadBackup] = { label: "Download Backups" }; + metadata[PrivilegesManager.ActionViewLockedNotes] = { + label: "View Locked Notes" + }; + + metadata[PrivilegesManager.ActionManagePrivileges] = { + label: "Manage Privileges" + } + return metadata[action]; } diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 0d4f3b225..272791b94 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -1,4 +1,11 @@ $heading-height: 75px; + +#editor-column { + .locked { + opacity: 0.8; + } +} + .editor { flex: 1 50%; display: flex; @@ -7,10 +14,6 @@ $heading-height: 75px; background-color: white; } -.locked { - opacity: 0.8; -} - #editor-title-bar { width: 100%; diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index ca1dac561..6d6278cbd 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -12,6 +12,10 @@ } } +#privileges-modal { + width: 700px; +} + #password-wizard { font-size: 16px; } diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index ca512a6e4..9733c4a59 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -130,7 +130,12 @@ .horizontal-group %a.info{"ng-click" => "changePasscodePressed()"} Change Passcode %a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode - + .panel-row + .horizontal-group + %p Autolock: + %a.info{"ng-repeat" => "option in passcodeAutoLockOptions", "ng-click" => "selectAutoLockInterval(option.value)", + "ng-class" => "{'info bold' : option.value == selectedAutoLockInterval}"} + {{option.label}} .panel-section{"ng-if" => "!importData.loading"} diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 94292cf7e..e4f730e2d 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -20,3 +20,14 @@ %p {{displayInfoForAction(action)}} %th{"ng-repeat" => "credential in availableCredentials"} %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} + .footer + %h2 About Privileges + %p + Privileges represent interface level authentication for accessing certain items and features. + Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. + Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. + + %p + Privileges sync across your other devices (not including mobile); however, note that if you require + a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode + requirement will be ignored on that device. diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index 8ba4a11cf..c2a8e5c93 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -39,6 +39,6 @@ .item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} .label Refresh - .item#lock-item{"ng-if" => "ctrl.hasPasscode()"} + .item#lock-item{"ng-if" => "ctrl.hasPasscode()", "title" => "Locks application and wipes unencrypted data from memory."} .label %i.icon.ion-locked#footer-lock-icon{"ng-if" => "ctrl.hasPasscode()", "ng-click" => "ctrl.lockApp()"} diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index a1e48dd1b..46f1ab1a0 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -59,9 +59,11 @@ .faded {{note.savedTagsString || note.tagsString()}} .name{"ng-if" => "note.title"} + %span.locked.tinted{"ng-if" => "note.locked", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} + %i.icon.ion-locked.medium-text {{note.title}} - .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview"} + .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview && !note.locked"} .html-preview{"ng-if" => "note.content.preview_html", "ng-bind-html" => "note.content.preview_html"} .plain-preview{"ng-if" => "!note.content.preview_html && note.content.preview_plain"} {{note.content.preview_plain}} .default-preview{"ng-if" => "!note.content.preview_html && !note.content.preview_plain"} {{note.text}} From bb8140d89c40fb0190e9f94a581c60d06ec309e7 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 14 Nov 2018 14:06:23 -0600 Subject: [PATCH 05/62] Autolock UI --- .../app/directives/views/accountMenu.js | 5 +- .../app/services/passcodeManager.js | 23 +- .../app/services/privilegesManager.js | 2 +- .../directives/account-menu.html.haml | 6 +- .../privileges-management-modal.html.haml | 19 +- package-lock.json | 882 +++++++++++++++++- package.json | 2 +- 7 files changed, 911 insertions(+), 28 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index 5a6c17450..d7a9c3414 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -380,7 +380,6 @@ class AccountMenu { passcodeManager.getAutoLockInterval().then((interval) => { $timeout(() => { $scope.selectedAutoLockInterval = interval; - console.log("selectedAutoLockInterval", $scope.selectedAutoLockInterval); }) }) } @@ -407,10 +406,10 @@ class AccountMenu { return; } - let fn = $scope.formData.changingPasscode ? passcodeManager.changePasscode : passcodeManager.setPasscode; + let fn = $scope.formData.changingPasscode ? passcodeManager.changePasscode.bind(passcodeManager) : passcodeManager.setPasscode.bind(passcodeManager); fn(passcode, () => { - $timeout(function(){ + $timeout(() => { $scope.formData.showPasscodeForm = false; var offline = authManager.offline(); diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 0210ee96b..4abd4fba0 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,7 +1,8 @@ class PasscodeManager { constructor(authManager, storageManager) { - document.addEventListener('visibilitychange', () => { + document.addEventListener('visibilitychange', (e) => { + console.log("visibilitychange", e, document.visibilityState); this.documentVisibilityChanged(document.visibilityState); }); @@ -13,6 +14,7 @@ class PasscodeManager { const MillisecondsPerSecond = 1000; PasscodeManager.AutoLockIntervalNone = 0; + PasscodeManager.AutoLockIntervalFiveSecs = 5 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; @@ -26,6 +28,10 @@ class PasscodeManager { value: PasscodeManager.AutoLockIntervalNone, label: "None" }, + { + value: PasscodeManager.AutoLockIntervalFiveSecs, + label: "5 Secs" + }, { value: PasscodeManager.AutoLockIntervalOneMinute, label: "1 Min" @@ -51,20 +57,21 @@ class PasscodeManager { } async beginAutoLockTimer() { - console.log("beginAutoLockTimer"); var interval = await this.getAutoLockInterval(); + if(interval == PasscodeManager.AutoLockIntervalNone) { + return; + } + this.lockTimeout = setTimeout(() => { this.lockApplication(); }, interval); } cancelAutoLockTimer() { - console.log("cancelAutoLockTimer"); clearTimeout(this.lockTimeout); } lockApplication() { - console.log("lockApplication"); window.location.reload(); this.cancelAutoLockTimer(); } @@ -82,14 +89,16 @@ class PasscodeManager { } async setAutoLockInterval(interval) { - console.log("Set autolock interval", interval); return this.storageManager.setItem(PasscodeManager.AutoLockIntervalKey, JSON.stringify(interval), StorageManager.Fixed); } async getAutoLockInterval() { let interval = await this.storageManager.getItem(PasscodeManager.AutoLockIntervalKey, StorageManager.Fixed); - console.log("Got interval", interval); - return interval && JSON.parse(interval); + if(interval) { + return JSON.parse(interval); + } else { + return PasscodeManager.AutoLockIntervalNone; + } } passcodeAuthParams() { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 8736057e4..178034d92 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -83,7 +83,7 @@ class PrivilegesManager { resolve(resolvedSingleton); }, (valueCallback) => { // Safe to create. Create and return object. - var privs = new Privilege({content_type: prefsContentType}); + var privs = new SNPrivileges({content_type: prefsContentType}); this.modelManager.addItem(privs); privs.setDirty(true); this.$rootScope.sync(); diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 9733c4a59..ae99c67b7 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -132,10 +132,12 @@ %a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode .panel-row .horizontal-group - %p Autolock: + %h4 Autolock + .vertical-rule %a.info{"ng-repeat" => "option in passcodeAutoLockOptions", "ng-click" => "selectAutoLockInterval(option.value)", - "ng-class" => "{'info bold' : option.value == selectedAutoLockInterval}"} + "ng-class" => "{'info boxed' : option.value == selectedAutoLockInterval}"} {{option.label}} + %p The autolock timer begins when the window or tab loses focus. .panel-section{"ng-if" => "!importData.loading"} diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index e4f730e2d..52898a899 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -22,12 +22,13 @@ %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} .footer %h2 About Privileges - %p - Privileges represent interface level authentication for accessing certain items and features. - Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. - Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. - - %p - Privileges sync across your other devices (not including mobile); however, note that if you require - a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode - requirement will be ignored on that device. + .panel-section.no-bottom-pad + .text-content + %p + Privileges represent interface level authentication for accessing certain items and features. + Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. + Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. + %p + Privileges sync across your other devices (not including mobile); however, note that if you require + a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode + requirement will be ignored on that device. diff --git a/package-lock.json b/package-lock.json index 712f36497..ffdf0d56e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.16", + "version": "2.3.17", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -7728,10 +7728,882 @@ "dev": true }, "sn-stylekit": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-1.0.15.tgz", - "integrity": "sha512-QeWlaCMHtF/VhFWWICzmx39ger92DEj1uLiCW4VVLX9LtU7nKQ5plqHgrpvnctO+wNh9LIYdPBLLWxTwgXm6Eg==", - "dev": true + "version": "file:../Stylekit", + "dev": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true + }, + "argparse": { + "version": "1.0.9", + "bundled": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-find-index": { + "version": "1.0.2", + "bundled": true + }, + "async": { + "version": "1.5.2", + "bundled": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "body-parser": { + "version": "1.14.2", + "bundled": true, + "requires": { + "bytes": "2.2.0", + "content-type": "~1.0.1", + "debug": "~2.2.0", + "depd": "~1.1.0", + "http-errors": "~1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "~2.3.0", + "qs": "5.2.0", + "raw-body": "~2.1.5", + "type-is": "~1.6.10" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "bundled": true, + "requires": { + "ms": "0.7.1" + } + }, + "iconv-lite": { + "version": "0.4.13", + "bundled": true + }, + "ms": { + "version": "0.7.1", + "bundled": true + }, + "qs": { + "version": "5.2.0", + "bundled": true + } + } + }, + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true + }, + "bytes": { + "version": "2.2.0", + "bundled": true + }, + "camelcase": { + "version": "2.1.1", + "bundled": true + }, + "camelcase-keys": { + "version": "2.1.0", + "bundled": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "coffee-script": { + "version": "1.10.0", + "bundled": true + }, + "colors": { + "version": "1.1.2", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "content-type": { + "version": "1.0.4", + "bundled": true + }, + "cross-spawn": { + "version": "0.2.9", + "bundled": true, + "requires": { + "lru-cache": "^2.5.0" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "bundled": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dargs": { + "version": "4.1.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "dateformat": { + "version": "1.0.12", + "bundled": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true + }, + "depd": { + "version": "1.1.1", + "bundled": true + }, + "ee-first": { + "version": "1.1.1", + "bundled": true + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "esprima": { + "version": "2.7.3", + "bundled": true + }, + "eventemitter2": { + "version": "0.4.14", + "bundled": true + }, + "exit": { + "version": "0.1.2", + "bundled": true + }, + "faye-websocket": { + "version": "0.10.0", + "bundled": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "find-up": { + "version": "1.1.2", + "bundled": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "findup-sync": { + "version": "0.3.0", + "bundled": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "bundled": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gaze": { + "version": "1.1.2", + "bundled": true, + "requires": { + "globule": "^1.0.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "bundled": true + }, + "getobject": { + "version": "0.1.0", + "bundled": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globule": { + "version": "1.2.0", + "bundled": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.4", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "grunt": { + "version": "1.0.1", + "bundled": true, + "requires": { + "coffee-script": "~1.10.0", + "dateformat": "~1.0.12", + "eventemitter2": "~0.4.13", + "exit": "~0.1.1", + "findup-sync": "~0.3.0", + "glob": "~7.0.0", + "grunt-cli": "~1.2.0", + "grunt-known-options": "~1.1.0", + "grunt-legacy-log": "~1.0.0", + "grunt-legacy-util": "~1.0.0", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.5.2", + "minimatch": "~3.0.0", + "nopt": "~3.0.6", + "path-is-absolute": "~1.0.0", + "rimraf": "~2.2.8" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "grunt-cli": { + "version": "1.2.0", + "bundled": true, + "requires": { + "findup-sync": "~0.3.0", + "grunt-known-options": "~1.1.0", + "nopt": "~3.0.6", + "resolve": "~1.1.0" + } + } + } + }, + "grunt-contrib-sass": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "^0.9.0", + "chalk": "^1.0.0", + "cross-spawn": "^0.2.3", + "dargs": "^4.0.0", + "which": "^1.0.5" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "bundled": true + } + } + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "^1.5.0", + "gaze": "^1.0.0", + "lodash": "^3.10.1", + "tiny-lr": "^0.2.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "bundled": true + } + } + }, + "grunt-haml2html": { + "version": "0.3.1", + "bundled": true, + "requires": { + "dargs": "~0.1.0" + }, + "dependencies": { + "dargs": { + "version": "0.1.0", + "bundled": true + } + } + }, + "grunt-known-options": { + "version": "1.1.0", + "bundled": true + }, + "grunt-legacy-log": { + "version": "1.0.0", + "bundled": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~3.10.1", + "underscore.string": "~3.2.3" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "bundled": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "1.0.0", + "bundled": true, + "requires": { + "chalk": "~1.1.1", + "lodash": "~4.3.0" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "bundled": true + } + } + }, + "grunt-legacy-util": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "~1.5.2", + "exit": "~0.1.1", + "getobject": "~0.1.0", + "hooker": "~0.2.3", + "lodash": "~4.3.0", + "underscore.string": "~3.2.3", + "which": "~1.2.1" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "bundled": true + } + } + }, + "grunt-newer": { + "version": "1.3.0", + "bundled": true, + "requires": { + "async": "^1.5.2", + "rimraf": "^2.5.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.2", + "bundled": true, + "requires": { + "glob": "^7.0.5" + } + } + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "bundled": true + }, + "hosted-git-info": { + "version": "2.5.0", + "bundled": true + }, + "http-errors": { + "version": "1.3.1", + "bundled": true, + "requires": { + "inherits": "~2.0.1", + "statuses": "1" + } + }, + "http-parser-js": { + "version": "0.4.9", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.19", + "bundled": true + }, + "indent-string": { + "version": "2.1.0", + "bundled": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-finite": { + "version": "1.0.2", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true + }, + "js-yaml": { + "version": "3.5.5", + "bundled": true, + "requires": { + "argparse": "^1.0.2", + "esprima": "^2.6.0" + } + }, + "livereload-js": { + "version": "2.2.2", + "bundled": true + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "bundled": true + }, + "loud-rejection": { + "version": "1.6.0", + "bundled": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "2.7.3", + "bundled": true + }, + "map-obj": { + "version": "1.0.1", + "bundled": true + }, + "media-typer": { + "version": "0.3.0", + "bundled": true + }, + "meow": { + "version": "3.7.0", + "bundled": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true + } + } + }, + "mime-db": { + "version": "1.30.0", + "bundled": true + }, + "mime-types": { + "version": "2.1.17", + "bundled": true, + "requires": { + "mime-db": "~1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "on-finished": { + "version": "2.3.0", + "bundled": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseurl": { + "version": "1.3.2", + "bundled": true + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "bundled": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "qs": { + "version": "5.1.0", + "bundled": true + }, + "raw-body": { + "version": "2.1.7", + "bundled": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.13", + "bundled": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "redent": { + "version": "1.0.0", + "bundled": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "repeating": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "resolve": { + "version": "1.1.7", + "bundled": true + }, + "rimraf": { + "version": "2.2.8", + "bundled": true + }, + "semver": { + "version": "5.4.1", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-license-ids": "^1.0.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true + }, + "sprintf-js": { + "version": "1.0.3", + "bundled": true + }, + "statuses": { + "version": "1.4.0", + "bundled": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "bundled": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "supports-color": { + "version": "2.0.0", + "bundled": true + }, + "tiny-lr": { + "version": "0.2.1", + "bundled": true, + "requires": { + "body-parser": "~1.14.0", + "debug": "~2.2.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.2.0", + "parseurl": "~1.3.0", + "qs": "~5.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "bundled": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "bundled": true + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "bundled": true + }, + "type-is": { + "version": "1.6.15", + "bundled": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.15" + } + }, + "underscore.string": { + "version": "3.2.3", + "bundled": true + }, + "unpipe": { + "version": "1.0.0", + "bundled": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + } + }, + "websocket-driver": { + "version": "0.7.0", + "bundled": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.2", + "bundled": true + }, + "which": { + "version": "1.2.14", + "bundled": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + } + } }, "snake-case": { "version": "2.1.0", diff --git a/package.json b/package.json index 0528a49ef..9436a7079 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "1.0.15", + "sn-stylekit": "file:~/Desktop/sn/dev/Stylekit", "standard-file-js": "0.3.19" } } From fb6b5fa983d74c5e489684388078082308043fa6 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 15 Nov 2018 14:41:04 -0600 Subject: [PATCH 06/62] Privs remember me for wip --- .../javascripts/app/controllers/footer.js | 3 +- .../directives/views/privilegesAuthModal.js | 12 +++ .../app/services/passcodeManager.js | 4 +- .../app/services/privilegesManager.js | 81 ++++++++++++++++++- .../privileges-auth-modal.html.haml | 6 ++ 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index 47ac00b76..5aeb5b176 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -182,11 +182,12 @@ angular.module('app') if(!room.showRoom) { // About to show, check if has privileges - if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageExtensions)) { privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageExtensions, () => { run(); }); + } else { + run(); } } else { run(); diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 99dad564d..072741c34 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -25,6 +25,17 @@ class PrivilegesAuthModal { 'ngInject'; $scope.authenticationParameters = {}; + $scope.sessionLengthOptions = privilegesManager.getSessionLengthOptions(); + + privilegesManager.getSelectedSessionLength().then((length) => { + $timeout(() => { + $scope.selectedSessionLength = length; + }) + }) + + $scope.selectSessionLength = function(length) { + $scope.selectedSessionLength = length; + } privilegesManager.getPrivileges().then((privileges) => { $timeout(() => { @@ -55,6 +66,7 @@ class PrivilegesAuthModal { privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => { $timeout(() => { if(result.success) { + privilegesManager.setSessionLength($scope.selectedSessionLength); $scope.onSuccess(); $scope.dismiss(); } else { diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 4abd4fba0..188a1aee7 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -89,11 +89,11 @@ class PasscodeManager { } async setAutoLockInterval(interval) { - return this.storageManager.setItem(PasscodeManager.AutoLockIntervalKey, JSON.stringify(interval), StorageManager.Fixed); + return this.storageManager.setItem(PasscodeManager.AutoLockIntervalKey, JSON.stringify(interval), StorageManager.FixedEncrypted); } async getAutoLockInterval() { - let interval = await this.storageManager.getItem(PasscodeManager.AutoLockIntervalKey, StorageManager.Fixed); + let interval = await this.storageManager.getItem(PasscodeManager.AutoLockIntervalKey, StorageManager.FixedEncrypted); if(interval) { return JSON.parse(interval); } else { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 178034d92..8b77653af 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -1,10 +1,11 @@ class PrivilegesManager { - constructor(passcodeManager, authManager, singletonManager, modelManager, $rootScope, $compile) { + constructor(passcodeManager, authManager, singletonManager, modelManager, storageManager, $rootScope, $compile) { this.passcodeManager = passcodeManager; this.authManager = authManager; this.singletonManager = singletonManager; this.modelManager = modelManager; + this.storageManager = storageManager; this.$rootScope = $rootScope; this.$compile = $compile; @@ -18,6 +19,14 @@ class PrivilegesManager { PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; + PrivilegesManager.SessionExpiresAtKey = "SessionExpiresAtKey"; + PrivilegesManager.SessionLengthKey = "SessionLengthKey"; + + PrivilegesManager.SessionLengthNone = 0; + PrivilegesManager.SessionLengthFiveMinutes = 5; + PrivilegesManager.SessionLengthOneHour = 3600; + PrivilegesManager.SessionLengthOneWeek = 604800; + this.availableActions = [ PrivilegesManager.ActionManageExtensions, PrivilegesManager.ActionDownloadBackup, @@ -29,6 +38,14 @@ class PrivilegesManager { PrivilegesManager.CredentialAccountPassword, PrivilegesManager.CredentialLocalPasscode ]; + + this.sessionLengths = [ + PrivilegesManager.SessionLengthNone, + PrivilegesManager.SessionLengthFiveMinutes, + PrivilegesManager.SessionLengthOneHour, + PrivilegesManager.SessionLengthOneWeek, + PrivilegesManager.SessionLengthIndefinite + ] } getAvailableActions() { @@ -122,7 +139,7 @@ class PrivilegesManager { metadata[PrivilegesManager.ActionManageExtensions] = { label: "Manage Extensions" - } + }; metadata[PrivilegesManager.ActionDownloadBackup] = { label: "Download Backups" @@ -134,12 +151,70 @@ class PrivilegesManager { metadata[PrivilegesManager.ActionManagePrivileges] = { label: "Manage Privileges" - } + }; return metadata[action]; } + getSessionLengthOptions() { + return [ + { + value: PrivilegesManager.SessionLengthNone, + label: "Don't Remember" + }, + { + value: PrivilegesManager.SessionLengthFiveMinutes, + label: "5 Min" + }, + { + value: PrivilegesManager.SessionLengthOneHour, + label: "1 Hr" + }, + { + value: PrivilegesManager.SessionLengthOneWeek, + label: "1 Week" + } + ] + } + + async setSessionLength(length) { + let addToNow = (seconds) => { + let date = new Date(); + date.setSeconds(date.getSeconds() + seconds); + return date; + } + + let expiresAt = addToNow(length); + + return Promise.all([ + this.storageManager.setItem(PrivilegesManager.SessionExpiresAtKey, JSON.stringify(expiresAt), StorageManager.FixedEncrypted), + this.storageManager.setItem(PrivilegesManager.SessionLengthKey, JSON.stringify(length), StorageManager.FixedEncrypted), + ]) + } + + async getSelectedSessionLength() { + let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, StorageManager.FixedEncrypted); + if(length) { + return JSON.parse(length); + } else { + return PrivilegesManager.SessionLengthNone; + } + } + + async getSessionExpirey() { + let expiresAt = await this.storageManager.getItem(PrivilegesManager.SessionExpiresAtKey, StorageManager.FixedEncrypted); + if(expiresAt) { + return new Date(JSON.parse(expiresAt)); + } else { + return new Date(); + } + } + async actionRequiresPrivilege(action) { + let expiresAt = await this.getSessionExpirey(); + if(expiresAt > new Date()) { + return false; + } return (await this.getPrivileges()).getCredentialsForAction(action).length > 0; } diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index 2603614a0..fd9074df3 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -12,6 +12,12 @@ %p {{promptForCredential(credential)}} %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. + .panel-row + .horizontal-group + %h4 Remember for + %a.info{"ng-repeat" => "option in sessionLengthOptions", "ng-click" => "selectSessionLength(option.value)", + "ng-class" => "{'info boxed' : option.value == selectedSessionLength}"} + {{option.label}} .footer .button.info.big.block.bold{"ng-click" => "submit()"} Submit From 16296e7f80ecf33c637eebca3378d1d998022c8a Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 19 Nov 2018 14:52:02 -0600 Subject: [PATCH 07/62] Privileges wip --- .../directives/views/privilegesAuthModal.js | 9 +++---- .../app/services/privilegesManager.js | 25 +++++++++++++++++-- .../privileges-auth-modal.html.haml | 15 +++++++---- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 072741c34..84452687a 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -21,7 +21,7 @@ class PrivilegesAuthModal { } } - controller($scope, privilegesManager, $timeout) { + controller($scope, privilegesManager, passcodeManager, authManager, $timeout) { 'ngInject'; $scope.authenticationParameters = {}; @@ -37,11 +37,10 @@ class PrivilegesAuthModal { $scope.selectedSessionLength = length; } - privilegesManager.getPrivileges().then((privileges) => { + privilegesManager.netCredentialsForAction($scope.action).then((credentials) => { $timeout(() => { - $scope.privileges = privileges; - $scope.requiredCredentials = privileges.getCredentialsForAction($scope.action); - }) + $scope.requiredCredentials = credentials; + }); }); $scope.promptForCredential = function(credential) { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 8b77653af..460b23fa3 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -78,6 +78,27 @@ class PrivilegesManager { this.currentAuthenticationElement = el; } + async netCredentialsForAction(action) { + let credentials = (await this.getPrivileges()).getCredentialsForAction(action); + let netCredentials = []; + + for(var cred of credentials) { + if(cred == PrivilegesManager.CredentialAccountPassword) { + if(!this.authManager.offline()) { + netCredentials.push(cred); + } else { + console.log("WE ARE OFFLINE"); + } + } else if(cred == PrivilegesManager.CredentialLocalPasscode) { + if(this.passcodeManager.hasPasscode()) { + netCredentials.push(cred); + } + } + } + + return netCredentials; + } + presentPrivilegesManagementModal() { var scope = this.$rootScope.$new(true); var el = this.$compile( "")(scope); @@ -215,7 +236,7 @@ class PrivilegesManager { if(expiresAt > new Date()) { return false; } - return (await this.getPrivileges()).getCredentialsForAction(action).length > 0; + return (await this.netCredentialsForAction(action)).length > 0; } async savePrivileges() { @@ -225,7 +246,7 @@ class PrivilegesManager { } async authenticateAction(action, credentialAuthMapping) { - var requiredCredentials = (await this.getPrivileges()).getCredentialsForAction(action); + var requiredCredentials = (await this.netCredentialsForAction(action)); var successfulCredentials = [], failedCredentials = []; for(let requiredCredential of requiredCredentials) { diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index fd9074df3..972a091f6 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -8,13 +8,18 @@ %a.close-button.info{"ng-click" => "cancel()"} Cancel .content .panel-section - .panel-row{"ng-repeat" => "credential in requiredCredentials"} - %p {{promptForCredential(credential)}} - %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} - %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. + %div{"ng-repeat" => "credential in requiredCredentials"} + %p + %strong {{promptForCredential(credential)}} + %div + %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} + %div + %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. + .panel-row .panel-row .horizontal-group - %h4 Remember for + %p + %strong Remember for %a.info{"ng-repeat" => "option in sessionLengthOptions", "ng-click" => "selectSessionLength(option.value)", "ng-class" => "{'info boxed' : option.value == selectedSessionLength}"} {{option.label}} From c5d50728c09a9c56444b5d6bfb16cfe4fa210c83 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 20 Nov 2018 13:13:58 -0600 Subject: [PATCH 08/62] Session clearing, more actions --- .../javascripts/app/controllers/editor.js | 31 +++++-- .../app/directives/views/accountMenu.js | 92 ++++++++++++++----- .../app/directives/views/menuRow.js | 1 + .../views/privilegesManagementModal.js | 19 +++- .../app/services/passcodeManager.js | 1 - .../app/services/privilegesManager.js | 26 ++++-- app/assets/stylesheets/app/_modals.scss | 4 + .../templates/directives/menu-row.html.haml | 5 +- .../privileges-management-modal.html.haml | 4 + app/assets/templates/editor.html.haml | 2 +- 10 files changed, 144 insertions(+), 41 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 1edba4c77..56e3d93aa 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -22,7 +22,8 @@ angular.module('app') } } }) - .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory) { + .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, + syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory, privilegesManager) { this.spellcheck = true; this.componentManager = componentManager; @@ -382,16 +383,28 @@ angular.module('app') } } - this.deleteNote = function() { - if(this.note.locked) { - alert("This note is locked. If you'd like to delete it, unlock it, and try again."); - return; + this.deleteNote = async function() { + let run = () => { + $timeout(() => { + if(this.note.locked) { + alert("This note is locked. If you'd like to delete it, unlock it, and try again."); + return; + } + + let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note"; + if(confirm(`Are you sure you want to delete ${title}?`)) { + this.remove()(this.note); + this.showMenu = false; + } + }); } - let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note"; - if(confirm(`Are you sure you want to delete ${title}?`)) { - this.remove()(this.note); - this.showMenu = false; + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDeleteNote)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDeleteNote, () => { + run(); + }); + } else { + run(); } } diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index d7a9c3414..f4df268a3 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -169,8 +169,20 @@ class AccountMenu { authManager.presentPasswordWizard(type); } - $scope.openPrivilegesModal = function() { - privilegesManager.presentPrivilegesManagementModal(); + $scope.openPrivilegesModal = async function() { + let run = () => { + $timeout(() => { + privilegesManager.presentPrivilegesManagementModal(); + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePrivileges)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePrivileges, () => { + run(); + }); + } else { + run(); + } } // Allows indexeddb unencrypted logs to be deleted @@ -387,8 +399,20 @@ class AccountMenu { $scope.reloadAutoLockInterval(); $scope.selectAutoLockInterval = async function(interval) { - await passcodeManager.setAutoLockInterval(interval); - $scope.reloadAutoLockInterval(); + let run = async () => { + await passcodeManager.setAutoLockInterval(interval); + $timeout(() => { + $scope.reloadAutoLockInterval(); + }); + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); + } } $scope.hasPasscode = function() { @@ -422,27 +446,51 @@ class AccountMenu { }) } - $scope.changePasscodePressed = function() { - $scope.formData.changingPasscode = true; - $scope.addPasscodeClicked(); - $scope.formData.changingPasscode = false; + $scope.changePasscodePressed = async function() { + let run = () => { + $timeout(() => { + $scope.formData.changingPasscode = true; + $scope.addPasscodeClicked(); + $scope.formData.changingPasscode = false; + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); + } } - $scope.removePasscodePressed = function() { - var signedIn = !authManager.offline(); - var message = "Are you sure you want to remove your local passcode?"; - if(!signedIn) { - message += " This will remove encryption from your local data."; - } - if(confirm(message)) { - passcodeManager.clearPasscode(); + $scope.removePasscodePressed = async function() { + let run = () => { + $timeout(() => { + var signedIn = !authManager.offline(); + var message = "Are you sure you want to remove your local passcode?"; + if(!signedIn) { + message += " This will remove encryption from your local data."; + } + if(confirm(message)) { + passcodeManager.clearPasscode(); - if(authManager.offline()) { - syncManager.markAllItemsDirtyAndSaveOffline(); - // Don't create backup here, as if the user is temporarily removing the passcode to change it, - // we don't want to write unencrypted data to disk. - // $rootScope.$broadcast("major-data-change"); - } + if(authManager.offline()) { + syncManager.markAllItemsDirtyAndSaveOffline(); + // Don't create backup here, as if the user is temporarily removing the passcode to change it, + // we don't want to write unencrypted data to disk. + // $rootScope.$broadcast("major-data-change"); + } + } + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); } } diff --git a/app/assets/javascripts/app/directives/views/menuRow.js b/app/assets/javascripts/app/directives/views/menuRow.js index 999e64f9f..49fbb5e0a 100644 --- a/app/assets/javascripts/app/directives/views/menuRow.js +++ b/app/assets/javascripts/app/directives/views/menuRow.js @@ -7,6 +7,7 @@ class MenuRow { this.scope = { action: "&", circle: "=", + circleAlign: "=", label: "=", subtitle: "=", hasButton: "=", diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js index b792d3858..d646cb48c 100644 --- a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -28,13 +28,30 @@ class PrivilegesManagementModal { } $scope.isCredentialRequiredForAction = function(action, credential) { + if(!$scope.privileges) { + return false; + } return $scope.privileges.isCredentialRequiredForAction(action, credential); } + $scope.clearSession = function() { + privilegesManager.clearSession().then(() => { + $scope.reloadPrivileges(); + }) + } + $scope.reloadPrivileges = async function() { - $scope.privileges = await privilegesManager.getPrivileges(); $scope.availableActions = privilegesManager.getAvailableActions(); $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + let sessionEndDate = await privilegesManager.getSessionExpirey(); + $scope.sessionExpirey = sessionEndDate.toLocaleString(); + $scope.sessionExpired = new Date() >= sessionEndDate; + + privilegesManager.getPrivileges().then((privs) => { + $timeout(() => { + $scope.privileges = privs; + }) + }) } $scope.checkboxValueChanged = function(action, credential) { diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 188a1aee7..1aa1f7c5e 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -2,7 +2,6 @@ class PasscodeManager { constructor(authManager, storageManager) { document.addEventListener('visibilitychange', (e) => { - console.log("visibilitychange", e, document.visibilityState); this.documentVisibilityChanged(document.visibilityState); }); diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 460b23fa3..daed765ab 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -18,12 +18,14 @@ class PrivilegesManager { PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; + PrivilegesManager.ActionManagePasscode = "ActionManagePasscode"; + PrivilegesManager.ActionDeleteNote = "ActionDeleteNote"; PrivilegesManager.SessionExpiresAtKey = "SessionExpiresAtKey"; PrivilegesManager.SessionLengthKey = "SessionLengthKey"; PrivilegesManager.SessionLengthNone = 0; - PrivilegesManager.SessionLengthFiveMinutes = 5; + PrivilegesManager.SessionLengthFiveMinutes = 300; PrivilegesManager.SessionLengthOneHour = 3600; PrivilegesManager.SessionLengthOneWeek = 604800; @@ -31,7 +33,9 @@ class PrivilegesManager { PrivilegesManager.ActionManageExtensions, PrivilegesManager.ActionDownloadBackup, PrivilegesManager.ActionViewLockedNotes, - PrivilegesManager.ActionManagePrivileges + PrivilegesManager.ActionManagePrivileges, + PrivilegesManager.ActionManagePasscode, + PrivilegesManager.ActionDeleteNote ] this.availableCredentials = [ @@ -86,8 +90,6 @@ class PrivilegesManager { if(cred == PrivilegesManager.CredentialAccountPassword) { if(!this.authManager.offline()) { netCredentials.push(cred); - } else { - console.log("WE ARE OFFLINE"); } } else if(cred == PrivilegesManager.CredentialLocalPasscode) { if(this.passcodeManager.hasPasscode()) { @@ -174,6 +176,14 @@ class PrivilegesManager { label: "Manage Privileges" }; + metadata[PrivilegesManager.ActionManagePasscode] = { + label: "Manage Passcode" + } + + metadata[PrivilegesManager.ActionDeleteNote] = { + label: "Delete Note" + } + return metadata[action]; } @@ -185,11 +195,11 @@ class PrivilegesManager { }, { value: PrivilegesManager.SessionLengthFiveMinutes, - label: "5 Min" + label: "5 Minutes" }, { value: PrivilegesManager.SessionLengthOneHour, - label: "1 Hr" + label: "1 Hour" }, { value: PrivilegesManager.SessionLengthOneWeek, @@ -213,6 +223,10 @@ class PrivilegesManager { ]) } + async clearSession() { + return this.setSessionLength(PrivilegesManager.SessionLengthNone); + } + async getSelectedSessionLength() { let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, StorageManager.FixedEncrypted); if(length) { diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 6d6278cbd..074bb4db9 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -14,6 +14,10 @@ #privileges-modal { width: 700px; + + th { + text-align: left; + } } #password-wizard { diff --git a/app/assets/templates/directives/menu-row.html.haml b/app/assets/templates/directives/menu-row.html.haml index 0cb3cf604..9cdaff83e 100644 --- a/app/assets/templates/directives/menu-row.html.haml +++ b/app/assets/templates/directives/menu-row.html.haml @@ -1,7 +1,7 @@ .row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} .column .left - .column{"ng-if" => "circle"} + .column{"ng-if" => "circle && (!circleAlign || circleAlign == 'left')"} .circle.small{"ng-class" => "circle"} .column{"ng-class" => "{'faded' : faded || disabled}"} .label @@ -13,6 +13,9 @@ %menu-row{"ng-repeat" => "row in subRows", "action" => "row.onClick()", "label" => "row.label", "subtitle" => "row.subtitle", "spinner-class" => "row.spinnerClass"} + .column{"ng-if" => "circle && circleAlign == 'right'"} + .circle.small{"ng-class" => "circle"} + .column{"ng-if" => "hasButton"} .button.info{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} {{buttonText}} diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 52898a899..1a7ce94d1 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -20,6 +20,10 @@ %p {{displayInfoForAction(action)}} %th{"ng-repeat" => "credential in availableCredentials"} %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} + + .panel-section{"ng-if" => "sessionExpirey && !sessionExpired"} + %p You will not be asked to authenticate until {{sessionExpirey}}. + %a{"ng-click" => "clearSession()"} Clear Session .footer %h2 About Privileges .panel-section.no-bottom-pad diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index d78f5eca9..332fe91f8 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -34,7 +34,7 @@ %menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"} %menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"} %menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"} - %menu-row{"label" => "ctrl.note.content.hidePreview ? 'Unhide Preview' : 'Hide Preview'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} + %menu-row{"label" => "'Preview'", "circle" => "ctrl.note.content.hidePreview ? 'danger' : 'success'", "circle-align" => "'right'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} %menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"} .section From 90793938f76291e7a791221f517ee877151d27bc Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 21 Nov 2018 14:27:04 -0600 Subject: [PATCH 09/62] Privs progress --- .../app/directives/views/accountMenu.js | 63 +++++++++++-------- .../directives/views/privilegesAuthModal.js | 2 +- .../views/privilegesManagementModal.js | 19 +++++- .../app/services/passcodeManager.js | 5 -- .../app/services/privilegesManager.js | 12 ++-- app/assets/stylesheets/app/_modals.scss | 1 + .../directives/account-menu.html.haml | 1 - .../privileges-auth-modal.html.haml | 4 +- .../privileges-management-modal.html.haml | 3 +- 9 files changed, 67 insertions(+), 43 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index f4df268a3..d984c28f8 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -243,36 +243,49 @@ class AccountMenu { }) } - $scope.importFileSelected = function(files) { - $scope.importData = {}; + $scope.importFileSelected = async function(files) { - var file = files[0]; - var reader = new FileReader(); - reader.onload = function(e) { - try { - var data = JSON.parse(e.target.result); - $timeout(function(){ - if(data.auth_params) { - // request password - $scope.importData.requestPassword = true; - $scope.importData.data = data; + let run = () => { + $timeout(() => { + $scope.importData = {}; - $timeout(() => { - var element = document.getElementById("import-password-request"); - if(element) { - element.scrollIntoView(false); + var file = files[0]; + var reader = new FileReader(); + reader.onload = function(e) { + try { + var data = JSON.parse(e.target.result); + $timeout(function(){ + if(data.auth_params) { + // request password + $scope.importData.requestPassword = true; + $scope.importData.data = data; + + $timeout(() => { + var element = document.getElementById("import-password-request"); + if(element) { + element.scrollIntoView(false); + } + }) + } else { + $scope.performImport(data, null); } }) - } else { - $scope.performImport(data, null); + } catch (e) { + alert("Unable to open file. Ensure it is a proper JSON file and try again."); } - }) - } catch (e) { - alert("Unable to open file. Ensure it is a proper JSON file and try again."); - } + } + + reader.readAsText(file); + }) } - reader.readAsText(file); + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { + run(); + }); + } else { + run(); + } } $scope.importJSONData = function(data, password, callback) { @@ -335,8 +348,8 @@ class AccountMenu { archiveManager.downloadBackup($scope.archiveFormData.encrypted); } - if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDownloadBackup)) { - privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDownloadBackup, () => { + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { run(); }); } else { diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 84452687a..91816b1b8 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -39,7 +39,7 @@ class PrivilegesAuthModal { privilegesManager.netCredentialsForAction($scope.action).then((credentials) => { $timeout(() => { - $scope.requiredCredentials = credentials; + $scope.requiredCredentials = credentials.sort(); }); }); diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js index d646cb48c..c9642b357 100644 --- a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -14,13 +14,22 @@ class PrivilegesManagementModal { } } - controller($scope, privilegesManager, $timeout) { + controller($scope, privilegesManager, passcodeManager, $timeout) { 'ngInject'; $scope.dummy = {}; + $scope.hasPasscode = passcodeManager.hasPasscode(); + $scope.displayInfoForCredential = function(credential) { - return privilegesManager.displayInfoForCredential(credential).label; + let info = privilegesManager.displayInfoForCredential(credential); + if(credential == PrivilegesManager.CredentialLocalPasscode) { + info["availability"] = $scope.hasPasscode; + } else { + info["availability"] = true; + } + + return info; } $scope.displayInfoForAction = function(action) { @@ -47,6 +56,11 @@ class PrivilegesManagementModal { $scope.sessionExpirey = sessionEndDate.toLocaleString(); $scope.sessionExpired = new Date() >= sessionEndDate; + $scope.credentialDisplayInfo = {}; + for(let cred of $scope.availableCredentials) { + $scope.credentialDisplayInfo[cred] = $scope.displayInfoForCredential(cred); + } + privilegesManager.getPrivileges().then((privs) => { $timeout(() => { $scope.privileges = privs; @@ -55,6 +69,7 @@ class PrivilegesManagementModal { } $scope.checkboxValueChanged = function(action, credential) { + console.log("toggleCredentialForAction", action, credential); $scope.privileges.toggleCredentialForAction(action, credential); privilegesManager.savePrivileges(); } diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 1aa1f7c5e..d203f5aba 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -13,7 +13,6 @@ class PasscodeManager { const MillisecondsPerSecond = 1000; PasscodeManager.AutoLockIntervalNone = 0; - PasscodeManager.AutoLockIntervalFiveSecs = 5 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; @@ -27,10 +26,6 @@ class PasscodeManager { value: PasscodeManager.AutoLockIntervalNone, label: "None" }, - { - value: PasscodeManager.AutoLockIntervalFiveSecs, - label: "5 Secs" - }, { value: PasscodeManager.AutoLockIntervalOneMinute, label: "1 Min" diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index daed765ab..a2869ead4 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -15,7 +15,7 @@ class PrivilegesManager { PrivilegesManager.CredentialLocalPasscode = "CredentialLocalPasscode"; PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; - PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; + PrivilegesManager.ActionManageBackups = "ActionManageBackups"; PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; PrivilegesManager.ActionManagePasscode = "ActionManagePasscode"; @@ -31,10 +31,10 @@ class PrivilegesManager { this.availableActions = [ PrivilegesManager.ActionManageExtensions, - PrivilegesManager.ActionDownloadBackup, - PrivilegesManager.ActionViewLockedNotes, + PrivilegesManager.ActionManageBackups, PrivilegesManager.ActionManagePrivileges, PrivilegesManager.ActionManagePasscode, + PrivilegesManager.ActionViewLockedNotes, PrivilegesManager.ActionDeleteNote ] @@ -164,8 +164,8 @@ class PrivilegesManager { label: "Manage Extensions" }; - metadata[PrivilegesManager.ActionDownloadBackup] = { - label: "Download Backups" + metadata[PrivilegesManager.ActionManageBackups] = { + label: "Download/Import Backups" }; metadata[PrivilegesManager.ActionViewLockedNotes] = { @@ -181,7 +181,7 @@ class PrivilegesManager { } metadata[PrivilegesManager.ActionDeleteNote] = { - label: "Delete Note" + label: "Delete Notes" } return metadata[action]; diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 074bb4db9..e777e752f 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -17,6 +17,7 @@ th { text-align: left; + font-weight: normal; } } diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index ae99c67b7..81ef1ce88 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -133,7 +133,6 @@ .panel-row .horizontal-group %h4 Autolock - .vertical-rule %a.info{"ng-repeat" => "option in passcodeAutoLockOptions", "ng-click" => "selectAutoLockInterval(option.value)", "ng-class" => "{'info boxed' : option.value == selectedAutoLockInterval}"} {{option.label}} diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index 972a091f6..3be9f08d5 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -7,12 +7,12 @@ %h1.title Authentication Required %a.close-button.info{"ng-click" => "cancel()"} Cancel .content - .panel-section + %form.panel-section{"ng-submit" => "submit()"} %div{"ng-repeat" => "credential in requiredCredentials"} %p %strong {{promptForCredential(credential)}} %div - %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} + %input{"type" => "password", "ng-model" => "authenticationParameters[credential]", "sn-autofocus" => "true", "should-focus" => "$index == 0"} %div %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. .panel-row diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 1a7ce94d1..ee9dac0ae 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -13,7 +13,8 @@ %tr %th %th{"ng-repeat" => "cred in availableCredentials"} - {{displayInfoForCredential(cred)}} + %strong {{credentialDisplayInfo[cred].label}} + %p.font-small{"style" => "margin-top: 2px", "ng-show" => "!credentialDisplayInfo[cred].availability"} Not Configured %tbody %tr{"ng-repeat" => "action in availableActions"} %td From 0cab8c29551bee5f8469937e474bd084973c5b0c Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 25 Nov 2018 18:35:51 -0600 Subject: [PATCH 10/62] Wip --- app/assets/javascripts/app/controllers/home.js | 12 ++++++------ .../app/directives/functional/snEnter.js | 15 +++++++++++++++ .../app/directives/views/accountMenu.js | 2 ++ .../app/directives/views/privilegesAuthModal.js | 16 ++++++++++++++++ .../javascripts/app/services/authManager.js | 1 + .../app/services/privilegesManager.js | 2 ++ .../javascripts/app/services/singletonManager.js | 1 - .../directives/privileges-auth-modal.html.haml | 5 +++-- .../privileges-management-modal.html.haml | 2 +- 9 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 app/assets/javascripts/app/directives/functional/snEnter.js diff --git a/app/assets/javascripts/app/controllers/home.js b/app/assets/javascripts/app/controllers/home.js index c83a1c0a4..72e095a93 100644 --- a/app/assets/javascripts/app/controllers/home.js +++ b/app/assets/javascripts/app/controllers/home.js @@ -84,14 +84,14 @@ angular.module('app') syncManager.loadLocalItems().then(() => { $timeout(() => { $scope.allTag.didLoad = true; - $rootScope.$broadcast("initial-data-loaded"); + $rootScope.$broadcast("initial-data-loaded"); // This needs to be processed first before sync is called so that singletonManager observers function properly. + syncManager.sync(); + // refresh every 30s + setInterval(function () { + syncManager.sync(); + }, 30000); }) - syncManager.sync(); - // refresh every 30s - setInterval(function () { - syncManager.sync(); - }, 30000); }); authManager.addEventHandler((event) => { diff --git a/app/assets/javascripts/app/directives/functional/snEnter.js b/app/assets/javascripts/app/directives/functional/snEnter.js new file mode 100644 index 000000000..fe12e0983 --- /dev/null +++ b/app/assets/javascripts/app/directives/functional/snEnter.js @@ -0,0 +1,15 @@ +angular +.module('app') +.directive('snEnter', function() { + return function(scope, element, attrs) { + element.bind("keydown keypress", function(event) { + if(event.which === 13) { + scope.$apply(function(){ + scope.$eval(attrs.snEnter, {'event': event}); + }); + + event.preventDefault(); + } + }); + }; +}); diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index d984c28f8..ae33c16c2 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -170,6 +170,8 @@ class AccountMenu { } $scope.openPrivilegesModal = async function() { + $scope.close(); + let run = () => { $timeout(() => { privilegesManager.presentPrivilegesManagementModal(); diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 91816b1b8..c677da92b 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -61,7 +61,23 @@ class PrivilegesAuthModal { }) != null; } + $scope.validate = function() { + var failed = []; + for(var cred of $scope.requiredCredentials) { + var value = $scope.authenticationParameters[cred]; + if(!value || value.length == 0) { + failed.push(cred); + } + } + + $scope.failedCredentials = failed; + return failed.length == 0; + } + $scope.submit = function() { + if(!$scope.validate()) { + return; + } privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => { $timeout(() => { if(result.success) { diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 47e169a68..3e4381e1f 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -135,6 +135,7 @@ class AuthManager extends SFAuthManager { let contentTypePredicate = new SFPredicate("content_type", "=", prefsContentType); this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { + // console.log("Loaded existing user prefs", resolvedSingleton.uuid); this.userPreferences = resolvedSingleton; this.userPreferencesDidChange(); }, (valueCallback) => { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index a2869ead4..5e695a030 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -120,6 +120,7 @@ class PrivilegesManager { if(!this.privileges.content.desktopPrivileges) { this.privileges.content.desktopPrivileges = {}; } + console.log("Resolved existing privs", resolvedSingleton.uuid); resolve(resolvedSingleton); }, (valueCallback) => { // Safe to create. Create and return object. @@ -128,6 +129,7 @@ class PrivilegesManager { privs.setDirty(true); this.$rootScope.sync(); valueCallback(privs); + console.log("Creating new privs", privs.uuid); resolve(privs); }); }); diff --git a/app/assets/javascripts/app/services/singletonManager.js b/app/assets/javascripts/app/services/singletonManager.js index dd1624072..c7ca742cc 100644 --- a/app/assets/javascripts/app/services/singletonManager.js +++ b/app/assets/javascripts/app/services/singletonManager.js @@ -104,7 +104,6 @@ class SingletonManager { var singleton = allExtantItemsMatchingPredicate[0]; singletonHandler.singleton = singleton; singletonHandler.resolutionCallback(singleton); - } } } else { diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index 3be9f08d5..5e649f502 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -7,12 +7,13 @@ %h1.title Authentication Required %a.close-button.info{"ng-click" => "cancel()"} Cancel .content - %form.panel-section{"ng-submit" => "submit()"} + .panel-section %div{"ng-repeat" => "credential in requiredCredentials"} %p %strong {{promptForCredential(credential)}} %div - %input{"type" => "password", "ng-model" => "authenticationParameters[credential]", "sn-autofocus" => "true", "should-focus" => "$index == 0"} + %input{"type" => "password", "ng-model" => "authenticationParameters[credential]", + "sn-autofocus" => "true", "should-focus" => "$index == 0", "sn-enter" => "submit()"} %div %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. .panel-row diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index ee9dac0ae..a8ebc25b0 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -20,7 +20,7 @@ %td %p {{displayInfoForAction(action)}} %th{"ng-repeat" => "credential in availableCredentials"} - %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} + %input{"type" => "checkbox", "ng-disabled" => "!credentialDisplayInfo[credential].availability", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} .panel-section{"ng-if" => "sessionExpirey && !sessionExpired"} %p You will not be asked to authenticate until {{sessionExpirey}}. From 0c41815601459e4270b8dd96402a8b2a75c14af2 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 27 Nov 2018 12:25:11 -0600 Subject: [PATCH 11/62] Updates --- .../app/directives/views/privilegesManagementModal.js | 6 ++++-- app/assets/javascripts/app/services/privilegesManager.js | 6 +++++- app/assets/templates/directives/account-menu.html.haml | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js index c9642b357..bec8691d4 100644 --- a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -14,17 +14,20 @@ class PrivilegesManagementModal { } } - controller($scope, privilegesManager, passcodeManager, $timeout) { + controller($scope, privilegesManager, passcodeManager, authManager, $timeout) { 'ngInject'; $scope.dummy = {}; $scope.hasPasscode = passcodeManager.hasPasscode(); + $scope.hasAccount = !authManager.offline(); $scope.displayInfoForCredential = function(credential) { let info = privilegesManager.displayInfoForCredential(credential); if(credential == PrivilegesManager.CredentialLocalPasscode) { info["availability"] = $scope.hasPasscode; + } else if(credential == PrivilegesManager.CredentialAccountPassword) { + info["availability"] = $scope.hasAccount; } else { info["availability"] = true; } @@ -69,7 +72,6 @@ class PrivilegesManagementModal { } $scope.checkboxValueChanged = function(action, credential) { - console.log("toggleCredentialForAction", action, credential); $scope.privileges.toggleCredentialForAction(action, credential); privilegesManager.savePrivileges(); } diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 5e695a030..817b48219 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -30,9 +30,9 @@ class PrivilegesManager { PrivilegesManager.SessionLengthOneWeek = 604800; this.availableActions = [ + PrivilegesManager.ActionManagePrivileges, PrivilegesManager.ActionManageExtensions, PrivilegesManager.ActionManageBackups, - PrivilegesManager.ActionManagePrivileges, PrivilegesManager.ActionManagePasscode, PrivilegesManager.ActionViewLockedNotes, PrivilegesManager.ActionDeleteNote @@ -61,6 +61,10 @@ class PrivilegesManager { } presentPrivilegesModal(action, onSuccess, onCancel) { + if(this.authenticationInProgress()) { + onCancel && onCancel(); + return; + } let customSuccess = () => { onSuccess && onSuccess(); diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 81ef1ce88..5eb144c6d 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -87,7 +87,7 @@ %a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password - %a.panel-row.condensed{"ng-click" => "openPrivilegesModal('')"} + %a.panel-row.condensed{"ng-show" => "user", "ng-click" => "openPrivilegesModal('')"} Manage Privileges %a.panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} .inline.circle.small.success.mr-8 @@ -114,6 +114,7 @@ %p Adding a passcode is not supported in temporary sessions. Please sign out, then sign back in with the "Stay signed in" option checked. %form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} + .panel-row %input.form-control{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} %input.form-control{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} .button-group.stretch.panel-row.form-submit @@ -138,6 +139,8 @@ {{option.label}} %p The autolock timer begins when the window or tab loses focus. + %a.panel-row.condensed{"ng-show" => "!user", "ng-click" => "openPrivilegesModal('')"} + Manage Privileges .panel-section{"ng-if" => "!importData.loading"} %h3.title Data Backups From 140b59e79de6f0e6f91b34eb74f7d96b1ccafa98 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 27 Nov 2018 12:30:37 -0600 Subject: [PATCH 12/62] 2.4.0-beta1 --- package-lock.json | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ffdf0d56e..f38c4d64f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.17", + "version": "2.4.0-beta1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -7728,7 +7728,7 @@ "dev": true }, "sn-stylekit": { - "version": "file:../Stylekit", + "version": "1.1.6", "dev": true, "dependencies": { "abbrev": { diff --git a/package.json b/package.json index c04e3d2d4..d80b04969 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.18", + "version": "2.4.0-beta1", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -44,7 +44,7 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "file:~/Desktop/sn/dev/Stylekit", + "sn-stylekit": "1.1.6", "standard-file-js": "0.3.19" } } From 285bb76c7a488b00e8e4a529b857b589fe0a9cc6 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 7 Dec 2018 14:26:38 -0600 Subject: [PATCH 13/62] StyleKit classes wip --- app/assets/stylesheets/app/_footer.scss | 8 +- app/assets/stylesheets/app/_lock-screen.scss | 4 +- app/assets/stylesheets/app/_menus.scss | 6 +- app/assets/stylesheets/app/_modals.scss | 14 +- app/assets/stylesheets/app/_stylekit-sub.scss | 20 +- .../directives/account-menu.html.haml | 188 +- .../directives/actions-menu.html.haml | 12 +- .../directives/component-modal.html.haml | 8 +- .../directives/component-view.html.haml | 86 +- .../conflict-resolution-modal.html.haml | 26 +- .../directives/editor-menu.html.haml | 26 +- .../directives/input-modal.html.haml | 24 +- .../templates/directives/menu-row.html.haml | 26 +- .../directives/password-wizard.html.haml | 97 +- .../directives/permissions-modal.html.haml | 23 +- .../revision-preview-modal.html.haml | 20 +- .../directives/session-history-menu.html.haml | 18 +- app/assets/templates/editor.html.haml | 38 +- app/assets/templates/footer.html.haml | 52 +- app/assets/templates/lock-screen.html.haml | 26 +- app/assets/templates/notes.html.haml | 32 +- package-lock.json | 3910 ++++++++++------- package.json | 2 +- public/extensions/batch-manager | 2 +- 24 files changed, 2763 insertions(+), 1905 deletions(-) diff --git a/app/assets/stylesheets/app/_footer.scss b/app/assets/stylesheets/app/_footer.scss index d2d1519ce..f03c27adb 100644 --- a/app/assets/stylesheets/app/_footer.scss +++ b/app/assets/stylesheets/app/_footer.scss @@ -6,12 +6,12 @@ z-index: $z-index-footer-bar; } -#footer-bar .item { +#footer-bar .sk-app-bar-item { z-index: $z-index-footer-bar-item; position: relative; user-select: none; - .panel { + .sk-panel { max-height: 85vh; position: absolute; right: 0px; @@ -20,16 +20,14 @@ min-width: 300px; z-index: $z-index-footer-bar-item-panel; margin-top: 15px; - background-color: white; } - } #account-panel { width: 400px; } -.panel { +.sk-panel { cursor: default; } diff --git a/app/assets/stylesheets/app/_lock-screen.scss b/app/assets/stylesheets/app/_lock-screen.scss index 7dad8285a..605ded806 100644 --- a/app/assets/stylesheets/app/_lock-screen.scss +++ b/app/assets/stylesheets/app/_lock-screen.scss @@ -26,11 +26,11 @@ height: 100%; } - .panel { + .sk-panel { width: 315px; flex-grow: 0; - .header { + .sk-panel-header { justify-content: center; } } diff --git a/app/assets/stylesheets/app/_menus.scss b/app/assets/stylesheets/app/_menus.scss index 77de3a5ff..e8f62bc0c 100644 --- a/app/assets/stylesheets/app/_menus.scss +++ b/app/assets/stylesheets/app/_menus.scss @@ -1,5 +1,5 @@ -.app-bar { - .item { +.sk-app-bar { + .sk-app-bar-item { position: relative; } } @@ -15,6 +15,4 @@ margin-top: 5px; width: 280px; max-height: calc(85vh - 90px); - background-color: white; - color: $selected-text-color; } diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index ca1dac561..411bf237c 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -1,13 +1,13 @@ #permissions-modal { width: 350px; - .panel { + .sk-panel { border-radius: 0; background-color: white; } - .content { + .sk-panel-content { padding-top: 1.1rem; } - .footer { + .sk-panel-footer { padding-bottom: 1.4rem; } } @@ -43,9 +43,9 @@ } } -.panel { - background-color: white; -} +// .sk-panel { +// background-color: white; +// } .header .subtitle { font-size: 1.1rem; @@ -70,7 +70,7 @@ .sn-component { height: 100%; - .panel { + .sk-panel { height: 100%; } } diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index b0a9285e1..307b2beaa 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -1,6 +1,6 @@ .sn-component { - .notification { + .sk-notification { &.unpadded { padding: 0; padding-bottom: 0 !important; @@ -18,7 +18,7 @@ } - .app-bar { + .sk-app-bar { &.no-top-edge { border-top: 0; } @@ -26,10 +26,8 @@ } -.panel { - color: black; - - .header { +.sk-panel { + .sk-panel-header { .close-button { &:hover { text-decoration: none; @@ -42,20 +40,16 @@ } - .button-group.stretch { - .button:not(.featured) { + .sk-button-group.stretch { + .sk-button:not(.featured) { // Default buttons that are not featured and stretched should have larger vertical padding padding: 9px; } } - - a { - color: $blue-color; - } } #session-history-menu { - .menu-panel .row .sublabel.opaque { + .sk-menu-panel .sk-menu-panel-row .sk-sublabel.opaque { opacity: 1.0 } } diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index f0fb6736c..ae61a0577 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -1,52 +1,51 @@ .sn-component - .panel#account-panel - .header - %h1.title Account - %a.close-button{"ng-click" => "close()"} Close - .content - - .panel-section.hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} - %h1.title Sign in or register to enable sync and end-to-end encryption. - .panel-row - .panel-row - .button-group.stretch - .button.info.featured{"ng-click" => "formData.showLogin = true"} - .label Sign In - .button.info.featured{"ng-click" => "formData.showRegister = true"} - .label Register + .sk-panel#account-panel + .sk-panel-header + .sk-panel-header-title Account + %a.sk-a.infoclose-button{"ng-click" => "close()"} Close + .sk-panel-content + .sk-panel-section.hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} + .sk-panel-section-title Sign in or register to enable sync and end-to-end encryption. + .sk-panel-row + .sk-panel-row + .sk-button-group.stretch + .sk-button.info.featured{"ng-click" => "formData.showLogin = true"} + .sk-label Sign In + .sk-button.info.featured{"ng-click" => "formData.showRegister = true"} + .sk-label Register %p Standard Notes is free on every platform, and comes standard with sync and encryption. - .panel-section{"ng-if" => "formData.showLogin || formData.showRegister"} - %h3.title.panel-row + .sk-panel-section{"ng-if" => "formData.showLogin || formData.showRegister"} + .sk-panel-section-title {{formData.showLogin ? "Sign In" : "Register"}} - %form.panel-form{"ng-submit" => "submitAuthForm()"} + %form.sk-panel-form{"ng-submit" => "submitAuthForm()"} %input{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} %input{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} %input{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf'} - %a.panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} + %a.sk-panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} Advanced Options - .notification.info{"ng-if" => "formData.showRegister"} - %h2.title No Password Reset. - .text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. + .sk-notification.info{"ng-if" => "formData.showRegister"} + .sk-notification-title No Password Reset. + .sk-notification-text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. - .notification.unpadded.default.advanced-options.panel-row{"ng-if" => "formData.showAdvanced"} - .panel-column.stretch - %h4.title.panel-row.padded-row Advanced Options + .sk-notification.unpadded.default.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} + .sk-panel-column.stretch + .sk-notification-title.sk-panel-row.padded-row Advanced Options %div.bordered-row.padded-row - %label Sync Server Domain - %input.form-control.mt-5{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} - %label.padded-row{"ng-if" => "formData.showLogin"} - %input{"type" => "checkbox", "ng-model" => "formData.strictSignin"} + %label.sk-label Sync Server Domain + %input.sk-input.mt-5.sk-input{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} + %label.sk-label.padded-row{"ng-if" => "formData.showLogin"} + %input.sk-input{"type" => "checkbox", "ng-model" => "formData.strictSignin"} Use strict sign in %span %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} (Learn more) - .button-group.stretch.panel-row.form-submit - %button.button.info.featured{"type" => "submit", "ng-disabled" => "formData.authenticating"} - .label {{formData.showLogin ? "Sign In" : "Register"}} + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info.featured{"type" => "submit", "ng-disabled" => "formData.authenticating"} + .sk-label {{formData.showLogin ? "Sign In" : "Register"}} %label %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} @@ -58,82 +57,85 @@ %em.block.center-align.mt-10{"ng-if" => "formData.status", "style" => "font-size: 14px;"} {{formData.status}} - .panel-section{"ng-if" => "formData.mfa"} + .sk-panel-section{"ng-if" => "formData.mfa"} %form{"ng-submit" => "submitMfaForm()"} %p {{formData.mfa.message}} - %input.form-control.mt-10{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} - .button-group.stretch.panel-row.form-submit + %input.sk-input.mt-10{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} + .sk-button-group.stretch.sk-panel-row.form-submit %button.button.info.featured{"type" => "submit"} - .label Sign In + .sk-label Sign In %div{"ng-if" => "!formData.showLogin && !formData.showRegister && !formData.mfa"} - .panel-section{"ng-if" => "user"} - .notification.danger{"ng-if" => "syncStatus.error"} - %h2.title Sync Unreachable - .text Hmm...we can't seem to sync your account. The reason: {{syncStatus.error.message}} + .sk-panel-section{"ng-if" => "user"} + .sk-notification.danger{"ng-if" => "syncStatus.error"} + .sk-notification-title Sync Unreachable + .sk-notification-text Hmm...we can't seem to sync your account. The reason: {{syncStatus.error.message}} %p %a{"href" => "https://standardnotes.org/help", "target" => "_blank"} Need help? - .panel-row - %h2.title.wrap {{user.email}} - .horizontal-group{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} - .spinner.small.info - .sublabel + + .sk-panel-row + .sk-panel-column + .sk-h1.sk-bold.wrap {{user.email}} + .sk-subtitle.subtle.normal {{server}} + .sk-horizontal-group{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} + .sk-spinner.small.info + .sk-sublabel {{"Syncing" + (syncStatus.total > 0 ? ":" : "")}} %span{"ng-if" => "syncStatus.total > 0"} {{syncStatus.current}}/{{syncStatus.total}} - .subtitle.subtle.normal {{server}} - .panel-row + .sk-panel-row - %a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password - %a.panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} - .inline.circle.small.success.mr-8 + %a.sk-a.info.sk-panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password + %a.sk-panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} + .inline.sk-circle.small.success.mr-8 .inline Security Update Available - .panel-section - %h3.title.panel-row Encryption - %h5.subtitle.info.panel-row{"ng-if" => "encryptionEnabled()"} + .sk-panel-section + .sk-panel-section-title Encryption + .sk-panel-section-subtitle.info{"ng-if" => "encryptionEnabled()"} {{encryptionStatusForNotes()}} - %p + %p.sk-p {{encryptionStatusString()}} - .panel-section - %h3.title.panel-row Passcode Lock + .sk-panel-section + .sk-panel-section-title Passcode Lock %div{"ng-if" => "!hasPasscode()"} %div{"ng-if" => "canAddPasscode"} - .panel-row{"ng-if" => "!formData.showPasscodeForm"} - .button.info{"ng-click" => "addPasscodeClicked(); $event.stopPropagation();"} - .label Add Passcode + .sk-panel-row{"ng-if" => "!formData.showPasscodeForm"} + .sk-button.info{"ng-click" => "addPasscodeClicked(); $event.stopPropagation();"} + .sk-label Add Passcode - %p Add an app passcode to lock the app and encrypt on-device key storage. + %p.sk-p Add an app passcode to lock the app and encrypt on-device key storage. %div{"ng-if" => "!canAddPasscode"} - %p Adding a passcode is not supported in temporary sessions. Please sign out, then sign back in with the "Stay signed in" option checked. + %p.sk-p Adding a passcode is not supported in temporary sessions. Please sign out, then sign back in with the "Stay signed in" option checked. - %form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} - %input.form-control{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} - %input.form-control{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Set Passcode - %a.panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel + %form.sk-panel-form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} + .sk-panel-row + %input.sk-input{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Set Passcode + %a.neutral.sk-a.sk-panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel %div{"ng-if" => "hasPasscode() && !formData.showPasscodeForm"} - .panel-row - %p + .sk-panel-row + %p.sk-p Passcode lock is enabled. %span{"ng-if" => "isDesktopApplication()"} Your passcode will be required on new sessions after app quit. - .panel-row.justify-left - .horizontal-group - %a.info{"ng-click" => "changePasscodePressed()"} Change Passcode - %a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode + .sk-panel-row.justify-left + .sk-horizontal-group + %a.sk-a.info{"ng-click" => "changePasscodePressed()"} Change Passcode + %a.sk-a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode - .panel-section{"ng-if" => "!importData.loading"} - %h3.title Data Backups - %form.panel-form{"ng-if" => "encryptedBackupsAvailable()"} - .input-group + .sk-panel-section{"ng-if" => "!importData.loading"} + .sk-panel-section-title Data Backups + %form.sk-panel-form.sk-panel-row{"ng-if" => "encryptedBackupsAvailable()"} + .sk-input-group %label %input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "true", "ng-change" => "archiveFormData.encrypted = true"} Encrypted @@ -141,30 +143,30 @@ %input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "false", "ng-change" => "archiveFormData.encrypted = false"} Decrypted - .button-group - .button.info{"ng-click" => "downloadDataArchive()"} - .label Download Backup + .sk-button-group.sk-panel-row.justify-left + .sk-button.info{"ng-click" => "downloadDataArchive()"} + .sk-label Download Backup - %label.button.info + %label.sk-button.info %input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"} - .label Import From Backup + .sk-label Import From Backup %span{"ng-if" => "isDesktopApplication()"} Backups are automatically created on desktop and can be managed via the "Backups" top-level menu. #import-password-request{"ng-if" => "importData.requestPassword"} - %form.panel-form.stretch{"ng-submit" => "submitImportPassword()"} + %form.sk-panel-form.stretch{"ng-submit" => "submitImportPassword()"} %p Enter the account password associated with the import file. - %input.form-control.mt-5{:type => 'password', "placeholder" => "Enter File Account Password", "ng-model" => "importData.password", "autofocus" => "true"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Decrypt & Import + %input.sk-input.mt-5{:type => 'password', "placeholder" => "Enter File Account Password", "ng-model" => "importData.password", "autofocus" => "true"} + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Decrypt & Import %p Importing from backup will not overwrite existing data, but instead create a duplicate of any differing data. %p If you'd like to import only a selection of items instead of the whole file, please use the Batch Manager extension. - .panel-row - .spinner.small.info{"ng-if" => "importData.loading"} - .footer - %a.right{"ng-if" => "formData.showLogin || formData.showRegister", "ng-click" => "formData.showLogin = false; formData.showRegister = false;"} + .sk-panel-row + .sk-spinner.small.info{"ng-if" => "importData.loading"} + .sk-panel-footer + %a.sk-a.right{"ng-if" => "formData.showLogin || formData.showRegister", "ng-click" => "formData.showLogin = false; formData.showRegister = false;"} Cancel - %a.right{"ng-if" => "!formData.showLogin && !formData.showRegister", "ng-click" => "destroyLocalData()"} + %a.sk-a.right.danger{"ng-if" => "!formData.showLogin && !formData.showRegister", "ng-click" => "destroyLocalData()"} {{ user ? "Sign out and clear local data" : "Clear all local data" }} diff --git a/app/assets/templates/directives/actions-menu.html.haml b/app/assets/templates/directives/actions-menu.html.haml index cf0b7fffe..47ce2b5d6 100644 --- a/app/assets/templates/directives/actions-menu.html.haml +++ b/app/assets/templates/directives/actions-menu.html.haml @@ -1,20 +1,20 @@ .sn-component - .menu-panel.dropdown-menu + .sk-menu-panel.dropdown-menu %a.no-decoration{"ng-if" => "extensions.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"} %menu-row{"label" => "'Download Actions'"} %div{"ng-repeat" => "extension in extensions"} - .header{"ng-click" => "extension.hide = !extension.hide; $event.stopPropagation();"} - .column - %h4.title {{extension.name}} - .spinner.small.loading{"ng-if" => "extension.loading"} + .sk-menu-panel-header{"ng-click" => "extension.hide = !extension.hide; $event.stopPropagation();"} + .sk-menu-panel-column + .sk-menu-panel-header-title {{extension.name}} + .sk-spinner.small.loading{"ng-if" => "extension.loading"} %div{"ng-if" => "extension.hide"} … %menu-row{"ng-if" => "!extension.hide", "ng-repeat" => "action in extension.actionsWithContextForItem(item)", "action" => "executeAction(action, extension);", "label" => "action.label", "subtitle" => "action.desc", "spinner-class" => "action.running ? 'info' : null", "sub-rows" => "action.subrows"} - .sublabel{"ng-if" => "action.access_type"} + .sk-sublabel{"ng-if" => "action.access_type"} Uses %strong {{action.access_type}} access to this note. diff --git a/app/assets/templates/directives/component-modal.html.haml b/app/assets/templates/directives/component-modal.html.haml index 6692df4d6..cb50246e4 100644 --- a/app/assets/templates/directives/component-modal.html.haml +++ b/app/assets/templates/directives/component-modal.html.haml @@ -2,9 +2,9 @@ .content{"ng-attr-id" => "component-content-outer-{{component.uuid}}"} .sn-component - .panel{"ng-attr-id" => "component-content-inner-{{component.uuid}}"} - .header - %h1.title + .sk-panel{"ng-attr-id" => "component-content-inner-{{component.uuid}}"} + .sk-panel-header + .sk-panel-header-title {{component.name}} - %a.close-button.info{"ng-click" => "dismiss()"} Close + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close %component-view.component-view{"component" => "component"} diff --git a/app/assets/templates/directives/component-view.html.haml b/app/assets/templates/directives/component-view.html.haml index 70b6be9d8..eba49d1c9 100644 --- a/app/assets/templates/directives/component-view.html.haml +++ b/app/assets/templates/directives/component-view.html.haml @@ -1,35 +1,35 @@ .sn-component{"ng-if" => "issueLoading"} - .app-bar.no-edges.no-top-edge + .sk-app-bar.no-edges.no-top-edge .left - .item - .label.warning There was an issue loading {{component.name}}. + .sk-app-bar-item + .sk-label.warning There was an issue loading {{component.name}}. .right - .item{"ng-click" => "reloadComponent()"} - .label Reload + .sk-app-bar-item{"ng-click" => "reloadComponent()"} + .sk-label Reload .sn-component{"ng-if" => "showNoThemesMessage"} - .app-bar.no-edges.no-top-edge + .sk-app-bar.no-edges.no-top-edge .left - .item - .label.warning This extension does not support themes. + .sk-app-bar-item + .sk-label.warning This extension does not support themes. .right - .item{"ng-click" => "noThemesMessageDismiss()"} - .label Dismiss - .item{"ng-click" => "disableActiveTheme()"} - .label Disable Active Theme + .sk-app-bar-item{"ng-click" => "noThemesMessageDismiss()"} + .sk-label Dismiss + .sk-app-bar-item{"ng-click" => "disableActiveTheme()"} + .sk-label Disable Active Theme .sn-component{"ng-if" => "error == 'expired'"} - .panel.static - .content - .panel-section.stretch - %h2.title Unable to load Standard Notes Extended + .sk-panel.static + .sk-panel-content + .sk-panel-section.stretch + .sk-panel-sectin-title Unable to load Standard Notes Extended %p Your Extended subscription expired on {{component.dateToLocalizedString(component.valid_until)}}. %p Please visit %a{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} dashboard.standardnotes.org to renew your subscription. - .panel-row - .panel-column + .sk-panel-row + .sk-panel-column %p %strong To reload your account status: %p @@ -40,25 +40,25 @@ menu located in the lower left corner of the app to refresh your account status. %li Click Reload below. - .panel-row - .button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} - .label Reload - .spinner.info.small{"ng-if" => "reloading"} + .sk-panel-row + .sk-button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} + .sk-label Reload + .sk-spinner.info.small{"ng-if" => "reloading"} - .panel-row - .panel-section + .sk-panel-row + .sk-panel-section %p{"ng-if" => "component.isEditor()"} Otherwise, please follow the steps below to disable any external editors, so you can edit your note using the plain text editor instead. %p To temporarily disable this extension: - .panel-row - .button.info{"ng-click" => "destroy()"} - .label Disable Extension - .spinner.info.small{"ng-if" => "reloading"} + .sk-panel-row + .sk-button.info{"ng-click" => "destroy()"} + .sk-label Disable Extension + .sk-spinner.info.small{"ng-if" => "reloading"} - .panel-row + .sk-panel-row %div{"ng-if" => "component.isEditor()"} %p To disassociate this note from this editor: @@ -76,28 +76,28 @@ page. .sn-component{"ng-if" => "error == 'offline-restricted'"} - .panel.static - .content - .panel-section.stretch - %h2.title You have restricted this extension to be used offline only. + .sk-panel.static + .sk-panel-content + .sk-panel-section.stretch + .sk-panel-section-title You have restricted this extension to be used offline only. %p Offline extensions are not available in the Web app. - .panel-row - .panel-column + .sk-panel-row + .sk-panel-column %p You can either: %p %ul %li Enable the Hosted option for this extension by opening the 'Extensions' menu and toggling 'Use hosted when local is unavailable' under this extension's options. Then press Reload below. %li Use the Desktop application. - .panel-row - .button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} - .label Reload - .spinner.info.small{"ng-if" => "reloading"} + .sk-panel-row + .sk-button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} + .sk-label Reload + .sk-spinner.info.small{"ng-if" => "reloading"} .sn-component{"ng-if" => "error == 'url-missing'"} - .panel.static - .content - .panel-section.stretch - %h2.title This extension is not installed correctly. + .sk-panel.static + .sk-panel-content + .sk-panel-section.stretch + .sk-panel-section-title This extension is not installed correctly. %p Please uninstall {{component.name}}, then re-install it. %p diff --git a/app/assets/templates/directives/conflict-resolution-modal.html.haml b/app/assets/templates/directives/conflict-resolution-modal.html.haml index 87bb97e28..032f0eca9 100644 --- a/app/assets/templates/directives/conflict-resolution-modal.html.haml +++ b/app/assets/templates/directives/conflict-resolution-modal.html.haml @@ -1,26 +1,26 @@ .modal.large#conflict-resolution-modal .content .sn-component - .panel - .header - %h1.title Conflicted items — choose which version to keep - .horizontal-group - %a.close-button.info{"ng-click" => "keepItem1()"} Keep left - %a.close-button.info{"ng-click" => "keepItem2()"} Keep right - %a.close-button.info{"ng-click" => "keepBoth()"} Keep both - %a.close-button.info{"ng-click" => "export()"} Export - %a.close-button.info{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .content.selectable - .panel-section + .sk-panel + .sk-panel-header + %h1.sk-panel-header-title Conflicted items — choose which version to keep + .sk-horizontal-group + %a.sk-a.info.close-button{"ng-click" => "keepItem1()"} Keep left + %a.sk-a.info.close-button{"ng-click" => "keepItem2()"} Keep right + %a.sk-a.info.close-button{"ng-click" => "keepBoth()"} Keep both + %a.sk-a.info.close-button{"ng-click" => "export()"} Export + %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .sk-panel-content.selectable + .sk-panel-section %h3 %strong Content type: {{contentType}} %p You may wish to look at the "created_at" and "updated_at" fields of the items to gain better context in deciding which to keep. #items - .panel.static#item1.item.border-color + .sk-panel.static#item1.item.border-color %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{item1Content}} .border - .panel.static#item2.item + .sk-panel.static#item2.item %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{item2Content}} diff --git a/app/assets/templates/directives/editor-menu.html.haml b/app/assets/templates/directives/editor-menu.html.haml index 9d6ce6df9..4bd52d9a0 100644 --- a/app/assets/templates/directives/editor-menu.html.haml +++ b/app/assets/templates/directives/editor-menu.html.haml @@ -1,26 +1,26 @@ .sn-component - .menu-panel.dropdown-menu - .section - .header - %h4.title Note Editor + .sk-menu-panel.dropdown-menu + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Note Editor %menu-row{"label" => "'Plain Editor'", "circle" => "selectedEditor == null && 'success'", "action" => "selectComponent(null)"} %menu-row{"ng-repeat" => "editor in editors", "action" => "selectComponent(editor)", "label" => "editor.name", "circle" => "selectedEditor === editor && 'success'", "has-button" => "selectedEditor == editor || defaultEditor == editor", "button-text" => "defaultEditor == editor ? 'Undefault' : 'Set Default'", "button-action" => "toggleDefaultForEditor(editor)", "button-class" => "defaultEditor == editor ? 'warning' : 'info'"} - .column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"} - %strong.red.medium-text{"ng-if" => "editor.conflict_of"} Conflicted copy - .sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally + .sk-menu-panel-column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"} + %strong.danger.medium-text{"ng-if" => "editor.conflict_of"} Conflicted copy + .sk-sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally %a.no-decoration{"ng-if" => "editors.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"} %menu-row{"label" => "'Download More Editors'"} - .section{"ng-if" => "stack.length > 0"} - .header - %h4.title Editor Stack + .sk-menu-panel-section{"ng-if" => "stack.length > 0"} + .sk-menu-panel-header + .sk-menu-panel-header-title Editor Stack %menu-row{"ng-repeat" => "component in stack", "action" => "selectComponent(component)", "label" => "component.name", "circle" => "stackComponentEnabled(component) ? 'success' : 'danger'"} - .column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"} - %strong.red.medium-text{"ng-if" => "component.conflict_of"} Conflicted copy - .sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally + .sk-menu-panel-column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"} + %strong.danger.medium-text{"ng-if" => "component.conflict_of"} Conflicted copy + .sk-sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally diff --git a/app/assets/templates/directives/input-modal.html.haml b/app/assets/templates/directives/input-modal.html.haml index 706e6ac97..3fa0cf810 100644 --- a/app/assets/templates/directives/input-modal.html.haml +++ b/app/assets/templates/directives/input-modal.html.haml @@ -1,18 +1,18 @@ .modal.small.auto-height .content .sn-component - .panel - .header - %h1.title {{title}} - %a.close-button{"ng-click" => "dismiss()"} Close - .content - .panel-section - %p.panel-row {{message}} - .panel-row - .panel-column.stretch + .sk-panel + .sk-panel-header + %h1.sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content + .sk-panel-section + %p.sk-panel-row {{message}} + .sk-panel-row + .sk-panel-column.stretch %form{"ng-submit" => "submit()"} - %input.form-control{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} - .footer - %a.right{"ng-click" => "submit()"} + .sk-panel-footer + %a.sk-a.info.right{"ng-click" => "submit()"} Submit diff --git a/app/assets/templates/directives/menu-row.html.haml b/app/assets/templates/directives/menu-row.html.haml index 0cb3cf604..009c0d236 100644 --- a/app/assets/templates/directives/menu-row.html.haml +++ b/app/assets/templates/directives/menu-row.html.haml @@ -1,21 +1,21 @@ -.row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} - .column +.sk-menu-panel-row.row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} + .sk-menu-panel-column .left - .column{"ng-if" => "circle"} - .circle.small{"ng-class" => "circle"} - .column{"ng-class" => "{'faded' : faded || disabled}"} - .label + .sk-menu-panel-column{"ng-if" => "circle"} + .sk-circle.small{"ng-class" => "circle"} + .sk-menu-panel-column{"ng-class" => "{'faded' : faded || disabled}"} + .sk-label {{label}} - .sublabel{"ng-if" => "subtitle"} + .sk-sublabel{"ng-if" => "subtitle"} {{subtitle}} %ng-transclude - .subrows{"ng-if" => "subRows && subRows.length > 0"} + .sk-menu-panel-subrows{"ng-if" => "subRows && subRows.length > 0"} %menu-row{"ng-repeat" => "row in subRows", "action" => "row.onClick()", "label" => "row.label", "subtitle" => "row.subtitle", "spinner-class" => "row.spinnerClass"} - .column{"ng-if" => "hasButton"} - .button.info{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} - {{buttonText}} + .sk-menu-panel-column{"ng-if" => "hasButton"} + .sk-button{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} + .sk-label {{buttonText}} - .column{"ng-if" => "spinnerClass"} - .spinner.small{"ng-class" => "spinnerClass"} + .sk-menu-panel-column{"ng-if" => "spinnerClass"} + .sk-spinner.small{"ng-class" => "spinnerClass"} diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index cbcdf6f54..7922211af 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -1,108 +1,103 @@ #password-wizard.modal.small.auto-height .content .sn-component - .panel - .header - %h1.title {{title}} - %a.close-button{"ng-click" => "dismiss()"} Close - .content + .sk-panel + .sk-panel-header + .sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content %div{"ng-if" => "step == 0"} %div{"ng-if" => "changePassword"} - %h2.title.panel-row Change your password - %p + %p.sk-p Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. If you have many items, syncing your data can take several minutes. - %p.panel-row + %p.sk-p %strong You must keep the application window open during this process. %div{"ng-if" => "securityUpdate"} - %h2.title.panel-row Perform security update - %p + %p.sk-p A new update is available for your account. Updates address improvements and enhancements to our security specification. This process will guide you through the update, and perform the steps necessary with your supervision. - %p + %p.sk-p For more information about security updates, please visit - %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. + %a.sk-a.info{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. - %p.panel-row + %p.sk-panel-row.sk-p .info Press Continue to proceed. - .panel-row - .panel-row + .sk-panel-section{"ng-if" => "step > 0"} - .panel-section{"ng-if" => "step > 0"} - - %h3.title.panel-row Step {{step}} — {{titleForStep(step)}} + .sk-panel-section-title Step {{step}} — {{titleForStep(step)}} %div{"ng-if" => "step == 1"} - %p.panel-row + %p.sk-panel-row.sk-p As a result of this process, the entirety of your data will be re-encrypted and synced to your account. This is a generally safe process, but unforeseen factors like poor network connectivity or a sudden shutdown of your computer may cause this process to fail. It's best to be on the safe side before large operations such as this one. - .panel-row - .panel-row - .button-group - .button.info{"ng-click" => "downloadBackup(true)"} - .label Download Encrypted Backup - .button.info{"ng-click" => "downloadBackup(false)"} - .label Download Decrypted Backup + .sk-panel-row + .sk-panel-row + .sk-button-group + .sk-button.info{"ng-click" => "downloadBackup(true)"} + .sk-label Download Encrypted Backup + .sk-button.info{"ng-click" => "downloadBackup(false)"} + .sk-label Download Decrypted Backup %div{"ng-if" => "step == 2"} - %p.panel-row + %p.sk-p.sk-panel-row As a result of this process, your encryption keys will change. Any device on which you use Standard Notes will need to end its session. After this process completes, you will be asked to sign back in. - %p.bold.panel-row.info-i Please sign out of all applications (excluding this one), including: + %p.sk-p.bold.sk-panel-row.info-i Please sign out of all applications (excluding this one), including: %ul %li Desktop %li Web (Chrome, Firefox, Safari) %li Mobile (iOS and Android) - %p.panel-row + %p.sk-p.sk-panel-row If you do not currently have access to a device you're signed in on, you may proceed, but must make signing out and back in the first step upon gaining access to that device. - %p.panel-row Press Continue only when you have completed signing out of all your devices. + %p.sk-p.sk-panel-row Press Continue only when you have completed signing out of all your devices. %div{"ng-if" => "step == 3"} %div{"ng-if" => "changePassword"} %div{"ng-if" => "securityUpdate"} - %p.panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. - .panel-row - .panel-row - .panel-column.stretch - %form - %input.form-control{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} - %input.form-control{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} - %input.form-control{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} + %p.sk-panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. + .sk-panel-row + .sk-panel-row + .sk-panel-column.stretch + %form.sk-panel-form + %input.sk-input{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} + %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} %div{"ng-if" => "step == 4"} - %p.panel-row + %p.sk-panel-row Your data is being re-encrypted with your new keys and synced to your account. - %p.panel-row.danger + %p.sk-panel-row.danger Do not close this window until this process completes. - .panel-row - .panel-column - .spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} + .sk-panel-row + .sk-panel-column + .sk-spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} .inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"} {{formData.status}} - .panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} + .sk-panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} %p.info Syncing {{syncStatus.current}}/{{syncStatus.total}} %div{"ng-if" => "step == 5"} %div{"ng-if" => "changePassword"} - %p.panel-row Your password has been successfully changed. + %p.sk-panel-row Your password has been successfully changed. %div{"ng-if" => "securityUpdate"} - %p.panel-row + %p.sk-panel-row The security update has been successfully applied to your account. - %p.panel-row + %p.sk-panel-row %strong Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. - %p.panel-row You may now sign back in on all your devices and close this window. + %p.sk-panel-row You may now sign back in on all your devices and close this window. - .footer + .sk-panel-footer .empty - %a.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} - .spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} + %a.sk-a.info.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} + .sk-spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} {{continueTitle}} diff --git a/app/assets/templates/directives/permissions-modal.html.haml b/app/assets/templates/directives/permissions-modal.html.haml index 63a5dc38f..b8522c27c 100644 --- a/app/assets/templates/directives/permissions-modal.html.haml +++ b/app/assets/templates/directives/permissions-modal.html.haml @@ -2,21 +2,22 @@ .content#permissions-modal .sn-component - .panel - .header - %h1.title Activate Extension - %a.close-button.info{"ng-click" => "deny()"} Cancel - .content - .panel-section - .panel-row + .sk-panel + .sk-panel-header + %h1.sk-panel-header-title Activate Extension + %a.sk-a.info.close-button{"ng-click" => "deny()"} Cancel + .sk-panel-content + .sk-panel-section + .sk-panel-row %h3 %strong {{component.name}} would like to interact with your {{permissionsString()}} - .panel-row + .sk-panel-row %p Extensions use an offline messaging system to communicate. Learn more at - %a{"href" => "https://standardnotes.org/permissions", "target" => "_blank"} https://standardnotes.org/permissions. - .footer - .button.info.big.block.bold{"ng-click" => "accept()"} Continue + %a.sk-a.info{"href" => "https://standardnotes.org/permissions", "target" => "_blank"} https://standardnotes.org/permissions. + .sk-panel-footer + .sk-button.info.big.block.bold{"ng-click" => "accept()"} + .sk-label Continue diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml index df37fb182..4d144d6bd 100644 --- a/app/assets/templates/directives/revision-preview-modal.html.haml +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -1,13 +1,13 @@ .modal.medium#item-preview-modal .content .sn-component - .panel - .header - %h1.title Preview - .horizontal-group - %a.close-button.info{"ng-click" => "restore(false)"} Restore - %a.close-button.info{"ng-click" => "restore(true)"} Restore as copy - %a.close-button.info{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .content.selectable - %h2 {{content.title}} - %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} + .sk-panel + .sk-panel-header + .sk-panel-header-title Preview + .sk-horizontal-group + %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore + %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy + %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .sk-panel-content.selectable + .sk-h2 {{content.title}} + %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} diff --git a/app/assets/templates/directives/session-history-menu.html.haml b/app/assets/templates/directives/session-history-menu.html.haml index fd994a9a6..72f87e640 100644 --- a/app/assets/templates/directives/session-history-menu.html.haml +++ b/app/assets/templates/directives/session-history-menu.html.haml @@ -1,23 +1,23 @@ .sn-component#session-history-menu - .menu-panel.dropdown-menu - .header - .column - %h4.title {{history.entries.length || 'No'}} revisions - %h4{"ng-click" => "showOptions = !showOptions; $event.stopPropagation();"} - %a Options + .sk-menu-panel.dropdown-menu + .sk-menu-panel-header + .sk-menu-panel-column + .sk-menu-panel-header-title {{history.entries.length || 'No'}} revisions + .sk-menu-panel-column{"ng-click" => "showOptions = !showOptions; $event.stopPropagation();"} + %a.sk-a.info.sk-menu-panel-header-title Options %div{"ng-if" => "showOptions"} %menu-row{"label" => "'Clear note local history'", "action" => "clearItemHistory()"} %menu-row{"label" => "'Clear all local history'", "action" => "clearAllHistory()"} %menu-row{"label" => "(autoOptimize ? 'Disable' : 'Enable') + ' auto cleanup'", "action" => "toggleAutoOptimize()"} - .sublabel + .sk-sublabel Automatically cleans up small revisions to conserve space. %menu-row{"label" => "(diskEnabled ? 'Disable' : 'Enable') + ' saving history to disk'", "action" => "toggleDiskSaving()"} - .sublabel + .sk-sublabel Saving to disk may increase app loading time and memory footprint. %menu-row{"ng-repeat" => "revision in entries", "action" => "openRevision(revision);", "label" => "revision.previewTitle()"} - .sublabel.opaque{"ng-class" => "classForRevision(revision)"} + .sk-sublabel.opaque{"ng-class" => "classForRevision(revision)"} {{revision.previewSubTitle()}} diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index d78f5eca9..c0b323b67 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -1,9 +1,9 @@ .section.editor#editor-column{"aria-label" => "Note"} .sn-component - .app-bar.no-edges{"ng-if" => "ctrl.note.locked", "ng-init" => "ctrl.lockText = 'Note Locked'", "ng-mouseover" => "ctrl.lockText = 'Unlock'", "ng-mouseleave" => "ctrl.lockText = 'Note Locked'"} + .sk-app-bar.no-edges{"ng-if" => "ctrl.note.locked", "ng-init" => "ctrl.lockText = 'Note Locked'", "ng-mouseover" => "ctrl.lockText = 'Unlock'", "ng-mouseleave" => "ctrl.lockText = 'Note Locked'"} .left - .item{"ng-click" => "ctrl.toggleLockNote()"} - .label.warning + .sk-app-bar-item{"ng-click" => "ctrl.toggleLockNote()"} + .sk-label.warning %i.icon.ion-locked {{ctrl.lockText}} @@ -23,23 +23,23 @@ "spellcheck" => "false", "ng-disabled" => "ctrl.note.locked"} .sn-component{"ng-if" => "ctrl.note"} - .app-bar.no-edges + .sk-app-bar.no-edges .left - .item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} - .label Options - .menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} - .section - .header - %h4.title Note Options + .sk-app-bar-item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} + .sk-label Options + .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Note Options %menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"} %menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"} %menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"} %menu-row{"label" => "ctrl.note.content.hidePreview ? 'Unhide Preview' : 'Hide Preview'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} %menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"} - .section - .header - %h4.title Global Display + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Global Display %menu-row{"label" => "'Monospace Font'", "circle" => "ctrl.monospaceFont ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('monospaceFont')", "desc" => "'Toggles the font style for the default editor'", "subtitle" => "ctrl.selectedEditor ? 'Not available with editor extensions' : null", "disabled" => "ctrl.selectedEditor"} @@ -50,16 +50,16 @@ %menu-row{"label" => "'Margin Resizers'", "circle" => "ctrl.marginResizersEnabled ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('marginResizersEnabled')", "desc" => "'Allows for editor left and right margins to be resized'", "faded" => "!ctrl.marginResizersEnabled"} - .item{"ng-click" => "ctrl.onEditorMenuClick()", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} - .label Editor + .sk-app-bar-item{"ng-click" => "ctrl.onEditorMenuClick()", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} + .sk-label Editor %editor-menu{"ng-if" => "ctrl.showEditorMenu", "callback" => "ctrl.editorMenuOnSelect", "selected-editor" => "ctrl.selectedEditor", "current-item" => "ctrl.note"} - .item{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} - .label Actions + .sk-app-bar-item{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} + .sk-label Actions %actions-menu{"ng-if" => "ctrl.showExtensions", "item" => "ctrl.note"} - .item{"ng-click" => "ctrl.showSessionHistory = !ctrl.showSessionHistory; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} - .label Session History + .sk-app-bar-item{"ng-click" => "ctrl.showSessionHistory = !ctrl.showSessionHistory; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} + .sk-label Session History %session-history-menu{"ng-if" => "ctrl.showSessionHistory", "item" => "ctrl.note"} .editor-content#editor-content{"ng-if" => "ctrl.noteReady && !ctrl.note.errorDecrypting"} diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index c4dfd0171..edf43f615 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -1,44 +1,44 @@ .sn-component - #footer-bar.app-bar.no-edges + #footer-bar.sk-app-bar.no-edges .left - .item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} - .column - .circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} - .column - .label.title{"ng-class" => "{red: ctrl.error}"} Account + .sk-app-bar-item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} + .sk-app-bar-item-column + .sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} + .sk-app-bar-item-column + .sk-label.title{"ng-class" => "{red: ctrl.error}"} Account %account-menu{"ng-click" => "$event.stopPropagation()", "ng-if" => "ctrl.showAccountMenu", "on-successful-auth" => "ctrl.onAuthSuccess", "close-function" => "ctrl.closeAccountMenu"} - .item - %a.no-decoration.label.title{"href" => "https://standardnotes.org/help", "target" => "_blank"} + .sk-app-bar-item + %a.no-decoration.sk-label.title{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help - .item.border + .sk-app-bar-item.border - .item{"ng-repeat" => "room in ctrl.rooms track by room.uuid"} - .column{"ng-click" => "ctrl.selectRoom(room)"} - .label {{room.name}} + .sk-app-bar-item{"ng-repeat" => "room in ctrl.rooms track by room.uuid"} + .sk-app-bar-item-column{"ng-click" => "ctrl.selectRoom(room)"} + .sk-label {{room.name}} %component-modal{"ng-if" => "room.showRoom", "component" => "room", "on-dismiss" => "ctrl.onRoomDismiss"} .right - .item{"ng-if" => "ctrl.securityUpdateAvailable", "ng-click" => "ctrl.openSecurityUpdate()"} - %span.success.label Security update available. + .sk-app-bar-item{"ng-if" => "ctrl.securityUpdateAvailable", "ng-click" => "ctrl.openSecurityUpdate()"} + %span.success.sk-label Security update available. - .item{"ng-if" => "ctrl.newUpdateAvailable == true", "ng-click" => "ctrl.clickedNewUpdateAnnouncement()"} - %span.info.label New update available. + .sk-app-bar-item{"ng-if" => "ctrl.newUpdateAvailable == true", "ng-click" => "ctrl.clickedNewUpdateAnnouncement()"} + %span.info.sk-label New update available. - .item.no-pointer{"ng-if" => "ctrl.lastSyncDate && !ctrl.isRefreshing"} - .label.subtle + .sk-app-bar-item.no-pointer{"ng-if" => "ctrl.lastSyncDate && !ctrl.isRefreshing"} + .sk-label.subtle Last refreshed {{ctrl.lastSyncDate | appDateTime}} - .item{"ng-if" => "ctrl.lastSyncDate && ctrl.isRefreshing"} - .spinner.small + .sk-app-bar-item{"ng-if" => "ctrl.lastSyncDate && ctrl.isRefreshing"} + .sk-spinner.small - .item{"ng-if" => "ctrl.offline"} - .label Offline - .item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} - .label Refresh + .sk-app-bar-item{"ng-if" => "ctrl.offline"} + .sk-label Offline + .sk-app-bar-item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} + .sk-label Refresh - .item#lock-item{"ng-if" => "ctrl.hasPasscode()"} - .label + .sk-app-bar-item#lock-item{"ng-if" => "ctrl.hasPasscode()"} + .sk-label %i.icon.ion-locked#footer-lock-icon{"ng-if" => "ctrl.hasPasscode()", "ng-click" => "ctrl.lockApp()"} diff --git a/app/assets/templates/lock-screen.html.haml b/app/assets/templates/lock-screen.html.haml index e79559517..46cde4e19 100644 --- a/app/assets/templates/lock-screen.html.haml +++ b/app/assets/templates/lock-screen.html.haml @@ -1,23 +1,23 @@ #lock-screen.sn-component - .panel - .header - %h1.title Passcode Required - .content - .panel-section - %form.panel-form.panel-row{"ng-submit" => "submitPasscodeForm()"} - .panel-column.stretch - %input.panel-row{:type => 'password', + .sk-panel + .sk-panel-header + .sk-panel-header-title Passcode Required + .sk-panel-content + .sk-panel-section + %form.sk-panel-form.sk-panel-row{"ng-submit" => "submitPasscodeForm()"} + .sk-panel-column.stretch + %input.sk-panel-row.sk-input{:type => 'password', "ng-model" => "formData.passcode", "autofocus" => "true", "sn-autofocus" => "true", "should-focus" => "true", "placeholder" => "Enter Passcode", "autocomplete" => "new-password"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Unlock + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Unlock #passcode-reset - %a.default{"ng-if" => "!formData.showRecovery", "ng-click" => "forgotPasscode()"} Forgot Passcode? + %a.sk-a.neutral{"ng-if" => "!formData.showRecovery", "ng-click" => "forgotPasscode()"} Forgot Passcode? %div{"ng-if" => "formData.showRecovery"} %p If you forgot your local passcode, your only option is to clear all your local data from this device and sign back in to your account. - %a.danger{"ng-click" => "beginDeleteData()"} Delete Local Data + %a.sk-a.danger{"ng-click" => "beginDeleteData()"} Delete Local Data diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index a1e48dd1b..14766fe20 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -11,28 +11,26 @@ "title" => "Searches notes in the currently selected tag"} #search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.clearFilterText();"} ✕ .sn-component#notes-menu-bar - .app-bar.no-edges + .sk-app-bar.no-edges .left - .item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu", "ng-class" => "{'selected' : ctrl.showMenu}"} - .column - .label + .sk-app-bar-item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu", "ng-class" => "{'selected' : ctrl.showMenu}"} + .sk-app-bar-item-column + .sk-label Options - .column - .sublabel {{ctrl.optionsSubtitle()}} + .sk-app-bar-item-column + .sk-sublabel {{ctrl.optionsSubtitle()}} - .sn-component{"ng-if" => "ctrl.showMenu"} - .menu-panel.dropdown-menu - .section - .header - %h4.title Sort By + .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} + .sk-menu-panel-header + .sk-menu-panel-header-title Sort By - %menu-row{"label" => "'Date Added'", "circle" => "ctrl.sortBy == 'created_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()", "desc" => "'Sort notes by newest first'"} - %menu-row{"label" => "'Date Modified'", "circle" => "ctrl.sortBy == 'client_updated_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()", "desc" => "'Sort notes with the most recently updated first'"} - %menu-row{"label" => "'Title'", "circle" => "ctrl.sortBy == 'title' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByTitle()", "desc" => "'Sort notes alphabetically by their title'"} + %menu-row{"label" => "'Date Added'", "circle" => "ctrl.sortBy == 'created_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()", "desc" => "'Sort notes by newest first'"} + %menu-row{"label" => "'Date Modified'", "circle" => "ctrl.sortBy == 'client_updated_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()", "desc" => "'Sort notes with the most recently updated first'"} + %menu-row{"label" => "'Title'", "circle" => "ctrl.sortBy == 'title' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByTitle()", "desc" => "'Sort notes alphabetically by their title'"} - .section{"ng-if" => "!ctrl.tag.isSmartTag()"} - .header - %h4.title Display + .sk-menu-panel-section{"ng-if" => "!ctrl.tag.isSmartTag()"} + .sk-menu-panel-header + .sk-menu-panel-header-title Display %menu-row{"label" => "'Archived Notes'", "circle" => "ctrl.showArchived ? 'success' : 'danger'", "faded" => "!ctrl.showArchived", "action" => "ctrl.selectedMenuItem(); ctrl.toggleKey('showArchived')", "desc" => "'Archived notes are usually hidden. You can explicitly show them with this option.'"} %menu-row{"label" => "'Pinned Notes'", "circle" => "ctrl.hidePinned ? 'danger' : 'success'", "faded" => "ctrl.hidePinned", "action" => "ctrl.selectedMenuItem(); ctrl.toggleKey('hidePinned')", "desc" => "'Pinned notes always appear on top. You can hide them temporarily with this option so you can focus on other notes in the list.'"} diff --git a/package-lock.json b/package-lock.json index 712f36497..8cc47e753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.16", + "version": "2.3.18", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,8 +10,8 @@ "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==", "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "jsonparse": "1.3.1", + "through": "2.3.8" } }, "abbrev": { @@ -32,8 +32,8 @@ "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", "dev": true, "requires": { - "acorn": "^5.4.1", - "xtend": "^4.0.1" + "acorn": "5.6.2", + "xtend": "4.0.1" }, "dependencies": { "acorn": { @@ -63,7 +63,7 @@ "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "es6-promisify": "5.0.0" } }, "ajv": { @@ -72,10 +72,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "align-text": { @@ -84,9 +84,9 @@ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "alter": { @@ -95,7 +95,7 @@ "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", "dev": true, "requires": { - "stable": "~0.1.3" + "stable": "0.1.8" } }, "amdefine": { @@ -111,11 +111,11 @@ "dev": true, "optional": true, "requires": { - "bitsyntax": "~0.0.4", - "bluebird": "^3.4.6", + "bitsyntax": "0.0.4", + "bluebird": "3.5.1", "buffer-more-ints": "0.0.2", - "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" + "readable-stream": "1.1.14", + "safe-buffer": "5.1.2" }, "dependencies": { "isarray": { @@ -132,10 +132,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -177,8 +177,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "argparse": { @@ -187,7 +187,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" }, "dependencies": { "sprintf-js": { @@ -204,7 +204,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.1.0" } }, "arr-flatten": { @@ -267,9 +267,9 @@ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -329,7 +329,7 @@ "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", "dev": true, "requires": { - "acorn": "^4.0.3" + "acorn": "4.0.13" } }, "async": { @@ -391,7 +391,7 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.2.0" + "debug": "2.6.9" } } } @@ -402,21 +402,21 @@ "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" + "babel-core": "6.26.3", + "babel-polyfill": "6.26.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "chokidar": "1.7.0", + "commander": "2.15.1", + "convert-source-map": "1.5.1", + "fs-readdir-recursive": "1.1.0", + "glob": "7.1.2", + "lodash": "4.17.10", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.7", + "v8flags": "2.1.1" } }, "babel-code-frame": { @@ -425,9 +425,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" } }, "babel-core": { @@ -436,25 +436,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" } }, "babel-generator": { @@ -463,14 +463,14 @@ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.10", + "source-map": "0.5.7", + "trim-right": "1.0.1" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -479,9 +479,9 @@ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-call-delegate": { @@ -490,10 +490,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-define-map": { @@ -502,10 +502,10 @@ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-explode-assignable-expression": { @@ -514,9 +514,9 @@ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-function-name": { @@ -525,11 +525,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-get-function-arity": { @@ -538,8 +538,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-hoist-variables": { @@ -548,8 +548,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-optimise-call-expression": { @@ -558,8 +558,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-regex": { @@ -568,9 +568,9 @@ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-remap-async-to-generator": { @@ -579,11 +579,11 @@ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-replace-supers": { @@ -592,12 +592,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helpers": { @@ -606,8 +606,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-messages": { @@ -616,7 +616,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-angularjs-annotate": { @@ -625,9 +625,9 @@ "integrity": "sha512-erYvZAJgnrgeyEZqIJOAiK6vUK44HsVb0+Tid4zTBcsvdQuas0Z5Teh0w/hcINKW3G0xweqA5LGfg2ZWlp3nMA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-types": "^6.26.0", - "simple-is": "~0.2.0" + "babel-code-frame": "6.26.0", + "babel-types": "6.26.0", + "simple-is": "0.2.0" } }, "babel-plugin-check-es2015-constants": { @@ -636,7 +636,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-syntax-async-functions": { @@ -663,9 +663,9 @@ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -674,7 +674,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -683,7 +683,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -692,11 +692,11 @@ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-plugin-transform-es2015-classes": { @@ -705,15 +705,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -722,8 +722,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -732,7 +732,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -741,8 +741,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -751,7 +751,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -760,9 +760,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-literals": { @@ -771,7 +771,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -780,9 +780,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -791,10 +791,10 @@ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -803,9 +803,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -814,9 +814,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -825,8 +825,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -835,12 +835,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -849,8 +849,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-spread": { @@ -859,7 +859,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -868,9 +868,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -879,7 +879,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -888,7 +888,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -897,9 +897,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -908,9 +908,9 @@ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -919,7 +919,7 @@ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "regenerator-transform": "0.10.1" } }, "babel-plugin-transform-runtime": { @@ -928,7 +928,7 @@ "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-strict-mode": { @@ -937,8 +937,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-polyfill": { @@ -947,9 +947,9 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "regenerator-runtime": "0.10.5" }, "dependencies": { "regenerator-runtime": { @@ -966,36 +966,36 @@ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "3.2.8", + "invariant": "2.2.4", + "semver": "5.5.0" } }, "babel-preset-es2015": { @@ -1004,30 +1004,30 @@ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" } }, "babel-preset-es2016": { @@ -1036,7 +1036,7 @@ "integrity": "sha1-+QC/k+LrwNJ235uKtZck6/2Vn4s=", "dev": true, "requires": { - "babel-plugin-transform-exponentiation-operator": "^6.24.1" + "babel-plugin-transform-exponentiation-operator": "6.24.1" } }, "babel-register": { @@ -1045,13 +1045,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "babel-core": "6.26.3", + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "home-or-tmp": "2.0.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" } }, "babel-runtime": { @@ -1060,8 +1060,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" } }, "babel-template": { @@ -1070,11 +1070,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.10" } }, "babel-traverse": { @@ -1083,15 +1083,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" } }, "babel-types": { @@ -1100,10 +1100,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" } }, "babylon": { @@ -1130,13 +1130,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" }, "dependencies": { "component-emitter": { @@ -1151,7 +1151,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -1160,7 +1160,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -1169,7 +1169,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -1178,9 +1178,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -1222,7 +1222,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "better-assert": { @@ -1257,7 +1257,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "~2.0.5" + "readable-stream": "2.0.6" }, "dependencies": { "process-nextick-args": { @@ -1274,12 +1274,12 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -1315,10 +1315,10 @@ "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" + "continuable-cache": "0.3.1", + "error": "7.0.2", + "raw-body": "1.1.7", + "safe-json-parse": "1.0.1" } }, "body-parser": { @@ -1328,15 +1328,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", + "depd": "1.1.2", + "http-errors": "1.6.3", "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "~1.6.16" + "type-is": "1.6.16" }, "dependencies": { "bytes": { @@ -1365,7 +1365,7 @@ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "bower": { @@ -1380,7 +1380,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1390,9 +1390,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "brorand": { @@ -1407,12 +1407,12 @@ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "defined": "1.0.0", + "safe-buffer": "5.1.2", + "through2": "2.0.3", + "umd": "3.0.3" } }, "browser-resolve": { @@ -1436,54 +1436,54 @@ "integrity": "sha512-fMES05wq1Oukts6ksGUU2TMVHHp06LyQt0SIwbXIHm7waSrQmNBZePsU0iM/4f94zbvb/wHma+D1YrdzWYnF/A==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", - "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^2.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", + "JSONStream": "1.3.3", + "assert": "1.4.1", + "browser-pack": "6.1.0", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.2.0", + "buffer": "5.1.0", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.2.0", + "duplexer2": "0.1.4", + "events": "2.1.0", + "glob": "7.1.2", + "has": "1.0.3", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.1.0", + "labeled-stream-splicer": "2.0.1", + "mkdirp": "0.5.1", + "module-deps": "6.1.0", + "os-browserify": "0.3.0", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.6", + "resolve": "1.1.7", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "1.1.1", + "subarg": "1.0.0", + "syntax-error": "1.4.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" + "url": "0.11.0", + "util": "0.10.4", + "vm-browserify": "1.0.1", + "xtend": "4.0.1" } }, "browserify-aes": { @@ -1492,12 +1492,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "browserify-cache-api": { @@ -1506,9 +1506,9 @@ "integrity": "sha1-liR+hT8Gj9bg1FzHPwuyzZd47wI=", "dev": true, "requires": { - "async": "^1.5.2", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "async": "1.5.2", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "browserify-cipher": { @@ -1517,9 +1517,9 @@ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -1528,9 +1528,9 @@ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1" + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" } }, "browserify-incremental": { @@ -1539,10 +1539,10 @@ "integrity": "sha1-BxPLdYckemMqnwjPG9FpuHi2Koo=", "dev": true, "requires": { - "JSONStream": "^0.10.0", - "browserify-cache-api": "^3.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "0.10.0", + "browserify-cache-api": "3.0.1", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "JSONStream": { @@ -1552,7 +1552,7 @@ "dev": true, "requires": { "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" + "through": "2.3.8" } }, "jsonparse": { @@ -1569,8 +1569,8 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "randombytes": "2.0.6" } }, "browserify-sign": { @@ -1579,13 +1579,13 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.1" } }, "browserify-zlib": { @@ -1594,7 +1594,7 @@ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "~1.0.5" + "pako": "1.0.6" } }, "browserslist": { @@ -1603,8 +1603,8 @@ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "caniuse-lite": "1.0.30000849", + "electron-to-chromium": "1.3.48" } }, "buffer": { @@ -1613,8 +1613,8 @@ "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "1.3.0", + "ieee754": "1.1.11" } }, "buffer-from": { @@ -1675,15 +1675,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" }, "dependencies": { "component-emitter": { @@ -1718,8 +1718,8 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "camelcase": { @@ -1734,8 +1734,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "2.1.1", + "map-obj": "1.0.1" } }, "caniuse-lite": { @@ -1756,8 +1756,8 @@ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chai": { @@ -1766,12 +1766,12 @@ "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", - "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" } }, "chalk": { @@ -1780,11 +1780,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "change-case": { @@ -1793,24 +1793,24 @@ "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", "dev": true, "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "constant-case": "2.0.0", + "dot-case": "2.1.1", + "header-case": "1.0.1", + "is-lower-case": "1.1.3", + "is-upper-case": "1.1.2", + "lower-case": "1.1.4", + "lower-case-first": "1.0.2", + "no-case": "2.3.2", + "param-case": "2.1.1", + "pascal-case": "2.0.1", + "path-case": "2.1.1", + "sentence-case": "2.1.1", + "snake-case": "2.1.0", + "swap-case": "1.1.2", + "title-case": "2.1.1", + "upper-case": "1.1.3", + "upper-case-first": "1.1.2" } }, "check-error": { @@ -1825,15 +1825,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.2.4", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "cipher-base": { @@ -1842,8 +1842,8 @@ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "circular-json": { @@ -1858,10 +1858,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" }, "dependencies": { "define-property": { @@ -1870,7 +1870,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "isobject": { @@ -1887,8 +1887,8 @@ "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", "dev": true, "requires": { - "commander": "2.8.x", - "source-map": "0.4.x" + "commander": "2.8.1", + "source-map": "0.4.4" }, "dependencies": { "commander": { @@ -1897,7 +1897,7 @@ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } }, "source-map": { @@ -1906,7 +1906,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -1917,8 +1917,8 @@ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" } }, @@ -1940,8 +1940,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "map-visit": "1.0.0", + "object-visit": "1.0.1" } }, "color-convert": { @@ -1950,7 +1950,7 @@ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { - "color-name": "^1.1.1" + "color-name": "1.1.3" } }, "color-name": { @@ -1971,7 +1971,7 @@ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "^4.5.0" + "lodash": "4.17.10" } }, "combine-source-map": { @@ -1980,10 +1980,10 @@ "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" }, "dependencies": { "convert-source-map": { @@ -2000,7 +2000,7 @@ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -2033,10 +2033,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" } }, "connect": { @@ -2047,7 +2047,7 @@ "requires": { "debug": "2.6.9", "finalhandler": "1.1.0", - "parseurl": "~1.3.2", + "parseurl": "1.3.2", "utils-merge": "1.0.1" } }, @@ -2057,7 +2057,7 @@ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "^0.1.4" + "date-now": "0.1.4" } }, "constant-case": { @@ -2066,8 +2066,8 @@ "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", "dev": true, "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" + "snake-case": "2.1.0", + "upper-case": "1.1.3" } }, "constants-browserify": { @@ -2124,8 +2124,8 @@ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "bn.js": "4.11.8", + "elliptic": "6.4.0" } }, "create-hash": { @@ -2134,11 +2134,11 @@ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { @@ -2147,12 +2147,12 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "cross-spawn": { @@ -2161,7 +2161,7 @@ "integrity": "sha1-vWf5bAfvtjA7f+lMHpefiEeOCjk=", "dev": true, "requires": { - "lru-cache": "^2.5.0" + "lru-cache": "2.7.3" } }, "cryptiles": { @@ -2171,7 +2171,7 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "crypto-browserify": { @@ -2180,17 +2180,17 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "browserify-cipher": "1.0.1", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", + "inherits": "2.0.3", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "currently-unhandled": { @@ -2199,7 +2199,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "array-find-index": "1.0.2" } }, "custom-event": { @@ -2214,7 +2214,7 @@ "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "dashdash": { @@ -2223,7 +2223,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "data-uri-to-buffer": { @@ -2251,8 +2251,8 @@ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "debug": { @@ -2282,7 +2282,7 @@ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "^4.0.0" + "type-detect": "4.0.8" } }, "deep-is": { @@ -2298,8 +2298,8 @@ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "foreach": "2.0.5", + "object-keys": "1.0.11" } }, "define-property": { @@ -2308,8 +2308,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "is-descriptor": "1.0.2", + "isobject": "3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2318,7 +2318,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -2327,7 +2327,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -2336,9 +2336,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -2368,9 +2368,9 @@ "dev": true, "optional": true, "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" + "ast-types": "0.11.5", + "escodegen": "1.11.0", + "esprima": "3.1.3" }, "dependencies": { "esprima": { @@ -2400,10 +2400,10 @@ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" + "JSONStream": "1.3.3", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" } }, "des.js": { @@ -2412,8 +2412,8 @@ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "destroy": { @@ -2428,7 +2428,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "detective": { @@ -2437,9 +2437,9 @@ "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==", "dev": true, "requires": { - "acorn-node": "^1.3.0", - "defined": "^1.0.0", - "minimist": "^1.1.1" + "acorn-node": "1.3.0", + "defined": "1.0.0", + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -2468,9 +2468,9 @@ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" } }, "dom-serialize": { @@ -2479,10 +2479,10 @@ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" } }, "domain-browser": { @@ -2497,7 +2497,7 @@ "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "double-ended-queue": { @@ -2513,7 +2513,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "ecc-jsbn": { @@ -2523,7 +2523,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "ee-first": { @@ -2544,13 +2544,13 @@ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "encodeurl": { @@ -2571,8 +2571,8 @@ "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", "dev": true, "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "string-template": "0.2.1", + "xtend": "4.0.1" } }, "error-ex": { @@ -2581,7 +2581,7 @@ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "es6-promise": { @@ -2596,7 +2596,7 @@ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "es6-promise": "4.2.4" } }, "escape-html": { @@ -2618,11 +2618,11 @@ "dev": true, "optional": true, "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" }, "dependencies": { "esprima": { @@ -2690,8 +2690,8 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "md5.js": "1.3.4", + "safe-buffer": "5.1.2" } }, "exit": { @@ -2706,9 +2706,9 @@ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", "dev": true, "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" }, "dependencies": { "braces": { @@ -2717,7 +2717,7 @@ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", "dev": true, "requires": { - "expand-range": "^0.1.0" + "expand-range": "0.1.1" } }, "expand-range": { @@ -2726,8 +2726,8 @@ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" + "is-number": "0.1.1", + "repeat-string": "0.2.2" } }, "is-number": { @@ -2750,7 +2750,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -2759,7 +2759,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.4" } }, "extend": { @@ -2774,8 +2774,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -2784,7 +2784,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -2795,7 +2795,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "extract-zip": { @@ -2841,7 +2841,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": ">=0.5.1" + "websocket-driver": "0.7.0" } }, "fd-slicer": { @@ -2850,7 +2850,7 @@ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "dev": true, "requires": { - "pend": "~1.2.0" + "pend": "1.2.0" } }, "figures": { @@ -2859,8 +2859,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "file-sync-cmp": { @@ -2888,11 +2888,11 @@ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "3.0.0", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -2902,12 +2902,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" }, "dependencies": { "statuses": { @@ -2924,8 +2924,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "findup-sync": { @@ -2934,7 +2934,7 @@ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "requires": { - "glob": "~5.0.0" + "glob": "5.0.15" }, "dependencies": { "glob": { @@ -2943,11 +2943,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } } } @@ -2958,7 +2958,7 @@ "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", "dev": true, "requires": { - "debug": "^3.1.0" + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -2984,7 +2984,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "foreach": { @@ -3005,9 +3005,9 @@ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.18" } }, "fragment-cache": { @@ -3016,7 +3016,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "^0.2.2" + "map-cache": "0.2.2" } }, "fresh": { @@ -3031,9 +3031,9 @@ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" } }, "fs-readdir-recursive": { @@ -3055,8 +3055,8 @@ "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "2.11.0", + "node-pre-gyp": "0.10.0" }, "dependencies": { "abbrev": { @@ -3082,8 +3082,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.3.6" } }, "balanced-match": { @@ -3096,7 +3096,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -3160,7 +3160,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "fs.realpath": { @@ -3175,14 +3175,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" } }, "glob": { @@ -3191,12 +3191,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "has-unicode": { @@ -3211,7 +3211,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": "2.1.2" } }, "ignore-walk": { @@ -3220,7 +3220,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "3.0.4" } }, "inflight": { @@ -3229,8 +3229,8 @@ "dev": true, "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -3249,7 +3249,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "isarray": { @@ -3263,7 +3263,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -3276,8 +3276,8 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, "minizlib": { @@ -3286,7 +3286,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "mkdirp": { @@ -3309,9 +3309,9 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" } }, "node-pre-gyp": { @@ -3320,16 +3320,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "needle": "2.2.0", + "nopt": "4.0.1", + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.7", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" } }, "nopt": { @@ -3338,8 +3338,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" } }, "npm-bundled": { @@ -3354,8 +3354,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" } }, "npmlog": { @@ -3364,10 +3364,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { @@ -3386,7 +3386,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { @@ -3407,8 +3407,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { @@ -3429,10 +3429,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "deep-extend": "0.5.1", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" }, "dependencies": { "minimist": { @@ -3449,13 +3449,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "rimraf": { @@ -3464,7 +3464,7 @@ "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "safe-buffer": { @@ -3507,9 +3507,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -3518,7 +3518,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } }, "strip-ansi": { @@ -3526,7 +3526,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { @@ -3541,13 +3541,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, "util-deprecate": { @@ -3562,7 +3562,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "wrappy": { @@ -3584,7 +3584,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "1.1.x", + "readable-stream": "1.1.14", "xregexp": "2.0.0" }, "dependencies": { @@ -3602,10 +3602,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -3629,7 +3629,7 @@ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { - "globule": "^1.0.0" + "globule": "1.2.1" } }, "generate-function": { @@ -3639,7 +3639,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.2" + "is-property": "1.0.2" } }, "generate-object-property": { @@ -3649,7 +3649,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.0" + "is-property": "1.0.2" } }, "get-func-name": { @@ -3671,12 +3671,12 @@ "dev": true, "optional": true, "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" + "data-uri-to-buffer": "1.2.0", + "debug": "2.6.9", + "extend": "3.0.1", + "file-uri-to-path": "1.0.0", + "ftp": "0.3.10", + "readable-stream": "2.3.6" } }, "get-value": { @@ -3697,7 +3697,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "glob": { @@ -3706,12 +3706,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-base": { @@ -3720,8 +3720,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-parent": { @@ -3730,7 +3730,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "globals": { @@ -3745,9 +3745,9 @@ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "dev": true, "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" + "glob": "7.1.2", + "lodash": "4.17.10", + "minimatch": "3.0.4" } }, "graceful-fs": { @@ -3774,23 +3774,23 @@ "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.5.2", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", - "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "coffeescript": "1.10.0", + "dateformat": "1.0.12", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.3.0", + "glob": "7.0.6", + "grunt-cli": "1.2.0", + "grunt-known-options": "1.1.0", + "grunt-legacy-log": "2.0.0", + "grunt-legacy-util": "1.1.1", + "iconv-lite": "0.4.23", + "js-yaml": "3.5.5", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" }, "dependencies": { "glob": { @@ -3799,12 +3799,12 @@ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "grunt-cli": { @@ -3813,10 +3813,10 @@ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", "dev": true, "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.0", + "nopt": "3.0.6", + "resolve": "1.1.7" } } } @@ -3827,7 +3827,7 @@ "integrity": "sha1-EJYDorlf8BAZtxjHA0EmjwnYvhk=", "dev": true, "requires": { - "html-minifier": "~2.1.2" + "html-minifier": "2.1.7" } }, "grunt-babel": { @@ -3836,7 +3836,7 @@ "integrity": "sha1-N4GJtIfeEWjExKn8iN1gBbNd+WA=", "dev": true, "requires": { - "babel-core": "^6.0.12" + "babel-core": "6.26.3" } }, "grunt-browserify": { @@ -3845,13 +3845,13 @@ "integrity": "sha1-R/2M+LrFj+LeaDr9xX9/OoDKeS0=", "dev": true, "requires": { - "async": "^2.5.0", - "browserify": "^16.0.0", - "browserify-incremental": "^3.1.1", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "resolve": "^1.1.6", - "watchify": "^3.6.1" + "async": "2.6.1", + "browserify": "16.2.2", + "browserify-incremental": "3.1.1", + "glob": "7.1.2", + "lodash": "4.17.10", + "resolve": "1.1.7", + "watchify": "3.11.0" }, "dependencies": { "async": { @@ -3860,7 +3860,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3871,8 +3871,8 @@ "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "requires": { - "chalk": "^1.0.0", - "source-map": "^0.5.3" + "chalk": "1.1.3", + "source-map": "0.5.7" } }, "grunt-contrib-copy": { @@ -3881,8 +3881,8 @@ "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=", "dev": true, "requires": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" + "chalk": "1.1.3", + "file-sync-cmp": "0.1.1" } }, "grunt-contrib-cssmin": { @@ -3891,9 +3891,9 @@ "integrity": "sha1-FzTL09hMpzZHWLflj/GOUqpgu3Y=", "dev": true, "requires": { - "chalk": "^1.0.0", - "clean-css": "~3.4.2", - "maxmin": "^1.1.0" + "chalk": "1.1.3", + "clean-css": "3.4.28", + "maxmin": "1.1.0" } }, "grunt-contrib-sass": { @@ -3902,11 +3902,11 @@ "integrity": "sha1-gGg4JRy8DhqU1k1RXN00z2dNcBs=", "dev": true, "requires": { - "async": "^0.9.0", - "chalk": "^1.0.0", - "cross-spawn": "^0.2.3", - "dargs": "^4.0.0", - "which": "^1.0.5" + "async": "0.9.2", + "chalk": "1.1.3", + "cross-spawn": "0.2.9", + "dargs": "4.1.0", + "which": "1.3.1" }, "dependencies": { "async": { @@ -3923,11 +3923,11 @@ "integrity": "sha1-s9AmDr3WzvoS/y+Onh4ln33kIW8=", "dev": true, "requires": { - "chalk": "^1.0.0", - "maxmin": "^1.1.0", - "object.assign": "^4.0.4", - "uglify-js": "~2.8.21", - "uri-path": "^1.0.0" + "chalk": "1.1.3", + "maxmin": "1.1.0", + "object.assign": "4.1.0", + "uglify-js": "2.8.29", + "uri-path": "1.0.0" }, "dependencies": { "uglify-js": { @@ -3936,9 +3936,9 @@ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" } } } @@ -3949,10 +3949,10 @@ "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { - "async": "^2.6.0", - "gaze": "^1.1.0", - "lodash": "^4.17.10", - "tiny-lr": "^1.1.1" + "async": "2.6.1", + "gaze": "1.1.3", + "lodash": "4.17.10", + "tiny-lr": "1.1.1" }, "dependencies": { "async": { @@ -3961,7 +3961,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3972,7 +3972,7 @@ "integrity": "sha1-b7W9R+JQ3Q9VzS76kj7kMQFEFCM=", "dev": true, "requires": { - "dargs": "~0.1.0" + "dargs": "0.1.0" }, "dependencies": { "dargs": { @@ -3995,10 +3995,10 @@ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", "dev": true, "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" + "colors": "1.1.2", + "grunt-legacy-log-utils": "2.0.1", + "hooker": "0.2.3", + "lodash": "4.17.10" } }, "grunt-legacy-log-utils": { @@ -4007,8 +4007,8 @@ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" + "chalk": "2.4.1", + "lodash": "4.17.10" }, "dependencies": { "ansi-styles": { @@ -4017,7 +4017,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.1" } }, "chalk": { @@ -4026,9 +4026,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" } }, "supports-color": { @@ -4037,7 +4037,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -4048,13 +4048,13 @@ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", "dev": true, "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" + "async": "1.5.2", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "4.17.10", + "underscore.string": "3.3.4", + "which": "1.3.1" } }, "grunt-newer": { @@ -4063,8 +4063,8 @@ "integrity": "sha1-g8y3od2ny9irI7BZAk6+YUrS80I=", "dev": true, "requires": { - "async": "^1.5.2", - "rimraf": "^2.5.2" + "async": "1.5.2", + "rimraf": "2.6.2" } }, "grunt-ng-annotate": { @@ -4073,8 +4073,8 @@ "integrity": "sha1-dqKiGha6Y+Vve+G3XuXErZMCeTk=", "dev": true, "requires": { - "lodash.clonedeep": "^4.5.0", - "ng-annotate": "^1.2.1" + "lodash.clonedeep": "4.5.0", + "ng-annotate": "1.2.2" } }, "gzip-size": { @@ -4083,8 +4083,8 @@ "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", "dev": true, "requires": { - "browserify-zlib": "^0.1.4", - "concat-stream": "^1.4.1" + "browserify-zlib": "0.1.4", + "concat-stream": "1.6.2" }, "dependencies": { "browserify-zlib": { @@ -4093,7 +4093,7 @@ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "requires": { - "pako": "~0.2.0" + "pako": "0.2.9" } }, "pako": { @@ -4116,8 +4116,8 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "has": { @@ -4126,7 +4126,7 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -4135,7 +4135,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-binary2": { @@ -4179,9 +4179,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4198,8 +4198,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -4208,7 +4208,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -4217,7 +4217,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4228,7 +4228,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4239,8 +4239,8 @@ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "hash.js": { @@ -4249,8 +4249,8 @@ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "hasha": { @@ -4259,8 +4259,8 @@ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", "dev": true, "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" } }, "hawk": { @@ -4270,10 +4270,10 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "he": { @@ -4288,8 +4288,8 @@ "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "hipchat-notifier": { @@ -4299,8 +4299,8 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.0.0", - "request": "^2.0.0" + "lodash": "4.17.10", + "request": "2.87.0" } }, "hmac-drbg": { @@ -4309,9 +4309,9 @@ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { @@ -4326,8 +4326,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "hooker": { @@ -4348,13 +4348,13 @@ "integrity": "sha1-kFHW/LvPIU7TB+GtdPQyu5rWVcw=", "dev": true, "requires": { - "change-case": "3.0.x", - "clean-css": "3.4.x", - "commander": "2.9.x", - "he": "1.1.x", - "ncname": "1.0.x", - "relateurl": "0.2.x", - "uglify-js": "2.6.x" + "change-case": "3.0.2", + "clean-css": "3.4.28", + "commander": "2.9.0", + "he": "1.1.1", + "ncname": "1.0.0", + "relateurl": "0.2.7", + "uglify-js": "2.6.4" }, "dependencies": { "commander": { @@ -4363,7 +4363,7 @@ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } } } @@ -4380,10 +4380,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "statuses": "1.5.0" } }, "http-parser-js": { @@ -4398,9 +4398,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "eventemitter3": "3.1.0", + "follow-redirects": "1.5.0", + "requires-port": "1.0.0" } }, "http-proxy-agent": { @@ -4409,7 +4409,7 @@ "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { - "agent-base": "4", + "agent-base": "4.2.1", "debug": "3.1.0" }, "dependencies": { @@ -4430,9 +4430,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "httpntlm": { @@ -4441,8 +4441,8 @@ "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", "dev": true, "requires": { - "httpreq": ">=0.4.22", - "underscore": "~1.7.0" + "httpreq": "0.4.24", + "underscore": "1.7.0" } }, "httpreq": { @@ -4463,8 +4463,8 @@ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" + "agent-base": "4.2.1", + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -4484,7 +4484,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "ieee754": { @@ -4499,7 +4499,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "indexof": { @@ -4521,8 +4521,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -4537,7 +4537,7 @@ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "requires": { - "source-map": "~0.5.3" + "source-map": "0.5.7" } }, "insert-module-globals": { @@ -4546,15 +4546,15 @@ "integrity": "sha512-LbYZdybvKjbbcKLp03lB323Cgc8f0iL0Rjh8U6JZ7K1gZSf7MxQH191iCNUcLX4qIQ6/yWe4Q4ZsQ+opcReNFg==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "lexical-scope": "^1.2.0", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "concat-stream": "1.6.2", + "is-buffer": "1.1.6", + "lexical-scope": "1.2.0", + "path-is-absolute": "1.0.1", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "invariant": { @@ -4563,7 +4563,7 @@ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "ip": { @@ -4578,7 +4578,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-arrayish": { @@ -4593,7 +4593,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -4608,7 +4608,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-data-descriptor": { @@ -4617,7 +4617,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-descriptor": { @@ -4626,9 +4626,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" }, "dependencies": { "kind-of": { @@ -4651,7 +4651,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -4672,7 +4672,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-glob": { @@ -4681,7 +4681,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-lower-case": { @@ -4690,7 +4690,7 @@ "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", "dev": true, "requires": { - "lower-case": "^1.1.0" + "lower-case": "1.1.4" } }, "is-my-ip-valid": { @@ -4707,11 +4707,11 @@ "dev": true, "optional": true, "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" + "generate-function": "2.3.1", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" } }, "is-number": { @@ -4720,7 +4720,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-plain-object": { @@ -4729,7 +4729,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4776,7 +4776,7 @@ "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", "dev": true, "requires": { - "upper-case": "^1.1.0" + "upper-case": "1.1.3" } }, "is-utf8": { @@ -4830,9 +4830,9 @@ "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=", "dev": true, "requires": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.99.0" + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.99.1" } }, "jasmine-core": { @@ -4853,8 +4853,8 @@ "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", "dev": true, "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0" + "argparse": "1.0.10", + "esprima": "2.7.3" } }, "jsbn": { @@ -4888,7 +4888,7 @@ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -4909,7 +4909,7 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -4949,31 +4949,31 @@ "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^2.0.3", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.4", - "log4js": "^2.5.3", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", + "bluebird": "3.5.1", + "body-parser": "1.18.3", + "chokidar": "2.0.4", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.6", + "core-js": "2.5.7", + "di": "0.0.1", + "dom-serialize": "2.2.1", + "expand-braces": "0.1.2", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "http-proxy": "1.17.0", + "isbinaryfile": "3.0.2", + "lodash": "4.17.10", + "log4js": "2.11.0", + "mime": "1.6.0", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.2.0", + "range-parser": "1.2.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.2", "socket.io": "2.0.4", - "source-map": "^0.6.1", + "source-map": "0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" }, @@ -4984,7 +4984,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, @@ -4994,8 +4994,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "micromatch": "3.1.10", + "normalize-path": "2.1.1" } }, "arr-diff": { @@ -5022,16 +5022,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" }, "dependencies": { "extend-shallow": { @@ -5040,7 +5040,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5051,19 +5051,19 @@ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.2.4", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" } }, "component-emitter": { @@ -5078,13 +5078,13 @@ "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { - "accepts": "~1.3.4", + "accepts": "1.3.5", "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", - "ws": "~3.3.1" + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" }, "dependencies": { "debug": { @@ -5106,14 +5106,14 @@ "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", "yeast": "0.1.2" }, "dependencies": { @@ -5135,10 +5135,10 @@ "dev": true, "requires": { "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", + "arraybuffer.slice": "0.0.7", "base64-arraybuffer": "0.1.5", "blob": "0.0.4", - "has-binary2": "~1.0.2" + "has-binary2": "1.0.3" } }, "expand-brackets": { @@ -5147,13 +5147,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5162,7 +5162,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -5171,7 +5171,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "is-accessor-descriptor": { @@ -5180,7 +5180,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5189,7 +5189,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5200,7 +5200,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5209,7 +5209,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5220,9 +5220,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" } }, "kind-of": { @@ -5239,14 +5239,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5255,7 +5255,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "extend-shallow": { @@ -5264,7 +5264,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5275,10 +5275,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" }, "dependencies": { "extend-shallow": { @@ -5287,7 +5287,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5298,8 +5298,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" }, "dependencies": { "is-glob": { @@ -5308,7 +5308,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } } } @@ -5319,7 +5319,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -5328,7 +5328,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -5337,9 +5337,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-extglob": { @@ -5354,7 +5354,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "is-extglob": "2.1.1" } }, "is-number": { @@ -5363,7 +5363,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5372,7 +5372,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5401,18 +5401,18 @@ "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", "dev": true, "requires": { - "amqplib": "^0.5.2", - "axios": "^0.15.3", - "circular-json": "^0.5.4", - "date-format": "^1.2.0", - "debug": "^3.1.0", - "hipchat-notifier": "^1.1.0", - "loggly": "^1.1.0", - "mailgun-js": "^0.18.0", - "nodemailer": "^2.5.0", - "redis": "^2.7.1", - "semver": "^5.5.0", - "slack-node": "~0.2.0", + "amqplib": "0.5.2", + "axios": "0.15.3", + "circular-json": "0.5.5", + "date-format": "1.2.0", + "debug": "3.1.0", + "hipchat-notifier": "1.1.0", + "loggly": "1.1.1", + "mailgun-js": "0.18.1", + "nodemailer": "2.7.2", + "redis": "2.8.0", + "semver": "5.5.0", + "slack-node": "0.2.0", "streamroller": "0.7.0" }, "dependencies": { @@ -5439,19 +5439,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.13", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "socket.io": { @@ -5460,11 +5460,11 @@ "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", "dev": true, "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", - "socket.io-adapter": "~1.1.0", + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", "socket.io-client": "2.0.4", - "socket.io-parser": "~3.1.1" + "socket.io-parser": "3.1.3" } }, "socket.io-adapter": { @@ -5483,14 +5483,14 @@ "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", + "debug": "2.6.9", + "engine.io-client": "3.1.6", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", + "socket.io-parser": "3.1.3", "to-array": "0.1.4" } }, @@ -5501,8 +5501,8 @@ "dev": true, "requires": { "component-emitter": "1.2.1", - "debug": "~3.1.0", - "has-binary2": "~1.0.2", + "debug": "3.1.0", + "has-binary2": "1.0.3", "isarray": "2.0.1" }, "dependencies": { @@ -5529,7 +5529,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "os-tmpdir": "1.0.2" } }, "ultron": { @@ -5544,8 +5544,8 @@ "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", "dev": true, "requires": { - "lru-cache": "2.2.x", - "tmp": "0.0.x" + "lru-cache": "2.2.4", + "tmp": "0.0.33" } }, "ws": { @@ -5554,9 +5554,9 @@ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "async-limiter": "1.0.0", + "safe-buffer": "5.1.2", + "ultron": "1.1.1" } }, "xmlhttprequest-ssl": { @@ -5573,7 +5573,7 @@ "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=", "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.1.7" } }, "karma-jasmine": { @@ -5588,8 +5588,8 @@ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", "dev": true, "requires": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" + "lodash": "4.17.10", + "phantomjs-prebuilt": "2.1.16" } }, "kew": { @@ -5604,7 +5604,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -5613,7 +5613,7 @@ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "labeled-stream-splicer": { @@ -5622,9 +5622,9 @@ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "isarray": "^2.0.4", - "stream-splicer": "^2.0.0" + "inherits": "2.0.3", + "isarray": "2.0.4", + "stream-splicer": "2.0.0" }, "dependencies": { "isarray": { @@ -5648,8 +5648,8 @@ "dev": true, "optional": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "lexical-scope": { @@ -5658,7 +5658,7 @@ "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", "dev": true, "requires": { - "astw": "^2.0.0" + "astw": "2.2.0" } }, "libbase64": { @@ -5704,11 +5704,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" } }, "lodash": { @@ -5742,9 +5742,9 @@ "dev": true, "optional": true, "requires": { - "json-stringify-safe": "5.0.x", - "request": "2.75.x", - "timespan": "2.3.x" + "json-stringify-safe": "5.0.1", + "request": "2.75.0", + "timespan": "2.3.0" }, "dependencies": { "assert-plus": { @@ -5775,9 +5775,9 @@ "dev": true, "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "har-validator": { @@ -5787,10 +5787,10 @@ "dev": true, "optional": true, "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" + "chalk": "1.1.3", + "commander": "2.15.1", + "is-my-json-valid": "2.19.0", + "pinkie-promise": "2.0.1" } }, "http-signature": { @@ -5800,9 +5800,9 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "qs": { @@ -5819,27 +5819,27 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.0.0", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.0.0", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "node-uuid": "1.4.8", + "oauth-sign": "0.8.2", + "qs": "6.2.3", + "stringstream": "0.0.6", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3" } }, "tunnel-agent": { @@ -5863,7 +5863,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.2" } }, "loud-rejection": { @@ -5872,8 +5872,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" } }, "lower-case": { @@ -5888,7 +5888,7 @@ "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", "dev": true, "requires": { - "lower-case": "^1.1.2" + "lower-case": "1.1.4" } }, "lru-cache": { @@ -5915,15 +5915,15 @@ "dev": true, "optional": true, "requires": { - "async": "~2.6.0", - "debug": "~3.1.0", - "form-data": "~2.3.0", - "inflection": "~1.12.0", - "is-stream": "^1.1.0", - "path-proxy": "~1.0.0", - "promisify-call": "^2.0.2", - "proxy-agent": "~3.0.0", - "tsscmp": "~1.0.0" + "async": "2.6.1", + "debug": "3.1.0", + "form-data": "2.3.2", + "inflection": "1.12.0", + "is-stream": "1.1.0", + "path-proxy": "1.0.0", + "promisify-call": "2.0.4", + "proxy-agent": "3.0.1", + "tsscmp": "1.0.6" }, "dependencies": { "async": { @@ -5933,7 +5933,7 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } }, "debug": { @@ -5966,7 +5966,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "^1.0.0" + "object-visit": "1.0.1" } }, "math-random": { @@ -5981,10 +5981,10 @@ "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", "dev": true, "requires": { - "chalk": "^1.0.0", - "figures": "^1.0.1", - "gzip-size": "^1.0.0", - "pretty-bytes": "^1.0.0" + "chalk": "1.1.3", + "figures": "1.7.0", + "gzip-size": "1.0.0", + "pretty-bytes": "1.0.4" } }, "md5.js": { @@ -5993,8 +5993,8 @@ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "media-typer": { @@ -6009,16 +6009,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" }, "dependencies": { "minimist": { @@ -6035,19 +6035,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" } }, "miller-rabin": { @@ -6056,8 +6056,8 @@ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "bn.js": "4.11.8", + "brorand": "1.1.0" } }, "mime": { @@ -6078,7 +6078,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" } }, "minimalistic-assert": { @@ -6099,7 +6099,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -6114,8 +6114,8 @@ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "for-in": "1.0.2", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -6124,7 +6124,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -6172,7 +6172,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -6183,21 +6183,21 @@ "integrity": "sha512-NPs5N511VD1rrVJihSso/LiBShRbJALYBKzDW91uZYy7BpjnO4bGnZL3HjZ9yKcFdZUWwaYjDz9zxbuP7vKMuQ==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.0", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.0.2", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "defined": "1.0.0", + "detective": "5.1.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.6", + "resolve": "1.7.1", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "resolve": { @@ -6206,7 +6206,7 @@ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } } } @@ -6230,17 +6230,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "arr-diff": { @@ -6269,7 +6269,7 @@ "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", "dev": true, "requires": { - "xml-char-classes": "^1.0.0" + "xml-char-classes": "1.0.0" } }, "negotiator": { @@ -6291,18 +6291,18 @@ "integrity": "sha1-3D/FG6Cy+LOF2+BH9NoG9YCh/WE=", "dev": true, "requires": { - "acorn": "~2.6.4", - "alter": "~0.2.0", - "convert-source-map": "~1.1.2", - "optimist": "~0.6.1", - "ordered-ast-traverse": "~1.1.1", - "simple-fmt": "~0.1.0", - "simple-is": "~0.2.0", - "source-map": "~0.5.3", - "stable": "~0.1.5", - "stringmap": "~0.2.2", - "stringset": "~0.2.1", - "tryor": "~0.1.2" + "acorn": "2.6.4", + "alter": "0.2.0", + "convert-source-map": "1.1.3", + "optimist": "0.6.1", + "ordered-ast-traverse": "1.1.1", + "simple-fmt": "0.1.0", + "simple-is": "0.2.0", + "source-map": "0.5.7", + "stable": "0.1.8", + "stringmap": "0.2.2", + "stringset": "0.2.1", + "tryor": "0.1.2" }, "dependencies": { "acorn": { @@ -6325,7 +6325,7 @@ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "1.1.4" } }, "node-uuid": { @@ -6358,8 +6358,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.2", - "smart-buffer": "^1.0.4" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } } } @@ -6426,7 +6426,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.1.1" } }, "normalize-package-data": { @@ -6435,10 +6435,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -6447,7 +6447,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.1.0" } }, "number-is-nan": { @@ -6480,9 +6480,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" }, "dependencies": { "define-property": { @@ -6491,7 +6491,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -6508,7 +6508,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "^3.0.0" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6525,10 +6525,10 @@ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "has-symbols": "1.0.0", + "object-keys": "1.0.11" } }, "object.omit": { @@ -6537,8 +6537,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "object.pick": { @@ -6547,7 +6547,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6573,7 +6573,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "optimist": { @@ -6582,8 +6582,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.2" } }, "optionator": { @@ -6593,12 +6593,12 @@ "dev": true, "optional": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" }, "dependencies": { "wordwrap": { @@ -6616,7 +6616,7 @@ "integrity": "sha1-aEOhcLwO7otSDMjdwd3TqjD6BXw=", "dev": true, "requires": { - "ordered-esprima-props": "~1.1.0" + "ordered-esprima-props": "1.1.0" } }, "ordered-esprima-props": { @@ -6649,7 +6649,7 @@ "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", "dev": true, "requires": { - "shell-quote": "^1.4.2" + "shell-quote": "1.6.1" } }, "output-file-sync": { @@ -6658,9 +6658,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" } }, "pac-proxy-agent": { @@ -6670,14 +6670,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^3.0.0" + "agent-base": "4.2.1", + "debug": "3.1.0", + "get-uri": "2.0.2", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "pac-resolver": "3.0.0", + "raw-body": "2.3.3", + "socks-proxy-agent": "3.0.1" }, "dependencies": { "bytes": { @@ -6717,8 +6717,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" + "agent-base": "4.2.1", + "socks": "1.1.10" } } } @@ -6730,11 +6730,11 @@ "dev": true, "optional": true, "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" + "co": "4.6.0", + "degenerator": "1.0.4", + "ip": "1.1.5", + "netmask": "1.0.6", + "thunkify": "2.1.2" } }, "pako": { @@ -6749,7 +6749,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "parents": { @@ -6758,7 +6758,7 @@ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "requires": { - "path-platform": "~0.11.15" + "path-platform": "0.11.15" } }, "parse-asn1": { @@ -6767,11 +6767,11 @@ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.16" } }, "parse-glob": { @@ -6780,10 +6780,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-json": { @@ -6792,7 +6792,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "parseqs": { @@ -6801,7 +6801,7 @@ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseuri": { @@ -6810,7 +6810,7 @@ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseurl": { @@ -6825,8 +6825,8 @@ "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", "dev": true, "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "upper-case-first": "1.1.2" } }, "pascalcase": { @@ -6847,7 +6847,7 @@ "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "path-dirname": { @@ -6862,7 +6862,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-is-absolute": { @@ -6890,7 +6890,7 @@ "dev": true, "optional": true, "requires": { - "inflection": "~1.3.0" + "inflection": "1.3.8" }, "dependencies": { "inflection": { @@ -6908,9 +6908,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pathval": { @@ -6925,11 +6925,11 @@ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "pend": { @@ -6950,15 +6950,15 @@ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", "dev": true, "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" + "es6-promise": "4.2.4", + "extract-zip": "1.6.7", + "fs-extra": "1.0.0", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.87.0", + "request-progress": "2.0.1", + "which": "1.3.1" } }, "pify": { @@ -6979,7 +6979,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "posix-character-classes": { @@ -7006,8 +7006,8 @@ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.1.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "private": { @@ -7041,7 +7041,7 @@ "dev": true, "optional": true, "requires": { - "with-callback": "^1.0.2" + "with-callback": "1.0.2" } }, "proxy-agent": { @@ -7051,14 +7051,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^2.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" + "agent-base": "4.2.1", + "debug": "3.1.0", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "lru-cache": "4.1.3", + "pac-proxy-agent": "2.0.2", + "proxy-from-env": "1.0.0", + "socks-proxy-agent": "4.0.1" }, "dependencies": { "debug": { @@ -7078,8 +7078,8 @@ "dev": true, "optional": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pseudomap": "1.0.2", + "yallist": "2.1.2" } } } @@ -7104,11 +7104,11 @@ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", + "randombytes": "2.0.6" } }, "punycode": { @@ -7147,9 +7147,9 @@ "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "dev": true, "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { "is-number": { @@ -7172,7 +7172,7 @@ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "safe-buffer": "5.1.2" } }, "randomfill": { @@ -7181,8 +7181,8 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "randombytes": "2.0.6", + "safe-buffer": "5.1.2" } }, "range-parser": { @@ -7197,8 +7197,8 @@ "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { - "bytes": "1", - "string_decoder": "0.10" + "bytes": "1.0.0", + "string_decoder": "0.10.31" }, "dependencies": { "string_decoder": { @@ -7215,7 +7215,7 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "read-pkg": { @@ -7224,9 +7224,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -7235,8 +7235,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "readable-stream": { @@ -7245,13 +7245,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -7260,10 +7260,10 @@ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.6", + "set-immediate-shim": "1.0.1" } }, "redent": { @@ -7272,8 +7272,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "2.1.0", + "strip-indent": "1.0.1" } }, "redis": { @@ -7283,9 +7283,9 @@ "dev": true, "optional": true, "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.5", + "redis-parser": "2.6.0" } }, "redis-commands": { @@ -7320,9 +7320,9 @@ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" } }, "regex-cache": { @@ -7331,7 +7331,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3" + "is-equal-shallow": "0.1.3" } }, "regex-not": { @@ -7340,8 +7340,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "regexpu-core": { @@ -7350,9 +7350,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -7367,7 +7367,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" }, "dependencies": { "jsesc": { @@ -7408,7 +7408,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "request": { @@ -7417,26 +7417,26 @@ "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "dev": true, "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" } }, "request-progress": { @@ -7445,7 +7445,7 @@ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", "dev": true, "requires": { - "throttleit": "^1.0.0" + "throttleit": "1.0.0" } }, "requestretry": { @@ -7455,10 +7455,10 @@ "dev": true, "optional": true, "requires": { - "extend": "^3.0.0", - "lodash": "^4.15.0", - "request": "^2.74.0", - "when": "^3.7.7" + "extend": "3.0.1", + "lodash": "4.17.10", + "request": "2.87.0", + "when": "3.7.8" } }, "requires-port": { @@ -7491,7 +7491,7 @@ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -7500,7 +7500,7 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "ripemd160": { @@ -7509,8 +7509,8 @@ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "safe-buffer": { @@ -7531,7 +7531,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "~0.1.10" + "ret": "0.1.15" } }, "safer-buffer": { @@ -7553,18 +7553,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" }, "dependencies": { "mime": { @@ -7587,8 +7587,8 @@ "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" + "no-case": "2.3.2", + "upper-case-first": "1.1.2" } }, "serve-static": { @@ -7597,9 +7597,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.2" } }, @@ -7615,10 +7615,10 @@ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" }, "dependencies": { "extend-shallow": { @@ -7627,7 +7627,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7644,8 +7644,8 @@ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "shasum": { @@ -7654,8 +7654,8 @@ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.11" } }, "shell-quote": { @@ -7664,10 +7664,10 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" } }, "signal-exit": { @@ -7695,7 +7695,7 @@ "dev": true, "optional": true, "requires": { - "requestretry": "^1.2.2" + "requestretry": "1.13.0" } }, "slash": { @@ -7728,10 +7728,882 @@ "dev": true }, "sn-stylekit": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-1.0.15.tgz", - "integrity": "sha512-QeWlaCMHtF/VhFWWICzmx39ger92DEj1uLiCW4VVLX9LtU7nKQ5plqHgrpvnctO+wNh9LIYdPBLLWxTwgXm6Eg==", - "dev": true + "version": "file:../stylekit", + "dev": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true + }, + "argparse": { + "version": "1.0.9", + "bundled": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-find-index": { + "version": "1.0.2", + "bundled": true + }, + "async": { + "version": "1.5.2", + "bundled": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "body-parser": { + "version": "1.14.2", + "bundled": true, + "requires": { + "bytes": "2.2.0", + "content-type": "1.0.4", + "debug": "2.2.0", + "depd": "1.1.1", + "http-errors": "1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "2.3.0", + "qs": "5.2.0", + "raw-body": "2.1.7", + "type-is": "1.6.15" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "bundled": true, + "requires": { + "ms": "0.7.1" + } + }, + "iconv-lite": { + "version": "0.4.13", + "bundled": true + }, + "ms": { + "version": "0.7.1", + "bundled": true + }, + "qs": { + "version": "5.2.0", + "bundled": true + } + } + }, + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true + }, + "bytes": { + "version": "2.2.0", + "bundled": true + }, + "camelcase": { + "version": "2.1.1", + "bundled": true + }, + "camelcase-keys": { + "version": "2.1.0", + "bundled": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "coffee-script": { + "version": "1.10.0", + "bundled": true + }, + "colors": { + "version": "1.1.2", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "content-type": { + "version": "1.0.4", + "bundled": true + }, + "cross-spawn": { + "version": "0.2.9", + "bundled": true, + "requires": { + "lru-cache": "2.7.3" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "bundled": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "dargs": { + "version": "4.1.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "dateformat": { + "version": "1.0.12", + "bundled": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true + }, + "depd": { + "version": "1.1.1", + "bundled": true + }, + "ee-first": { + "version": "1.1.1", + "bundled": true + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "esprima": { + "version": "2.7.3", + "bundled": true + }, + "eventemitter2": { + "version": "0.4.14", + "bundled": true + }, + "exit": { + "version": "0.1.2", + "bundled": true + }, + "faye-websocket": { + "version": "0.10.0", + "bundled": true, + "requires": { + "websocket-driver": "0.7.0" + } + }, + "find-up": { + "version": "1.1.2", + "bundled": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "findup-sync": { + "version": "0.3.0", + "bundled": true, + "requires": { + "glob": "5.0.15" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "bundled": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gaze": { + "version": "1.1.2", + "bundled": true, + "requires": { + "globule": "1.2.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "bundled": true + }, + "getobject": { + "version": "0.1.0", + "bundled": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globule": { + "version": "1.2.0", + "bundled": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4", + "minimatch": "3.0.4" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "grunt": { + "version": "1.0.1", + "bundled": true, + "requires": { + "coffee-script": "1.10.0", + "dateformat": "1.0.12", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.3.0", + "glob": "7.0.6", + "grunt-cli": "1.2.0", + "grunt-known-options": "1.1.0", + "grunt-legacy-log": "1.0.0", + "grunt-legacy-util": "1.0.0", + "iconv-lite": "0.4.19", + "js-yaml": "3.5.5", + "minimatch": "3.0.4", + "nopt": "3.0.6", + "path-is-absolute": "1.0.1", + "rimraf": "2.2.8" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "bundled": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "grunt-cli": { + "version": "1.2.0", + "bundled": true, + "requires": { + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.0", + "nopt": "3.0.6", + "resolve": "1.1.7" + } + } + } + }, + "grunt-contrib-sass": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "0.9.2", + "chalk": "1.1.3", + "cross-spawn": "0.2.9", + "dargs": "4.1.0", + "which": "1.2.14" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "bundled": true + } + } + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "1.5.2", + "gaze": "1.1.2", + "lodash": "3.10.1", + "tiny-lr": "0.2.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "bundled": true + } + } + }, + "grunt-haml2html": { + "version": "0.3.1", + "bundled": true, + "requires": { + "dargs": "0.1.0" + }, + "dependencies": { + "dargs": { + "version": "0.1.0", + "bundled": true + } + } + }, + "grunt-known-options": { + "version": "1.1.0", + "bundled": true + }, + "grunt-legacy-log": { + "version": "1.0.0", + "bundled": true, + "requires": { + "colors": "1.1.2", + "grunt-legacy-log-utils": "1.0.0", + "hooker": "0.2.3", + "lodash": "3.10.1", + "underscore.string": "3.2.3" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "bundled": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "1.0.0", + "bundled": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.3.0" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "bundled": true + } + } + }, + "grunt-legacy-util": { + "version": "1.0.0", + "bundled": true, + "requires": { + "async": "1.5.2", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "4.3.0", + "underscore.string": "3.2.3", + "which": "1.2.14" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "bundled": true + } + } + }, + "grunt-newer": { + "version": "1.3.0", + "bundled": true, + "requires": { + "async": "1.5.2", + "rimraf": "2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.2", + "bundled": true, + "requires": { + "glob": "7.1.2" + } + } + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "hooker": { + "version": "0.2.3", + "bundled": true + }, + "hosted-git-info": { + "version": "2.5.0", + "bundled": true + }, + "http-errors": { + "version": "1.3.1", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "statuses": "1.4.0" + } + }, + "http-parser-js": { + "version": "0.4.9", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.19", + "bundled": true + }, + "indent-string": { + "version": "2.1.0", + "bundled": true, + "requires": { + "repeating": "2.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-finite": { + "version": "1.0.2", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true + }, + "js-yaml": { + "version": "3.5.5", + "bundled": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "livereload-js": { + "version": "2.2.2", + "bundled": true + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "bundled": true + }, + "loud-rejection": { + "version": "1.6.0", + "bundled": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "2.7.3", + "bundled": true + }, + "map-obj": { + "version": "1.0.1", + "bundled": true + }, + "media-typer": { + "version": "0.3.0", + "bundled": true + }, + "meow": { + "version": "3.7.0", + "bundled": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true + } + } + }, + "mime-db": { + "version": "1.30.0", + "bundled": true + }, + "mime-types": { + "version": "2.1.17", + "bundled": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "on-finished": { + "version": "2.3.0", + "bundled": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parseurl": { + "version": "1.3.2", + "bundled": true + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "bundled": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "qs": { + "version": "5.1.0", + "bundled": true + }, + "raw-body": { + "version": "2.1.7", + "bundled": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.13", + "bundled": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "redent": { + "version": "1.0.0", + "bundled": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "repeating": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "resolve": { + "version": "1.1.7", + "bundled": true + }, + "rimraf": { + "version": "2.2.8", + "bundled": true + }, + "semver": { + "version": "5.4.1", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true + }, + "sprintf-js": { + "version": "1.0.3", + "bundled": true + }, + "statuses": { + "version": "1.4.0", + "bundled": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "bundled": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "supports-color": { + "version": "2.0.0", + "bundled": true + }, + "tiny-lr": { + "version": "0.2.1", + "bundled": true, + "requires": { + "body-parser": "1.14.2", + "debug": "2.2.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.2.2", + "parseurl": "1.3.2", + "qs": "5.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "bundled": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "bundled": true + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "bundled": true + }, + "type-is": { + "version": "1.6.15", + "bundled": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "underscore.string": { + "version": "3.2.3", + "bundled": true + }, + "unpipe": { + "version": "1.0.0", + "bundled": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "websocket-driver": { + "version": "0.7.0", + "bundled": true, + "requires": { + "http-parser-js": "0.4.9", + "websocket-extensions": "0.1.2" + } + }, + "websocket-extensions": { + "version": "0.1.2", + "bundled": true + }, + "which": { + "version": "1.2.14", + "bundled": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + } + } }, "snake-case": { "version": "2.1.0", @@ -7739,7 +8611,7 @@ "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "snapdragon": { @@ -7748,14 +8620,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.1" }, "dependencies": { "define-property": { @@ -7764,7 +8636,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -7773,7 +8645,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7784,9 +8656,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" }, "dependencies": { "define-property": { @@ -7795,7 +8667,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -7804,7 +8676,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -7813,7 +8685,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -7822,9 +8694,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -7847,7 +8719,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "^3.2.0" + "kind-of": "3.2.2" } }, "sntp": { @@ -7857,7 +8729,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "socks": { @@ -7867,8 +8739,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } }, "socks-proxy-agent": { @@ -7878,8 +8750,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" + "agent-base": "4.2.1", + "socks": "2.2.1" }, "dependencies": { "smart-buffer": { @@ -7896,8 +8768,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" + "ip": "1.1.5", + "smart-buffer": "4.0.1" } } } @@ -7914,11 +8786,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "atob": "2.1.2", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" } }, "source-map-support": { @@ -7927,7 +8799,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.7" } }, "source-map-url": { @@ -7942,8 +8814,8 @@ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, "spdx-exceptions": { @@ -7958,8 +8830,8 @@ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" } }, "spdx-license-ids": { @@ -7974,7 +8846,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "^3.0.0" + "extend-shallow": "3.0.2" } }, "sprintf-js": { @@ -7989,14 +8861,14 @@ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" } }, "stable": { @@ -8017,8 +8889,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "define-property": "0.2.5", + "object-copy": "0.1.0" }, "dependencies": { "define-property": { @@ -8027,7 +8899,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -8044,8 +8916,8 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "stream-combiner2": { @@ -8054,8 +8926,8 @@ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" + "duplexer2": "0.1.4", + "readable-stream": "2.3.6" } }, "stream-http": { @@ -8064,11 +8936,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" } }, "stream-splicer": { @@ -8077,8 +8949,8 @@ "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "streamroller": { @@ -8087,10 +8959,10 @@ "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { - "date-format": "^1.2.0", - "debug": "^3.1.0", - "mkdirp": "^0.5.1", - "readable-stream": "^2.3.0" + "date-format": "1.2.0", + "debug": "3.1.0", + "mkdirp": "0.5.1", + "readable-stream": "2.3.6" }, "dependencies": { "debug": { @@ -8116,7 +8988,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } }, "stringmap": { @@ -8144,7 +9016,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -8153,7 +9025,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "strip-indent": { @@ -8162,7 +9034,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "^4.0.1" + "get-stdin": "4.0.1" } }, "subarg": { @@ -8171,7 +9043,7 @@ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "requires": { - "minimist": "^1.1.0" + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -8194,8 +9066,8 @@ "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", "dev": true, "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" + "lower-case": "1.1.4", + "upper-case": "1.1.3" } }, "syntax-error": { @@ -8204,7 +9076,7 @@ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "requires": { - "acorn-node": "^1.2.0" + "acorn-node": "1.3.0" } }, "throttleit": { @@ -8225,8 +9097,8 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "readable-stream": "2.3.6", + "xtend": "4.0.1" } }, "thunkify": { @@ -8242,7 +9114,7 @@ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "requires": { - "process": "~0.11.0" + "process": "0.11.10" } }, "timespan": { @@ -8258,12 +9130,12 @@ "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" + "body": "5.1.0", + "debug": "3.1.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.3.0", + "object-assign": "4.1.1", + "qs": "6.5.2" }, "dependencies": { "debug": { @@ -8283,8 +9155,8 @@ "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "to-array": { @@ -8311,7 +9183,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "to-regex": { @@ -8320,10 +9192,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -8332,8 +9204,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "3.0.0", + "repeat-string": "1.6.1" }, "dependencies": { "is-number": { @@ -8342,7 +9214,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } } } @@ -8353,7 +9225,7 @@ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "trim-newlines": { @@ -8393,7 +9265,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "tweetnacl": { @@ -8409,7 +9281,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-detect": { @@ -8425,7 +9297,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" } }, "typedarray": { @@ -8440,10 +9312,10 @@ "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "async": "0.2.10", + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" }, "dependencies": { "async": { @@ -8478,8 +9350,8 @@ "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=", "dev": true, "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" + "sprintf-js": "1.1.1", + "util-deprecate": "1.0.2" } }, "union-value": { @@ -8488,10 +9360,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" }, "dependencies": { "extend-shallow": { @@ -8500,7 +9372,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "set-value": { @@ -8509,10 +9381,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" } } } @@ -8529,8 +9401,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "has-value": "0.3.1", + "isobject": "3.0.1" }, "dependencies": { "has-value": { @@ -8539,9 +9411,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" }, "dependencies": { "isobject": { @@ -8587,7 +9459,7 @@ "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", "dev": true, "requires": { - "upper-case": "^1.1.1" + "upper-case": "1.1.3" } }, "uri-path": { @@ -8672,7 +9544,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "^1.1.1" + "user-home": "1.1.1" } }, "validate-npm-package-license": { @@ -8681,8 +9553,8 @@ "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "verror": { @@ -8691,9 +9563,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "^1.0.0", + "assert-plus": "1.0.0", "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "extsprintf": "1.3.0" } }, "vm-browserify": { @@ -8714,13 +9586,13 @@ "integrity": "sha512-7jWG0c3cKKm2hKScnSAMUEUjRJKXUShwMPk0ASVhICycQhwND3IMAdhJYmc1mxxKzBUJTSF5HZizfrKrS6BzkA==", "dev": true, "requires": { - "anymatch": "^1.3.0", - "browserify": "^16.1.0", - "chokidar": "^1.0.0", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "anymatch": "1.3.2", + "browserify": "16.2.2", + "chokidar": "1.7.0", + "defined": "1.0.0", + "outpipe": "1.1.1", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "websocket-driver": { @@ -8729,8 +9601,8 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" + "http-parser-js": "0.4.13", + "websocket-extensions": "0.1.3" } }, "websocket-extensions": { @@ -8752,7 +9624,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "window-size": { @@ -8812,9 +9684,9 @@ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" }, "dependencies": { @@ -8832,7 +9704,7 @@ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "fd-slicer": "1.0.1" } }, "yeast": { diff --git a/package.json b/package.json index 7c64b522a..7eee54851 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "1.0.15", + "sn-stylekit": "file:~/Desktop/sn/dev/stylekit", "standard-file-js": "0.3.19" } } diff --git a/public/extensions/batch-manager b/public/extensions/batch-manager index c05c78303..3c8a9ffd7 160000 --- a/public/extensions/batch-manager +++ b/public/extensions/batch-manager @@ -1 +1 @@ -Subproject commit c05c78303875de567585330b3db2716b9e8103d0 +Subproject commit 3c8a9ffd7c8fc8d3d04c258d3e5fddb0633a74b9 From c0e702805c52175c2a017133429203eb419585f6 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 7 Dec 2018 18:59:28 -0600 Subject: [PATCH 14/62] Style cleanup --- app/assets/stylesheets/app/_editor.scss | 23 ++- app/assets/stylesheets/app/_lock-screen.scss | 4 +- app/assets/stylesheets/app/_main.scss | 53 ++--- app/assets/stylesheets/app/_modals.scss | 30 ++- app/assets/stylesheets/app/_notes.scss | 29 ++- app/assets/stylesheets/app/_stylekit-sub.scss | 4 +- app/assets/stylesheets/app/_tags.scss | 39 +--- .../conflict-resolution-modal.html.haml | 9 +- .../directives/input-modal.html.haml | 36 ++-- .../directives/password-wizard.html.haml | 186 +++++++++--------- .../revision-preview-modal.html.haml | 28 +-- app/assets/templates/editor.html.haml | 4 +- app/assets/templates/notes.html.haml | 5 +- app/assets/templates/tags.html.haml | 5 +- 14 files changed, 209 insertions(+), 246 deletions(-) diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 0d4f3b225..5cf5f3d6f 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -4,7 +4,7 @@ $heading-height: 75px; display: flex; flex-direction: column; overflow-y: hidden; - background-color: white; + background-color: var(--sn-stylekit-background-color); } .locked { @@ -19,7 +19,6 @@ $heading-height: 75px; padding-bottom: 10px; padding-right: 10px; - background-color: white; border-bottom: none; z-index: $z-index-editor-title-bar; @@ -41,9 +40,10 @@ $heading-height: 75px; border: none; outline: none; background-color: transparent; + color: var(--sn-stylekit-foreground-color); &:disabled { - color: black; + color: var(--sn-stylekit-foreground-color); } } @@ -60,17 +60,12 @@ $heading-height: 75px; font-weight: normal; margin-top: 4px; text-align: right; - color: rgba(black, 0.23); - - &.error, .error { - color: #f6a200; - } + color: var(--sn-stylekit-contrast-background-color); } .editor-tags { clear: left; width: 100%; - // height: 25px; overflow: visible; position: relative; @@ -88,6 +83,7 @@ $heading-height: 75px; .tags-input { background-color: transparent; + color: var(--sn-stylekit-foreground-color); width: 100%; border: none; } @@ -100,7 +96,7 @@ $heading-height: 75px; overflow-y: hidden; height: 100%; display: flex; - background-color: white; + background-color: var(--sn-stylekit-background-color); position: relative; @@ -113,12 +109,14 @@ $heading-height: 75px; font-family: monospace; overflow-y: scroll; width: 100%; + background-color: var(--sn-stylekit-background-color); + color: var(--sn-stylekit-foreground-color); border: none; outline: none; padding: 15px; padding-top: 11px; - font-size: 17px; + font-size: var(--sn-stylekit-font-size-editor); resize: none; } } @@ -129,7 +127,8 @@ $heading-height: 75px; .component-stack-item { width: 100%; position: relative; - border-top: 1px solid $bg-color; + border-top: 1px solid var(--sn-stylekit-border-color); + iframe { width: 100%; } diff --git a/app/assets/stylesheets/app/_lock-screen.scss b/app/assets/stylesheets/app/_lock-screen.scss index 605ded806..4a7f57b66 100644 --- a/app/assets/stylesheets/app/_lock-screen.scss +++ b/app/assets/stylesheets/app/_lock-screen.scss @@ -12,8 +12,8 @@ bottom: 0; z-index: $z-index-lock-screen; - background-color: rgba(white, 0.5); - color: black; + background-color: var(--sn-stylekit-background-color); + color: var(--sn-stylekit-foreground-color); font-size: 16px; display: flex; align-items: center; diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index c4f412b3b..329437ee2 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -1,11 +1,3 @@ -$main-text-color: black; -$secondary-text-color: rgba($main-text-color, 0.8); -$bg-color: #e3e3e3; -$light-bg-color: #e9e9e9; -$selection-color: $bg-color; -$selected-text-color: black; -$blue-color: #086dd6; - $z-index-editor-content: 10; $z-index-editor-title-bar: 100; @@ -27,13 +19,13 @@ body { "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: $main-text-color; -webkit-font-smoothing: antialiased; min-height: 100%; height: 100%; font-size: 14px; margin: 0; - background-color: $bg-color; + color: var(--sn-stylekit-foreground-color); + background-color: var(--sn-stylekit-background-color); } * { @@ -41,11 +33,11 @@ body { } .tinted { - color: $blue-color; + color: var(--sn-stylekit-info-color); } .tinted-selected { - color: white; + color: var(--sn-stylekit-info-contrast-color); } *:focus {outline:0;} @@ -61,7 +53,7 @@ input, button, select, textarea { } a { - color: $blue-color; + color: var(--sn-stylekit-info-color); text-decoration: none; &.no-decoration { @@ -77,6 +69,16 @@ a { } } +::selection { + background: var(--sn-stylekit-info-color) !important; /* WebKit/Blink Browsers */ + color: var(--sn-stylekit-info-contrast-color); +} + +::-moz-selection { + background: var(--sn-stylekit-text-selection-color) !important; /* WebKit/Blink Browsers */ + color: white; +} + p { overflow: auto; } @@ -85,7 +87,7 @@ p { min-height: 100vh; height: 100vh; overflow: auto; - background-color: $bg-color; + background-color: var(--sn-stylekit-background-color); } $footer-height: 32px; @@ -115,7 +117,8 @@ $footer-height: 32px; height: 100%; position: absolute; cursor: col-resize; - background-color: rgba(black, 0.1); + // needs to be a color that works on main bg and contrast bg + background-color: var(--sn-stylekit-on-contrast-background-color); opacity: 0; border-top: none; border-bottom: none; @@ -181,7 +184,7 @@ $footer-height: 32px; > .content { height: 100%; max-height: 100%; - background-color: white; + background-color: var(--sn-stylekit-background-color); position: relative; } @@ -205,24 +208,6 @@ $footer-height: 32px; width: 80%; overflow: hidden; } - - > .add-button { - $button-bg: #e9e9e9; - color: lighten($main-text-color, 40%); - font-size: 18px; - width: 45px; - height: 24px; - cursor: pointer; - background-color: $button-bg; - border-radius: 4px; - font-weight: normal; - text-align: center; - - &:hover { - background-color: darken($button-bg, 5%); - color: lighten($main-text-color, 40%); - } - } } } } diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 411bf237c..3623f719d 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -2,7 +2,6 @@ width: 350px; .sk-panel { border-radius: 0; - background-color: white; } .sk-panel-content { padding-top: 1.1rem; @@ -17,7 +16,7 @@ } #item-preview-modal { - > .content { + > .sk-modal-content { width: 800px; height: 500px; } @@ -37,21 +36,17 @@ .border { height: 100%; - background-color: rgba(black, 0.1); + background-color: var(--sn-stylekit-border-color); width: 1px; margin: 0 15px; } } -// .sk-panel { -// background-color: white; -// } - .header .subtitle { font-size: 1.1rem; } -.modal { +.sk-modal { position: fixed; margin-left: auto; margin-right: auto; @@ -62,8 +57,9 @@ z-index: $z-index-modal; width: 100vw; height: 100vh; - background-color: rgba(gray, 0.3); - color: black; + + background-color: transparent; + color: var(--sn-stylekit-contrast-foreground-color); display: flex; align-items: center; justify-content: center; @@ -76,40 +72,42 @@ } &.auto-height { - > .content { + > .sk-modal-content { height: auto !important; } } &.large { - > .content { + > .sk-modal-content { width: 900px; height: 600px; } } &.medium { - > .content { + > .sk-modal-content { width: 700px; height: 500px; } } &.small { - > .content { + > .sk-modal-content { width: 700px; height: 344px; } } - .background { + .sk-modal-background { position: absolute; z-index: -1; width: 100%; height: 100%; + background-color: var(--sn-stylekit-contrast-background-color); + opacity: 0.7; } - > .content { + > .sk-modal-content { overflow-y: auto; width: auto; padding: 0; diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index e3c4a4647..c880e1057 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -1,6 +1,6 @@ #notes-column, .notes { - border-left: 1px solid #dddddd; - border-right: 1px solid #dddddd; + border-left: 1px solid var(--sn-stylekit-border-color); + border-right: 1px solid var(--sn-stylekit-border-color); width: 350px; flex-grow: 0; @@ -21,15 +21,11 @@ font-size: 18px; .section-title-bar-header .title { - color: rgba(black, 0.40); + color: var(--sn-stylekit-neutral-color); width: calc(90% - 45px); } } - #notes-add-button { - - } - #notes-menu-bar { position: relative; margin-top: 14px; @@ -42,7 +38,7 @@ position: relative; .filter-bar { - background-color: $light-bg-color; + background-color: var(--sn-stylekit-contrast-background-color); border-radius: 4px; height: 100%; color: #909090; @@ -60,9 +56,9 @@ border-radius: 50%; width: 17px; height: 17px; - color: white; cursor: default; - background-color: gray; + background-color: var(--sn-stylekit-neutral-color); + color: var(--sn-stylekit-neutral-contrast-color); font-size: 10px; line-height: 17px; text-align: center; @@ -73,7 +69,7 @@ transition: background-color 0.15s linear; &:hover { - background-color: $blue-color; + background-color: var(--sn-stylekit-info-color); } } } @@ -102,9 +98,8 @@ .note { width: 100%; padding: 15px; - border-bottom: 1px solid $bg-color; + border-bottom: 1px solid var(--sn-stylekit-border-color); cursor: pointer; - background-color: white; > .name { font-weight: 600; @@ -137,11 +132,11 @@ overflow: hidden; text-overflow: ellipsis; - $line-height: 18px; .default-preview, .plain-preview { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; /* number of lines to show */ + $line-height: 18px; line-height: $line-height; /* fallback */ max-height: calc(#{$line-height} * 1); /* fallback */ } @@ -159,11 +154,11 @@ } &.selected { - background-color: $blue-color; - color: white; + background-color: var(--sn-stylekit-info-color); + color: var(--sn-stylekit-info-contrast-color); .pinned { - color: white; + color: var(--sn-stylekit-info-contrast-color); } } diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index 307b2beaa..77a666bc0 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -12,8 +12,8 @@ } .bordered-row { - border-bottom: 1px solid rgba(black, 0.1); - border-top: 1px solid rgba(black, 0.1); + border-bottom: 1px solid var(--sn-stylekit-border-color); + border-top: 1px solid var(--sn-stylekit-border-color); } } diff --git a/app/assets/stylesheets/app/_tags.scss b/app/assets/stylesheets/app/_tags.scss index 45a849be6..c23d15108 100644 --- a/app/assets/stylesheets/app/_tags.scss +++ b/app/assets/stylesheets/app/_tags.scss @@ -6,27 +6,18 @@ -webkit-user-select: none; &, #tags-content { - background-color: #f6f6f6; + background-color: var(--sn-stylekit-secondary-background-color); display: flex; flex-direction: column; } #tags-title-bar { - color: black; + color: var(--sn-stylekit-secondary-foreground-color); padding-top: 14px; padding-bottom: 16px; padding-left: 12px; padding-right: 12px; font-size: 12px; - color: rgba(black, 0.8); - } - - #tag-add-button { - background-color: #d7d7d7; - - &:hover { - background-color: rgba(#d7d7d7, 0.8); - } } .scrollable { @@ -62,7 +53,7 @@ background-color: transparent; font-weight: 600; float: left; - color: $main-text-color; + color: var(--sn-stylekit-secondary-foreground-color); border: none; cursor: pointer; text-overflow: ellipsis; @@ -76,6 +67,7 @@ right: 17px; padding-top: 1px; font-weight: bold; + color: var(--sn-stylekit-neutral-color); } } @@ -97,32 +89,17 @@ } } - $tags-selected-color: #dbdbdb; - &.selected { - background-color: $tags-selected-color; - color: $selected-text-color; > .title { - color: $selected-text-color; cursor: text; } } - /* When a note is dragged over tag */ - &.over { - background-color: $tags-selected-color; - color: $selected-text-color; - border: 2px dashed white; + &:hover:not(.selected), &.selected { + background-color: var(--sn-stylekit-secondary-contrast-background-color); + color: var(--sn-stylekit-secondary-contrast-foreground-color); > .title { - color: $selected-text-color; - } - } - - &:hover:not(.selected) { - background-color: $tags-selected-color; - color: $selected-text-color; - > .title { - color: $selected-text-color; + color: var(--sn-stylekit-secondary-contrast-foreground-color); } } } diff --git a/app/assets/templates/directives/conflict-resolution-modal.html.haml b/app/assets/templates/directives/conflict-resolution-modal.html.haml index 032f0eca9..c59b7ea03 100644 --- a/app/assets/templates/directives/conflict-resolution-modal.html.haml +++ b/app/assets/templates/directives/conflict-resolution-modal.html.haml @@ -1,6 +1,7 @@ -.modal.large#conflict-resolution-modal - .content - .sn-component +.sn-component + .sk-modal.large#conflict-resolution-modal + .sk-modal-background + .sk-modal-content .sk-panel .sk-panel-header %h1.sk-panel-header-title Conflicted items — choose which version to keep @@ -17,7 +18,7 @@ {{contentType}} %p You may wish to look at the "created_at" and "updated_at" fields of the items to gain better context in deciding which to keep. #items - .sk-panel.static#item1.item.border-color + .sk-panel.static#item1.item %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{item1Content}} .border diff --git a/app/assets/templates/directives/input-modal.html.haml b/app/assets/templates/directives/input-modal.html.haml index 3fa0cf810..716e7a4eb 100644 --- a/app/assets/templates/directives/input-modal.html.haml +++ b/app/assets/templates/directives/input-modal.html.haml @@ -1,18 +1,20 @@ -.modal.small.auto-height - .content - .sn-component - .sk-panel - .sk-panel-header - %h1.sk-panel-header-title {{title}} - %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close - .sk-panel-content - .sk-panel-section - %p.sk-panel-row {{message}} - .sk-panel-row - .sk-panel-column.stretch - %form{"ng-submit" => "submit()"} - %input.sk-input{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} +.sn-component + .sk-modal.small.auto-height + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + %h1.sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content + .sk-panel-section + %p.sk-panel-row {{message}} + .sk-panel-row + .sk-panel-column.stretch + %form{"ng-submit" => "submit()"} + %input.sk-input{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} - .sk-panel-footer - %a.sk-a.info.right{"ng-click" => "submit()"} - Submit + .sk-panel-footer + %a.sk-a.info.right{"ng-click" => "submit()"} + Submit diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index 7922211af..70a856aa2 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -1,103 +1,105 @@ -#password-wizard.modal.small.auto-height - .content - .sn-component - .sk-panel - .sk-panel-header - .sk-panel-header-title {{title}} - %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close - .sk-panel-content +.sn-component + #password-wizard.sk-modal.small.auto-height + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content - %div{"ng-if" => "step == 0"} - %div{"ng-if" => "changePassword"} - %p.sk-p - Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. - If you have many items, syncing your data can take several minutes. - %p.sk-p - %strong You must keep the application window open during this process. - %div{"ng-if" => "securityUpdate"} - %p.sk-p - A new update is available for your account. Updates address improvements and enhancements to our security specification. - This process will guide you through the update, and perform the steps necessary with your supervision. - %p.sk-p - For more information about security updates, please visit - %a.sk-a.info{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. + %div{"ng-if" => "step == 0"} + %div{"ng-if" => "changePassword"} + %p.sk-p + Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. + If you have many items, syncing your data can take several minutes. + %p.sk-p + %strong You must keep the application window open during this process. + %div{"ng-if" => "securityUpdate"} + %p.sk-p + A new update is available for your account. Updates address improvements and enhancements to our security specification. + This process will guide you through the update, and perform the steps necessary with your supervision. + %p.sk-p + For more information about security updates, please visit + %a.sk-a.info{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. - %p.sk-panel-row.sk-p - .info Press Continue to proceed. - - .sk-panel-section{"ng-if" => "step > 0"} - - .sk-panel-section-title Step {{step}} — {{titleForStep(step)}} - - %div{"ng-if" => "step == 1"} %p.sk-panel-row.sk-p - As a result of this process, the entirety of your data will be re-encrypted and synced to your account. This is a generally safe process, - but unforeseen factors like poor network connectivity or a sudden shutdown of your computer may cause this process to fail. - It's best to be on the safe side before large operations such as this one. - .sk-panel-row - .sk-panel-row - .sk-button-group - .sk-button.info{"ng-click" => "downloadBackup(true)"} - .sk-label Download Encrypted Backup - .sk-button.info{"ng-click" => "downloadBackup(false)"} - .sk-label Download Decrypted Backup + .info Press Continue to proceed. - %div{"ng-if" => "step == 2"} - %p.sk-p.sk-panel-row - As a result of this process, your encryption keys will change. - Any device on which you use Standard Notes will need to end its session. After this process completes, you will be asked to sign back in. + .sk-panel-section{"ng-if" => "step > 0"} - %p.sk-p.bold.sk-panel-row.info-i Please sign out of all applications (excluding this one), including: - %ul - %li Desktop - %li Web (Chrome, Firefox, Safari) - %li Mobile (iOS and Android) - %p.sk-p.sk-panel-row - If you do not currently have access to a device you're signed in on, you may proceed, - but must make signing out and back in the first step upon gaining access to that device. - %p.sk-p.sk-panel-row Press Continue only when you have completed signing out of all your devices. + .sk-panel-section-title Step {{step}} — {{titleForStep(step)}} + + %div{"ng-if" => "step == 1"} + %p.sk-panel-row.sk-p + As a result of this process, the entirety of your data will be re-encrypted and synced to your account. This is a generally safe process, + but unforeseen factors like poor network connectivity or a sudden shutdown of your computer may cause this process to fail. + It's best to be on the safe side before large operations such as this one. + .sk-panel-row + .sk-panel-row + .sk-button-group + .sk-button.info{"ng-click" => "downloadBackup(true)"} + .sk-label Download Encrypted Backup + .sk-button.info{"ng-click" => "downloadBackup(false)"} + .sk-label Download Decrypted Backup + + %div{"ng-if" => "step == 2"} + %p.sk-p.sk-panel-row + As a result of this process, your encryption keys will change. + Any device on which you use Standard Notes will need to end its session. After this process completes, you will be asked to sign back in. + + %p.sk-p.bold.sk-panel-row.info-i Please sign out of all applications (excluding this one), including: + %ul + %li Desktop + %li Web (Chrome, Firefox, Safari) + %li Mobile (iOS and Android) + %p.sk-p.sk-panel-row + If you do not currently have access to a device you're signed in on, you may proceed, + but must make signing out and back in the first step upon gaining access to that device. + %p.sk-p.sk-panel-row Press Continue only when you have completed signing out of all your devices. - %div{"ng-if" => "step == 3"} - %div{"ng-if" => "changePassword"} - %div{"ng-if" => "securityUpdate"} - %p.sk-panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. - .sk-panel-row - .sk-panel-row - .sk-panel-column.stretch - %form.sk-panel-form - %input.sk-input{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} - %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} - %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} + %div{"ng-if" => "step == 3"} + %div{"ng-if" => "changePassword"} + %div{"ng-if" => "securityUpdate"} + %p.sk-panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. + .sk-panel-row + .sk-panel-row + .sk-panel-column.stretch + %form.sk-panel-form + %input.sk-input{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} + %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} - %div{"ng-if" => "step == 4"} - %p.sk-panel-row - Your data is being re-encrypted with your new keys and synced to your account. - %p.sk-panel-row.danger - Do not close this window until this process completes. - - .sk-panel-row - .sk-panel-column - .sk-spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} - .inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"} - {{formData.status}} - .sk-panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} - %p.info - Syncing {{syncStatus.current}}/{{syncStatus.total}} - - %div{"ng-if" => "step == 5"} - %div{"ng-if" => "changePassword"} - %p.sk-panel-row Your password has been successfully changed. - %div{"ng-if" => "securityUpdate"} + %div{"ng-if" => "step == 4"} %p.sk-panel-row - The security update has been successfully applied to your account. - %p.sk-panel-row - %strong Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. + Your data is being re-encrypted with your new keys and synced to your account. + %p.sk-panel-row.danger + Do not close this window until this process completes. - %p.sk-panel-row You may now sign back in on all your devices and close this window. + .sk-panel-row + .sk-panel-column + .sk-spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} + .inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"} + {{formData.status}} + .sk-panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} + %p.info + Syncing {{syncStatus.current}}/{{syncStatus.total}} - .sk-panel-footer - .empty - %a.sk-a.info.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} - .sk-spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} - {{continueTitle}} + %div{"ng-if" => "step == 5"} + %div{"ng-if" => "changePassword"} + %p.sk-panel-row Your password has been successfully changed. + %div{"ng-if" => "securityUpdate"} + %p.sk-panel-row + The security update has been successfully applied to your account. + %p.sk-panel-row + %strong Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. + + %p.sk-panel-row You may now sign back in on all your devices and close this window. + + .sk-panel-footer + .empty + %a.sk-a.info.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} + .sk-spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} + {{continueTitle}} diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml index 4d144d6bd..d9b8e3b87 100644 --- a/app/assets/templates/directives/revision-preview-modal.html.haml +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -1,13 +1,15 @@ -.modal.medium#item-preview-modal - .content - .sn-component - .sk-panel - .sk-panel-header - .sk-panel-header-title Preview - .sk-horizontal-group - %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore - %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy - %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .sk-panel-content.selectable - .sk-h2 {{content.title}} - %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} +.sn-component + .sk-modal.medium#item-preview-modal + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title Preview + .sk-horizontal-group + %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore + %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy + %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .sk-panel-content.selectable + .sk-h2 {{content.title}} + %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index c0b323b67..d33f6f985 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -13,7 +13,7 @@ "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} - #save-status{"ng-class" => "{'error bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} + #save-status{"ng-class" => "{'warning bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} .editor-tags #note-tags-component-container{"ng-if" => "ctrl.tagsComponent"} @@ -80,5 +80,5 @@ #editor-pane-component-stack .sn-component - %component-view.component-view.component-stack-item.border-color{"ng-repeat" => "component in ctrl.componentStack", + %component-view.component-view.component-stack-item{"ng-repeat" => "component in ctrl.componentStack", "ng-if" => "component.active", "ng-show" => "!component.hidden", "manual-dealloc" => "true", "component" => "component"} diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index 14766fe20..e566e45ea 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -1,10 +1,11 @@ -.section.notes#notes-column{"aria-label" => "Notes"} +.sn-component.section.notes#notes-column{"aria-label" => "Notes"} .content .section-title-bar#notes-title-bar .padded .section-title-bar-header .title {{ctrl.panelTitle()}} - .add-button#notes-add-button{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + + .sk-button.contrast.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + .sk-label + .filter-section{"role" => "search"} %input.filter-bar#search-bar.mousetrap{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true", "ng-blur" => "ctrl.onFilterEnter()", "ng-keyup" => "$event.keyCode == 13 && ctrl.onFilterEnter();", diff --git a/app/assets/templates/tags.html.haml b/app/assets/templates/tags.html.haml index 66c401a33..1df7a327f 100644 --- a/app/assets/templates/tags.html.haml +++ b/app/assets/templates/tags.html.haml @@ -1,4 +1,4 @@ -.section.tags#tags-column{"aria-label" => "Tags"} +.sn-component.section.tags#tags-column{"aria-label" => "Tags"} .component-view-container{"ng-if" => "ctrl.component.active"} %component-view.component-view{"component" => "ctrl.component"} @@ -7,7 +7,8 @@ #tags-title-bar.section-title-bar .section-title-bar-header .title Tags - .add-button#tag-add-button{"ng-click" => "ctrl.clickedAddNewTag()", "title" => "Create a new tag"} + + .sk-button.sk-secondary-contrast.wide{"ng-click" => "ctrl.clickedAddNewTag()", "title" => "Create a new tag"} + .sk-label + .scrollable .infinite-scroll From 19b018c29fb03aa41777cf82a85b3d24a75ecab7 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 7 Dec 2018 21:30:20 -0600 Subject: [PATCH 15/62] Permission modal fixes, progress styles --- .../app/services/actionsManager.js | 2 +- .../app/services/componentManager.js | 4 +-- .../javascripts/app/services/syncManager.js | 2 +- app/assets/stylesheets/app/_notes.scss | 27 ++++++++++++++++++- .../directives/permissions-modal.html.haml | 6 ++--- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/app/services/actionsManager.js b/app/assets/javascripts/app/services/actionsManager.js index 1953907c3..f23dfd379 100644 --- a/app/assets/javascripts/app/services/actionsManager.js +++ b/app/assets/javascripts/app/services/actionsManager.js @@ -202,7 +202,7 @@ class ActionsManager { var scope = this.$rootScope.$new(true); scope.uuid = uuid; scope.content = content; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 5d8fb15aa..a578fc7d2 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -765,14 +765,14 @@ class ComponentManager { var permissions = dialog.permissions; var component = dialog.component; var callback = dialog.callback; - var el = this.$compile( "" )(dialog); + var el = this.$compile( "" )(dialog); angular.element(document.body).append(el); } openModalComponent(component) { var scope = this.$rootScope.$new(true); scope.component = component; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index 291eaf50c..02596cf7f 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -11,7 +11,7 @@ class SyncManager extends SFSyncManager { scope.item1 = items[0]; scope.item2 = items[1]; scope.callback = callback; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index c880e1057..fb659a42a 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -153,6 +153,19 @@ opacity: 0.6; } + progress { + background-color: var(--sn-stylekit-contrast-background-color); + color: var(--sn-stylekit-info-color); + } + + progress::-webkit-progress-bar { + background-color: var(--sn-stylekit-contrast-background-color); + } + + progress::-webkit-progress-value { + background-color: var(--sn-stylekit-info-color); + } + &.selected { background-color: var(--sn-stylekit-info-color); color: var(--sn-stylekit-info-contrast-color); @@ -160,7 +173,19 @@ .pinned { color: var(--sn-stylekit-info-contrast-color); } - } + progress { + background-color: var(--sn-stylekit-secondary-foreground-color); + color: var(--sn-stylekit-secondary-background-color); + } + + progress::-webkit-progress-bar { + background-color: var(--sn-stylekit-secondary-foreground-color); + } + + progress::-webkit-progress-value { + background-color: var(--sn-stylekit-secondary-background-color); + } + } } } diff --git a/app/assets/templates/directives/permissions-modal.html.haml b/app/assets/templates/directives/permissions-modal.html.haml index b8522c27c..dc8fb2af3 100644 --- a/app/assets/templates/directives/permissions-modal.html.haml +++ b/app/assets/templates/directives/permissions-modal.html.haml @@ -4,18 +4,18 @@ .sn-component .sk-panel .sk-panel-header - %h1.sk-panel-header-title Activate Extension + .sk-panel-header-title Activate Extension %a.sk-a.info.close-button{"ng-click" => "deny()"} Cancel .sk-panel-content .sk-panel-section .sk-panel-row - %h3 + .sk-h3 %strong {{component.name}} would like to interact with your {{permissionsString()}} .sk-panel-row - %p + %p.sk-p Extensions use an offline messaging system to communicate. Learn more at %a.sk-a.info{"href" => "https://standardnotes.org/permissions", "target" => "_blank"} https://standardnotes.org/permissions. .sk-panel-footer From 99958f7f86e8b56a09ce1a36fef17e6978e2e35b Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 10 Dec 2018 18:03:57 -0600 Subject: [PATCH 16/62] Desktop changes --- Gemfile | 2 + Gemfile.lock | 9 +- .../app/directives/views/componentView.js | 2 + .../app/services/componentManager.js | 5 +- app/assets/stylesheets/app/_editor.scss | 10 +- app/assets/stylesheets/app/_main.scss | 1 + app/assets/stylesheets/app/_modals.scss | 8 +- app/assets/stylesheets/main.css.scss | 2 +- app/assets/templates/editor.html.haml | 3 +- package-lock.json | 3097 +++++++++-------- package.json | 7 +- 11 files changed, 1592 insertions(+), 1554 deletions(-) diff --git a/Gemfile b/Gemfile index af629c959..1fc8424e9 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,8 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Used for 'respond_to' feature gem 'responders', '~> 2.0' +gem 'tzinfo-data' + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 1056e5c0b..117dd64aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,6 +76,7 @@ GEM erubi (1.7.1) execjs (2.7.0) ffi (1.9.23) + ffi (1.9.23-x64-mingw32) globalid (0.4.1) activesupport (>= 4.2.0) haml (5.0.4) @@ -99,6 +100,8 @@ GEM nio4r (2.3.0) nokogiri (1.8.2) mini_portile2 (~> 2.3.0) + nokogiri (1.8.2-x64-mingw32) + mini_portile2 (~> 2.3.0) non-stupid-digest-assets (1.0.9) sprockets (>= 2.0) puma (3.11.4) @@ -172,6 +175,8 @@ GEM tilt (2.0.8) tzinfo (1.2.5) thread_safe (~> 0.1) + tzinfo-data (1.2018.7) + tzinfo (>= 1.0.0) uglifier (4.1.10) execjs (>= 0.3.0, < 3) web-console (3.5.1) @@ -185,6 +190,7 @@ GEM PLATFORMS ruby + x64-mingw32 DEPENDENCIES bower-rails (~> 0.10.0) @@ -207,8 +213,9 @@ DEPENDENCIES sdoc (~> 0.4.0) secure_headers spring + tzinfo-data uglifier web-console (= 3.5.1) BUNDLED WITH - 1.16.3 + 1.17.1 diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index a68ea4be5..ec4055116 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -125,6 +125,8 @@ class ComponentView { expired = component.valid_until && component.valid_until <= new Date(); + // expired = true; + $scope.componentValid = !offlineRestricted && !urlError && !expired; if(offlineRestricted) $scope.error = 'offline-restricted'; diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 5d8fb15aa..01cd4279d 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -981,10 +981,7 @@ class ComponentManager { if(!iframe) { return; } - var width = data.width; - var height = data.height; - iframe.width = width; - iframe.height = height; + setSize(iframe, data); // On Firefox, resizing a component iframe does not seem to have an effect with editor-stack extensions. diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 0d4f3b225..3d34f94f0 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -126,12 +126,18 @@ $heading-height: 75px; #editor-pane-component-stack { width: 100%; + // When two component stack items are expired and eat up full screen, this is required to scroll them. + overflow: auto; + .component-stack-item { width: 100%; position: relative; - border-top: 1px solid $bg-color; + iframe { width: 100%; + // we moved the border top from the .component-stack-item to the .iframe, as on parent, + // it increases its height and caused unneccessary scrollbars on windows. + border-top: 1px solid var(--sn-component-outer-border-color); } } -} +} \ No newline at end of file diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index c4f412b3b..7a703fbd7 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -38,6 +38,7 @@ body { * { box-sizing: border-box; + scrollbar-color: rebeccapurple green; } .tinted { diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index ca1dac561..643856bd7 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -145,7 +145,13 @@ } iframe { - flex: 1; + // We're disabling flex: 1; because on Firefox, it causes weird sizing issues with component stack items. + // Not sure yet if totally required. + // Update: The extensions manager doesn't display correctly without it + // flex-grow: 1 should fix that. + + flex-grow: 1; width: 100%; + height: 100%; } } diff --git a/app/assets/stylesheets/main.css.scss b/app/assets/stylesheets/main.css.scss index d59551f78..77c84f236 100644 --- a/app/assets/stylesheets/main.css.scss +++ b/app/assets/stylesheets/main.css.scss @@ -9,4 +9,4 @@ @import "app/modals"; @import "app/lock-screen"; @import "app/stylekit-sub"; -@import "app/ionicons"; +@import "app/ionicons"; \ No newline at end of file diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index d78f5eca9..4474f549b 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -79,6 +79,5 @@ %p.medium-padding{"style" => "padding-top: 0 !important;"} There was an error decrypting this item. Ensure you are running the latest version of this app, then sign out and sign back in to try again. #editor-pane-component-stack - .sn-component - %component-view.component-view.component-stack-item.border-color{"ng-repeat" => "component in ctrl.componentStack", + %component-view.sn-component.component-view.component-stack-item.border-color{"ng-repeat" => "component in ctrl.componentStack", "ng-if" => "component.active", "ng-show" => "!component.hidden", "manual-dealloc" => "true", "component" => "component"} diff --git a/package-lock.json b/package-lock.json index 712f36497..851de2967 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.16", + "version": "2.3.18", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,8 +10,8 @@ "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==", "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "jsonparse": "1.3.1", + "through": "2.3.8" } }, "abbrev": { @@ -32,8 +32,8 @@ "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", "dev": true, "requires": { - "acorn": "^5.4.1", - "xtend": "^4.0.1" + "acorn": "5.6.2", + "xtend": "4.0.1" }, "dependencies": { "acorn": { @@ -63,7 +63,7 @@ "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "es6-promisify": "5.0.0" } }, "ajv": { @@ -72,10 +72,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "align-text": { @@ -84,9 +84,9 @@ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "alter": { @@ -95,7 +95,7 @@ "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", "dev": true, "requires": { - "stable": "~0.1.3" + "stable": "0.1.8" } }, "amdefine": { @@ -111,11 +111,11 @@ "dev": true, "optional": true, "requires": { - "bitsyntax": "~0.0.4", - "bluebird": "^3.4.6", + "bitsyntax": "0.0.4", + "bluebird": "3.5.1", "buffer-more-ints": "0.0.2", - "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" + "readable-stream": "1.1.14", + "safe-buffer": "5.1.2" }, "dependencies": { "isarray": { @@ -132,10 +132,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -162,14 +162,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "anymatch": { "version": "1.3.2", @@ -177,8 +175,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "argparse": { @@ -187,7 +185,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" }, "dependencies": { "sprintf-js": { @@ -204,7 +202,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.1.0" } }, "arr-flatten": { @@ -267,9 +265,9 @@ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -329,7 +327,7 @@ "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", "dev": true, "requires": { - "acorn": "^4.0.3" + "acorn": "4.0.13" } }, "async": { @@ -391,7 +389,7 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.2.0" + "debug": "2.6.9" } } } @@ -402,21 +400,21 @@ "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" + "babel-core": "6.26.3", + "babel-polyfill": "6.26.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "chokidar": "1.7.0", + "commander": "2.15.1", + "convert-source-map": "1.5.1", + "fs-readdir-recursive": "1.1.0", + "glob": "7.1.2", + "lodash": "4.17.10", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.7", + "v8flags": "2.1.1" } }, "babel-code-frame": { @@ -425,9 +423,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" } }, "babel-core": { @@ -436,25 +434,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" } }, "babel-generator": { @@ -463,14 +461,14 @@ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.10", + "source-map": "0.5.7", + "trim-right": "1.0.1" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -479,9 +477,9 @@ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-call-delegate": { @@ -490,10 +488,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-define-map": { @@ -502,10 +500,10 @@ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-explode-assignable-expression": { @@ -514,9 +512,9 @@ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-function-name": { @@ -525,11 +523,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-get-function-arity": { @@ -538,8 +536,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-hoist-variables": { @@ -548,8 +546,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-optimise-call-expression": { @@ -558,8 +556,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-regex": { @@ -568,9 +566,9 @@ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-remap-async-to-generator": { @@ -579,11 +577,11 @@ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-replace-supers": { @@ -592,12 +590,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helpers": { @@ -606,8 +604,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-messages": { @@ -616,7 +614,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-angularjs-annotate": { @@ -625,9 +623,9 @@ "integrity": "sha512-erYvZAJgnrgeyEZqIJOAiK6vUK44HsVb0+Tid4zTBcsvdQuas0Z5Teh0w/hcINKW3G0xweqA5LGfg2ZWlp3nMA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-types": "^6.26.0", - "simple-is": "~0.2.0" + "babel-code-frame": "6.26.0", + "babel-types": "6.26.0", + "simple-is": "0.2.0" } }, "babel-plugin-check-es2015-constants": { @@ -636,7 +634,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-syntax-async-functions": { @@ -663,9 +661,9 @@ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -674,7 +672,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -683,7 +681,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -692,11 +690,11 @@ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-plugin-transform-es2015-classes": { @@ -705,15 +703,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -722,8 +720,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -732,7 +730,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -741,8 +739,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -751,7 +749,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -760,9 +758,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-literals": { @@ -771,7 +769,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -780,9 +778,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -791,10 +789,10 @@ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -803,9 +801,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -814,9 +812,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -825,8 +823,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -835,12 +833,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -849,8 +847,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-spread": { @@ -859,7 +857,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -868,9 +866,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -879,7 +877,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -888,7 +886,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -897,9 +895,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -908,9 +906,9 @@ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -919,7 +917,7 @@ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "regenerator-transform": "0.10.1" } }, "babel-plugin-transform-runtime": { @@ -928,7 +926,7 @@ "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-strict-mode": { @@ -937,8 +935,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-polyfill": { @@ -947,9 +945,9 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "regenerator-runtime": "0.10.5" }, "dependencies": { "regenerator-runtime": { @@ -966,36 +964,36 @@ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "3.2.8", + "invariant": "2.2.4", + "semver": "5.5.0" } }, "babel-preset-es2015": { @@ -1004,30 +1002,30 @@ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" } }, "babel-preset-es2016": { @@ -1036,7 +1034,7 @@ "integrity": "sha1-+QC/k+LrwNJ235uKtZck6/2Vn4s=", "dev": true, "requires": { - "babel-plugin-transform-exponentiation-operator": "^6.24.1" + "babel-plugin-transform-exponentiation-operator": "6.24.1" } }, "babel-register": { @@ -1045,13 +1043,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "babel-core": "6.26.3", + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "home-or-tmp": "2.0.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" } }, "babel-runtime": { @@ -1060,8 +1058,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" } }, "babel-template": { @@ -1070,11 +1068,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.10" } }, "babel-traverse": { @@ -1083,15 +1081,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" } }, "babel-types": { @@ -1100,10 +1098,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" } }, "babylon": { @@ -1130,13 +1128,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" }, "dependencies": { "component-emitter": { @@ -1151,7 +1149,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -1160,7 +1158,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -1169,7 +1167,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -1178,9 +1176,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -1222,7 +1220,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "better-assert": { @@ -1257,7 +1255,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "~2.0.5" + "readable-stream": "2.0.6" }, "dependencies": { "process-nextick-args": { @@ -1274,12 +1272,12 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -1315,10 +1313,10 @@ "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" + "continuable-cache": "0.3.1", + "error": "7.0.2", + "raw-body": "1.1.7", + "safe-json-parse": "1.0.1" } }, "body-parser": { @@ -1328,15 +1326,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", + "depd": "1.1.2", + "http-errors": "1.6.3", "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "~1.6.16" + "type-is": "1.6.16" }, "dependencies": { "bytes": { @@ -1365,7 +1363,7 @@ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "bower": { @@ -1380,7 +1378,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1390,9 +1388,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "brorand": { @@ -1407,12 +1405,12 @@ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "defined": "1.0.0", + "safe-buffer": "5.1.2", + "through2": "2.0.3", + "umd": "3.0.3" } }, "browser-resolve": { @@ -1436,54 +1434,54 @@ "integrity": "sha512-fMES05wq1Oukts6ksGUU2TMVHHp06LyQt0SIwbXIHm7waSrQmNBZePsU0iM/4f94zbvb/wHma+D1YrdzWYnF/A==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", - "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^2.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", + "JSONStream": "1.3.3", + "assert": "1.4.1", + "browser-pack": "6.1.0", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.2.0", + "buffer": "5.1.0", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.2.0", + "duplexer2": "0.1.4", + "events": "2.1.0", + "glob": "7.1.2", + "has": "1.0.3", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.1.0", + "labeled-stream-splicer": "2.0.1", + "mkdirp": "0.5.1", + "module-deps": "6.1.0", + "os-browserify": "0.3.0", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.6", + "resolve": "1.1.7", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "1.1.1", + "subarg": "1.0.0", + "syntax-error": "1.4.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" + "url": "0.11.0", + "util": "0.10.4", + "vm-browserify": "1.0.1", + "xtend": "4.0.1" } }, "browserify-aes": { @@ -1492,12 +1490,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "browserify-cache-api": { @@ -1506,9 +1504,9 @@ "integrity": "sha1-liR+hT8Gj9bg1FzHPwuyzZd47wI=", "dev": true, "requires": { - "async": "^1.5.2", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "async": "1.5.2", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "browserify-cipher": { @@ -1517,9 +1515,9 @@ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -1528,9 +1526,9 @@ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1" + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" } }, "browserify-incremental": { @@ -1539,10 +1537,10 @@ "integrity": "sha1-BxPLdYckemMqnwjPG9FpuHi2Koo=", "dev": true, "requires": { - "JSONStream": "^0.10.0", - "browserify-cache-api": "^3.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "0.10.0", + "browserify-cache-api": "3.0.1", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "JSONStream": { @@ -1552,7 +1550,7 @@ "dev": true, "requires": { "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" + "through": "2.3.8" } }, "jsonparse": { @@ -1569,8 +1567,8 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "randombytes": "2.0.6" } }, "browserify-sign": { @@ -1579,13 +1577,13 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.1" } }, "browserify-zlib": { @@ -1594,7 +1592,7 @@ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "~1.0.5" + "pako": "1.0.6" } }, "browserslist": { @@ -1603,8 +1601,8 @@ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "caniuse-lite": "1.0.30000849", + "electron-to-chromium": "1.3.48" } }, "buffer": { @@ -1613,8 +1611,8 @@ "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "1.3.0", + "ieee754": "1.1.11" } }, "buffer-from": { @@ -1675,15 +1673,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" }, "dependencies": { "component-emitter": { @@ -1718,8 +1716,8 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "camelcase": { @@ -1734,8 +1732,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "2.1.1", + "map-obj": "1.0.1" } }, "caniuse-lite": { @@ -1756,8 +1754,8 @@ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chai": { @@ -1766,25 +1764,24 @@ "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", - "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" } }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "change-case": { @@ -1793,24 +1790,24 @@ "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", "dev": true, "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "constant-case": "2.0.0", + "dot-case": "2.1.1", + "header-case": "1.0.1", + "is-lower-case": "1.1.3", + "is-upper-case": "1.1.2", + "lower-case": "1.1.4", + "lower-case-first": "1.0.2", + "no-case": "2.3.2", + "param-case": "2.1.1", + "pascal-case": "2.0.1", + "path-case": "2.1.1", + "sentence-case": "2.1.1", + "snake-case": "2.1.0", + "swap-case": "1.1.2", + "title-case": "2.1.1", + "upper-case": "1.1.3", + "upper-case-first": "1.1.2" } }, "check-error": { @@ -1825,15 +1822,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.2.4", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "cipher-base": { @@ -1842,8 +1839,8 @@ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "circular-json": { @@ -1858,10 +1855,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" }, "dependencies": { "define-property": { @@ -1870,7 +1867,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "isobject": { @@ -1887,8 +1884,8 @@ "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", "dev": true, "requires": { - "commander": "2.8.x", - "source-map": "0.4.x" + "commander": "2.8.1", + "source-map": "0.4.4" }, "dependencies": { "commander": { @@ -1897,7 +1894,7 @@ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } }, "source-map": { @@ -1906,7 +1903,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -1917,8 +1914,8 @@ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" } }, @@ -1940,17 +1937,17 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "map-visit": "1.0.0", + "object-visit": "1.0.1" } }, "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "color-name": "^1.1.1" + "color-name": "1.1.3" } }, "color-name": { @@ -1971,7 +1968,7 @@ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "^4.5.0" + "lodash": "4.17.10" } }, "combine-source-map": { @@ -1980,10 +1977,10 @@ "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" }, "dependencies": { "convert-source-map": { @@ -2000,7 +1997,7 @@ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -2033,10 +2030,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" } }, "connect": { @@ -2047,7 +2044,7 @@ "requires": { "debug": "2.6.9", "finalhandler": "1.1.0", - "parseurl": "~1.3.2", + "parseurl": "1.3.2", "utils-merge": "1.0.1" } }, @@ -2057,7 +2054,7 @@ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "^0.1.4" + "date-now": "0.1.4" } }, "constant-case": { @@ -2066,8 +2063,8 @@ "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", "dev": true, "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" + "snake-case": "2.1.0", + "upper-case": "1.1.3" } }, "constants-browserify": { @@ -2124,8 +2121,8 @@ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "bn.js": "4.11.8", + "elliptic": "6.4.0" } }, "create-hash": { @@ -2134,11 +2131,11 @@ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { @@ -2147,12 +2144,12 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "cross-spawn": { @@ -2161,7 +2158,7 @@ "integrity": "sha1-vWf5bAfvtjA7f+lMHpefiEeOCjk=", "dev": true, "requires": { - "lru-cache": "^2.5.0" + "lru-cache": "2.7.3" } }, "cryptiles": { @@ -2171,7 +2168,7 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "crypto-browserify": { @@ -2180,17 +2177,17 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "browserify-cipher": "1.0.1", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", + "inherits": "2.0.3", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "currently-unhandled": { @@ -2199,7 +2196,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "array-find-index": "1.0.2" } }, "custom-event": { @@ -2214,7 +2211,7 @@ "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "dashdash": { @@ -2223,7 +2220,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "data-uri-to-buffer": { @@ -2251,8 +2248,8 @@ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "debug": { @@ -2282,7 +2279,7 @@ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "^4.0.0" + "type-detect": "4.0.8" } }, "deep-is": { @@ -2298,8 +2295,8 @@ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "foreach": "2.0.5", + "object-keys": "1.0.11" } }, "define-property": { @@ -2308,8 +2305,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "is-descriptor": "1.0.2", + "isobject": "3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2318,7 +2315,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -2327,7 +2324,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -2336,9 +2333,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -2368,9 +2365,9 @@ "dev": true, "optional": true, "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" + "ast-types": "0.11.5", + "escodegen": "1.11.0", + "esprima": "3.1.3" }, "dependencies": { "esprima": { @@ -2400,10 +2397,10 @@ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" + "JSONStream": "1.3.3", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" } }, "des.js": { @@ -2412,8 +2409,8 @@ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "destroy": { @@ -2428,7 +2425,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "detective": { @@ -2437,9 +2434,9 @@ "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==", "dev": true, "requires": { - "acorn-node": "^1.3.0", - "defined": "^1.0.0", - "minimist": "^1.1.1" + "acorn-node": "1.3.0", + "defined": "1.0.0", + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -2468,9 +2465,9 @@ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" } }, "dom-serialize": { @@ -2479,10 +2476,10 @@ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" } }, "domain-browser": { @@ -2497,7 +2494,7 @@ "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "double-ended-queue": { @@ -2513,7 +2510,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "ecc-jsbn": { @@ -2523,7 +2520,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "ee-first": { @@ -2544,13 +2541,13 @@ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "encodeurl": { @@ -2571,8 +2568,8 @@ "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", "dev": true, "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "string-template": "0.2.1", + "xtend": "4.0.1" } }, "error-ex": { @@ -2581,7 +2578,7 @@ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "es6-promise": { @@ -2596,7 +2593,7 @@ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "es6-promise": "4.2.4" } }, "escape-html": { @@ -2608,8 +2605,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.11.0", @@ -2618,11 +2614,11 @@ "dev": true, "optional": true, "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" }, "dependencies": { "esprima": { @@ -2690,8 +2686,8 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "md5.js": "1.3.4", + "safe-buffer": "5.1.2" } }, "exit": { @@ -2706,9 +2702,9 @@ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", "dev": true, "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" }, "dependencies": { "braces": { @@ -2717,7 +2713,7 @@ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", "dev": true, "requires": { - "expand-range": "^0.1.0" + "expand-range": "0.1.1" } }, "expand-range": { @@ -2726,8 +2722,8 @@ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" + "is-number": "0.1.1", + "repeat-string": "0.2.2" } }, "is-number": { @@ -2750,7 +2746,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -2759,7 +2755,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.4" } }, "extend": { @@ -2774,8 +2770,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -2784,7 +2780,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -2795,7 +2791,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "extract-zip": { @@ -2841,7 +2837,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": ">=0.5.1" + "websocket-driver": "0.7.0" } }, "fd-slicer": { @@ -2850,7 +2846,7 @@ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "dev": true, "requires": { - "pend": "~1.2.0" + "pend": "1.2.0" } }, "figures": { @@ -2859,8 +2855,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "file-sync-cmp": { @@ -2888,11 +2884,11 @@ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "3.0.0", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -2902,12 +2898,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" }, "dependencies": { "statuses": { @@ -2924,8 +2920,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "findup-sync": { @@ -2934,7 +2930,7 @@ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "requires": { - "glob": "~5.0.0" + "glob": "5.0.15" }, "dependencies": { "glob": { @@ -2943,11 +2939,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } } } @@ -2958,7 +2954,7 @@ "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", "dev": true, "requires": { - "debug": "^3.1.0" + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -2984,7 +2980,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "foreach": { @@ -3005,9 +3001,9 @@ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.18" } }, "fragment-cache": { @@ -3016,7 +3012,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "^0.2.2" + "map-cache": "0.2.2" } }, "fresh": { @@ -3031,9 +3027,9 @@ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" } }, "fs-readdir-recursive": { @@ -3055,8 +3051,8 @@ "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "2.11.0", + "node-pre-gyp": "0.10.0" }, "dependencies": { "abbrev": { @@ -3082,8 +3078,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.3.6" } }, "balanced-match": { @@ -3096,7 +3092,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -3160,7 +3156,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "fs.realpath": { @@ -3175,14 +3171,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" } }, "glob": { @@ -3191,12 +3187,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "has-unicode": { @@ -3211,7 +3207,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": "2.1.2" } }, "ignore-walk": { @@ -3220,7 +3216,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "3.0.4" } }, "inflight": { @@ -3229,8 +3225,8 @@ "dev": true, "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -3249,7 +3245,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "isarray": { @@ -3263,7 +3259,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -3276,8 +3272,8 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, "minizlib": { @@ -3286,7 +3282,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "mkdirp": { @@ -3309,9 +3305,9 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" } }, "node-pre-gyp": { @@ -3320,16 +3316,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "needle": "2.2.0", + "nopt": "4.0.1", + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.7", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" } }, "nopt": { @@ -3338,8 +3334,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" } }, "npm-bundled": { @@ -3354,8 +3350,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" } }, "npmlog": { @@ -3364,10 +3360,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { @@ -3386,7 +3382,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { @@ -3407,8 +3403,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { @@ -3429,10 +3425,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "deep-extend": "0.5.1", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" }, "dependencies": { "minimist": { @@ -3449,13 +3445,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "rimraf": { @@ -3464,7 +3460,7 @@ "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "safe-buffer": { @@ -3507,9 +3503,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -3518,7 +3514,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } }, "strip-ansi": { @@ -3526,7 +3522,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { @@ -3541,13 +3537,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, "util-deprecate": { @@ -3562,7 +3558,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "wrappy": { @@ -3584,7 +3580,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "1.1.x", + "readable-stream": "1.1.14", "xregexp": "2.0.0" }, "dependencies": { @@ -3602,10 +3598,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -3629,7 +3625,7 @@ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { - "globule": "^1.0.0" + "globule": "1.2.1" } }, "generate-function": { @@ -3639,7 +3635,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.2" + "is-property": "1.0.2" } }, "generate-object-property": { @@ -3649,7 +3645,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.0" + "is-property": "1.0.2" } }, "get-func-name": { @@ -3671,12 +3667,12 @@ "dev": true, "optional": true, "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" + "data-uri-to-buffer": "1.2.0", + "debug": "2.6.9", + "extend": "3.0.1", + "file-uri-to-path": "1.0.0", + "ftp": "0.3.10", + "readable-stream": "2.3.6" } }, "get-value": { @@ -3697,7 +3693,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "glob": { @@ -3706,12 +3702,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-base": { @@ -3720,8 +3716,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-parent": { @@ -3730,7 +3726,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "globals": { @@ -3745,9 +3741,9 @@ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "dev": true, "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" + "glob": "7.1.2", + "lodash": "4.17.10", + "minimatch": "3.0.4" } }, "graceful-fs": { @@ -3774,23 +3770,23 @@ "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.5.2", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", - "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "coffeescript": "1.10.0", + "dateformat": "1.0.12", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.3.0", + "glob": "7.0.6", + "grunt-cli": "1.2.0", + "grunt-known-options": "1.1.1", + "grunt-legacy-log": "2.0.0", + "grunt-legacy-util": "1.1.1", + "iconv-lite": "0.4.23", + "js-yaml": "3.5.5", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" }, "dependencies": { "glob": { @@ -3799,12 +3795,12 @@ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "grunt-cli": { @@ -3813,10 +3809,10 @@ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", "dev": true, "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.1", + "nopt": "3.0.6", + "resolve": "1.1.7" } } } @@ -3827,7 +3823,7 @@ "integrity": "sha1-EJYDorlf8BAZtxjHA0EmjwnYvhk=", "dev": true, "requires": { - "html-minifier": "~2.1.2" + "html-minifier": "2.1.7" } }, "grunt-babel": { @@ -3836,7 +3832,7 @@ "integrity": "sha1-N4GJtIfeEWjExKn8iN1gBbNd+WA=", "dev": true, "requires": { - "babel-core": "^6.0.12" + "babel-core": "6.26.3" } }, "grunt-browserify": { @@ -3845,13 +3841,13 @@ "integrity": "sha1-R/2M+LrFj+LeaDr9xX9/OoDKeS0=", "dev": true, "requires": { - "async": "^2.5.0", - "browserify": "^16.0.0", - "browserify-incremental": "^3.1.1", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "resolve": "^1.1.6", - "watchify": "^3.6.1" + "async": "2.6.1", + "browserify": "16.2.2", + "browserify-incremental": "3.1.1", + "glob": "7.1.2", + "lodash": "4.17.10", + "resolve": "1.1.7", + "watchify": "3.11.0" }, "dependencies": { "async": { @@ -3860,7 +3856,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3871,8 +3867,8 @@ "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "requires": { - "chalk": "^1.0.0", - "source-map": "^0.5.3" + "chalk": "1.1.3", + "source-map": "0.5.7" } }, "grunt-contrib-copy": { @@ -3881,8 +3877,8 @@ "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=", "dev": true, "requires": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" + "chalk": "1.1.3", + "file-sync-cmp": "0.1.1" } }, "grunt-contrib-cssmin": { @@ -3891,9 +3887,9 @@ "integrity": "sha1-FzTL09hMpzZHWLflj/GOUqpgu3Y=", "dev": true, "requires": { - "chalk": "^1.0.0", - "clean-css": "~3.4.2", - "maxmin": "^1.1.0" + "chalk": "1.1.3", + "clean-css": "3.4.28", + "maxmin": "1.1.0" } }, "grunt-contrib-sass": { @@ -3902,11 +3898,11 @@ "integrity": "sha1-gGg4JRy8DhqU1k1RXN00z2dNcBs=", "dev": true, "requires": { - "async": "^0.9.0", - "chalk": "^1.0.0", - "cross-spawn": "^0.2.3", - "dargs": "^4.0.0", - "which": "^1.0.5" + "async": "0.9.2", + "chalk": "1.1.3", + "cross-spawn": "0.2.9", + "dargs": "4.1.0", + "which": "1.3.1" }, "dependencies": { "async": { @@ -3923,11 +3919,11 @@ "integrity": "sha1-s9AmDr3WzvoS/y+Onh4ln33kIW8=", "dev": true, "requires": { - "chalk": "^1.0.0", - "maxmin": "^1.1.0", - "object.assign": "^4.0.4", - "uglify-js": "~2.8.21", - "uri-path": "^1.0.0" + "chalk": "1.1.3", + "maxmin": "1.1.0", + "object.assign": "4.1.0", + "uglify-js": "2.8.29", + "uri-path": "1.0.0" }, "dependencies": { "uglify-js": { @@ -3936,9 +3932,9 @@ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" } } } @@ -3949,10 +3945,10 @@ "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { - "async": "^2.6.0", - "gaze": "^1.1.0", - "lodash": "^4.17.10", - "tiny-lr": "^1.1.1" + "async": "2.6.1", + "gaze": "1.1.3", + "lodash": "4.17.10", + "tiny-lr": "1.1.1" }, "dependencies": { "async": { @@ -3961,7 +3957,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3972,7 +3968,7 @@ "integrity": "sha1-b7W9R+JQ3Q9VzS76kj7kMQFEFCM=", "dev": true, "requires": { - "dargs": "~0.1.0" + "dargs": "0.1.0" }, "dependencies": { "dargs": { @@ -3984,9 +3980,9 @@ } }, "grunt-known-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", - "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", + "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", "dev": true }, "grunt-legacy-log": { @@ -3995,10 +3991,10 @@ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", "dev": true, "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" + "colors": "1.1.2", + "grunt-legacy-log-utils": "2.0.1", + "hooker": "0.2.3", + "lodash": "4.17.10" } }, "grunt-legacy-log-utils": { @@ -4007,8 +4003,8 @@ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" + "chalk": "2.4.1", + "lodash": "4.17.10" }, "dependencies": { "ansi-styles": { @@ -4017,7 +4013,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.3" } }, "chalk": { @@ -4026,18 +4022,18 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.5.0" } }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -4048,13 +4044,13 @@ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", "dev": true, "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" + "async": "1.5.2", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "4.17.10", + "underscore.string": "3.3.5", + "which": "1.3.1" } }, "grunt-newer": { @@ -4063,8 +4059,8 @@ "integrity": "sha1-g8y3od2ny9irI7BZAk6+YUrS80I=", "dev": true, "requires": { - "async": "^1.5.2", - "rimraf": "^2.5.2" + "async": "1.5.2", + "rimraf": "2.6.2" } }, "grunt-ng-annotate": { @@ -4073,8 +4069,17 @@ "integrity": "sha1-dqKiGha6Y+Vve+G3XuXErZMCeTk=", "dev": true, "requires": { - "lodash.clonedeep": "^4.5.0", - "ng-annotate": "^1.2.1" + "lodash.clonedeep": "4.5.0", + "ng-annotate": "1.2.2" + } + }, + "grunt-shell": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-2.1.0.tgz", + "integrity": "sha1-Q595FZ7RHmSmUaacyKPQK+v17MI=", + "requires": { + "chalk": "1.1.3", + "npm-run-path": "2.0.2" } }, "gzip-size": { @@ -4083,8 +4088,8 @@ "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", "dev": true, "requires": { - "browserify-zlib": "^0.1.4", - "concat-stream": "^1.4.1" + "browserify-zlib": "0.1.4", + "concat-stream": "1.6.2" }, "dependencies": { "browserify-zlib": { @@ -4093,7 +4098,7 @@ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "requires": { - "pako": "~0.2.0" + "pako": "0.2.9" } }, "pako": { @@ -4116,8 +4121,8 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "has": { @@ -4126,16 +4131,15 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "function-bind": "1.1.1" } }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-binary2": { @@ -4179,9 +4183,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4198,8 +4202,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -4208,7 +4212,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -4217,7 +4221,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4228,7 +4232,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4239,8 +4243,8 @@ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "hash.js": { @@ -4249,8 +4253,8 @@ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "hasha": { @@ -4259,8 +4263,8 @@ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", "dev": true, "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" } }, "hawk": { @@ -4270,10 +4274,10 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "he": { @@ -4288,8 +4292,8 @@ "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "hipchat-notifier": { @@ -4299,8 +4303,8 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.0.0", - "request": "^2.0.0" + "lodash": "4.17.10", + "request": "2.87.0" } }, "hmac-drbg": { @@ -4309,9 +4313,9 @@ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { @@ -4326,8 +4330,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "hooker": { @@ -4348,13 +4352,13 @@ "integrity": "sha1-kFHW/LvPIU7TB+GtdPQyu5rWVcw=", "dev": true, "requires": { - "change-case": "3.0.x", - "clean-css": "3.4.x", - "commander": "2.9.x", - "he": "1.1.x", - "ncname": "1.0.x", - "relateurl": "0.2.x", - "uglify-js": "2.6.x" + "change-case": "3.0.2", + "clean-css": "3.4.28", + "commander": "2.9.0", + "he": "1.1.1", + "ncname": "1.0.0", + "relateurl": "0.2.7", + "uglify-js": "2.6.4" }, "dependencies": { "commander": { @@ -4363,7 +4367,7 @@ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } } } @@ -4380,10 +4384,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "statuses": "1.5.0" } }, "http-parser-js": { @@ -4398,9 +4402,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "eventemitter3": "3.1.0", + "follow-redirects": "1.5.0", + "requires-port": "1.0.0" } }, "http-proxy-agent": { @@ -4409,7 +4413,7 @@ "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { - "agent-base": "4", + "agent-base": "4.2.1", "debug": "3.1.0" }, "dependencies": { @@ -4430,9 +4434,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "httpntlm": { @@ -4441,8 +4445,8 @@ "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", "dev": true, "requires": { - "httpreq": ">=0.4.22", - "underscore": "~1.7.0" + "httpreq": "0.4.24", + "underscore": "1.7.0" } }, "httpreq": { @@ -4463,8 +4467,8 @@ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" + "agent-base": "4.2.1", + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -4484,7 +4488,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "ieee754": { @@ -4499,7 +4503,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "indexof": { @@ -4521,8 +4525,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -4537,7 +4541,7 @@ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "requires": { - "source-map": "~0.5.3" + "source-map": "0.5.7" } }, "insert-module-globals": { @@ -4546,15 +4550,15 @@ "integrity": "sha512-LbYZdybvKjbbcKLp03lB323Cgc8f0iL0Rjh8U6JZ7K1gZSf7MxQH191iCNUcLX4qIQ6/yWe4Q4ZsQ+opcReNFg==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "lexical-scope": "^1.2.0", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "concat-stream": "1.6.2", + "is-buffer": "1.1.6", + "lexical-scope": "1.2.0", + "path-is-absolute": "1.0.1", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "invariant": { @@ -4563,7 +4567,7 @@ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "ip": { @@ -4578,7 +4582,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-arrayish": { @@ -4593,7 +4597,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -4608,7 +4612,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-data-descriptor": { @@ -4617,7 +4621,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-descriptor": { @@ -4626,9 +4630,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" }, "dependencies": { "kind-of": { @@ -4651,7 +4655,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -4672,7 +4676,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-glob": { @@ -4681,7 +4685,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-lower-case": { @@ -4690,7 +4694,7 @@ "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", "dev": true, "requires": { - "lower-case": "^1.1.0" + "lower-case": "1.1.4" } }, "is-my-ip-valid": { @@ -4707,11 +4711,11 @@ "dev": true, "optional": true, "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" + "generate-function": "2.3.1", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" } }, "is-number": { @@ -4720,7 +4724,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-plain-object": { @@ -4729,7 +4733,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4776,7 +4780,7 @@ "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", "dev": true, "requires": { - "upper-case": "^1.1.0" + "upper-case": "1.1.3" } }, "is-utf8": { @@ -4830,9 +4834,9 @@ "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=", "dev": true, "requires": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.99.0" + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.99.1" } }, "jasmine-core": { @@ -4853,8 +4857,8 @@ "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", "dev": true, "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0" + "argparse": "1.0.10", + "esprima": "2.7.3" } }, "jsbn": { @@ -4888,7 +4892,7 @@ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -4909,7 +4913,7 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -4949,31 +4953,31 @@ "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^2.0.3", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.4", - "log4js": "^2.5.3", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", + "bluebird": "3.5.1", + "body-parser": "1.18.3", + "chokidar": "2.0.4", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.6", + "core-js": "2.5.7", + "di": "0.0.1", + "dom-serialize": "2.2.1", + "expand-braces": "0.1.2", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "http-proxy": "1.17.0", + "isbinaryfile": "3.0.2", + "lodash": "4.17.10", + "log4js": "2.11.0", + "mime": "1.6.0", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.2.0", + "range-parser": "1.2.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.2", "socket.io": "2.0.4", - "source-map": "^0.6.1", + "source-map": "0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" }, @@ -4984,7 +4988,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, @@ -4994,8 +4998,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "micromatch": "3.1.10", + "normalize-path": "2.1.1" } }, "arr-diff": { @@ -5022,16 +5026,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" }, "dependencies": { "extend-shallow": { @@ -5040,7 +5044,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5051,19 +5055,19 @@ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.2.4", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" } }, "component-emitter": { @@ -5078,13 +5082,13 @@ "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { - "accepts": "~1.3.4", + "accepts": "1.3.5", "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", - "ws": "~3.3.1" + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" }, "dependencies": { "debug": { @@ -5106,14 +5110,14 @@ "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", "yeast": "0.1.2" }, "dependencies": { @@ -5135,10 +5139,10 @@ "dev": true, "requires": { "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", + "arraybuffer.slice": "0.0.7", "base64-arraybuffer": "0.1.5", "blob": "0.0.4", - "has-binary2": "~1.0.2" + "has-binary2": "1.0.3" } }, "expand-brackets": { @@ -5147,13 +5151,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5162,7 +5166,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -5171,7 +5175,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "is-accessor-descriptor": { @@ -5180,7 +5184,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5189,7 +5193,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5200,7 +5204,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5209,7 +5213,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5220,9 +5224,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" } }, "kind-of": { @@ -5239,14 +5243,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5255,7 +5259,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "extend-shallow": { @@ -5264,7 +5268,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5275,10 +5279,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" }, "dependencies": { "extend-shallow": { @@ -5287,7 +5291,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5298,8 +5302,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" }, "dependencies": { "is-glob": { @@ -5308,7 +5312,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } } } @@ -5319,7 +5323,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -5328,7 +5332,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -5337,9 +5341,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-extglob": { @@ -5354,7 +5358,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "is-extglob": "2.1.1" } }, "is-number": { @@ -5363,7 +5367,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5372,7 +5376,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5401,18 +5405,18 @@ "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", "dev": true, "requires": { - "amqplib": "^0.5.2", - "axios": "^0.15.3", - "circular-json": "^0.5.4", - "date-format": "^1.2.0", - "debug": "^3.1.0", - "hipchat-notifier": "^1.1.0", - "loggly": "^1.1.0", - "mailgun-js": "^0.18.0", - "nodemailer": "^2.5.0", - "redis": "^2.7.1", - "semver": "^5.5.0", - "slack-node": "~0.2.0", + "amqplib": "0.5.2", + "axios": "0.15.3", + "circular-json": "0.5.5", + "date-format": "1.2.0", + "debug": "3.1.0", + "hipchat-notifier": "1.1.0", + "loggly": "1.1.1", + "mailgun-js": "0.18.1", + "nodemailer": "2.7.2", + "redis": "2.8.0", + "semver": "5.5.0", + "slack-node": "0.2.0", "streamroller": "0.7.0" }, "dependencies": { @@ -5439,19 +5443,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.13", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "socket.io": { @@ -5460,11 +5464,11 @@ "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", "dev": true, "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", - "socket.io-adapter": "~1.1.0", + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", "socket.io-client": "2.0.4", - "socket.io-parser": "~3.1.1" + "socket.io-parser": "3.1.3" } }, "socket.io-adapter": { @@ -5483,14 +5487,14 @@ "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", + "debug": "2.6.9", + "engine.io-client": "3.1.6", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", + "socket.io-parser": "3.1.3", "to-array": "0.1.4" } }, @@ -5501,8 +5505,8 @@ "dev": true, "requires": { "component-emitter": "1.2.1", - "debug": "~3.1.0", - "has-binary2": "~1.0.2", + "debug": "3.1.0", + "has-binary2": "1.0.3", "isarray": "2.0.1" }, "dependencies": { @@ -5529,7 +5533,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "os-tmpdir": "1.0.2" } }, "ultron": { @@ -5544,8 +5548,8 @@ "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", "dev": true, "requires": { - "lru-cache": "2.2.x", - "tmp": "0.0.x" + "lru-cache": "2.2.4", + "tmp": "0.0.33" } }, "ws": { @@ -5554,9 +5558,9 @@ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "async-limiter": "1.0.0", + "safe-buffer": "5.1.2", + "ultron": "1.1.1" } }, "xmlhttprequest-ssl": { @@ -5573,7 +5577,7 @@ "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=", "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.1.7" } }, "karma-jasmine": { @@ -5588,8 +5592,8 @@ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", "dev": true, "requires": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" + "lodash": "4.17.10", + "phantomjs-prebuilt": "2.1.16" } }, "kew": { @@ -5604,7 +5608,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -5613,7 +5617,7 @@ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "labeled-stream-splicer": { @@ -5622,9 +5626,9 @@ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "isarray": "^2.0.4", - "stream-splicer": "^2.0.0" + "inherits": "2.0.3", + "isarray": "2.0.4", + "stream-splicer": "2.0.0" }, "dependencies": { "isarray": { @@ -5648,8 +5652,8 @@ "dev": true, "optional": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "lexical-scope": { @@ -5658,7 +5662,7 @@ "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", "dev": true, "requires": { - "astw": "^2.0.0" + "astw": "2.2.0" } }, "libbase64": { @@ -5704,11 +5708,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" } }, "lodash": { @@ -5742,9 +5746,9 @@ "dev": true, "optional": true, "requires": { - "json-stringify-safe": "5.0.x", - "request": "2.75.x", - "timespan": "2.3.x" + "json-stringify-safe": "5.0.1", + "request": "2.75.0", + "timespan": "2.3.0" }, "dependencies": { "assert-plus": { @@ -5775,9 +5779,9 @@ "dev": true, "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "har-validator": { @@ -5787,10 +5791,10 @@ "dev": true, "optional": true, "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" + "chalk": "1.1.3", + "commander": "2.15.1", + "is-my-json-valid": "2.19.0", + "pinkie-promise": "2.0.1" } }, "http-signature": { @@ -5800,9 +5804,9 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "qs": { @@ -5819,27 +5823,27 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.0.0", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.0.0", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "node-uuid": "1.4.8", + "oauth-sign": "0.8.2", + "qs": "6.2.3", + "stringstream": "0.0.6", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3" } }, "tunnel-agent": { @@ -5863,7 +5867,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.2" } }, "loud-rejection": { @@ -5872,8 +5876,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" } }, "lower-case": { @@ -5888,7 +5892,7 @@ "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", "dev": true, "requires": { - "lower-case": "^1.1.2" + "lower-case": "1.1.4" } }, "lru-cache": { @@ -5915,15 +5919,15 @@ "dev": true, "optional": true, "requires": { - "async": "~2.6.0", - "debug": "~3.1.0", - "form-data": "~2.3.0", - "inflection": "~1.12.0", - "is-stream": "^1.1.0", - "path-proxy": "~1.0.0", - "promisify-call": "^2.0.2", - "proxy-agent": "~3.0.0", - "tsscmp": "~1.0.0" + "async": "2.6.1", + "debug": "3.1.0", + "form-data": "2.3.2", + "inflection": "1.12.0", + "is-stream": "1.1.0", + "path-proxy": "1.0.0", + "promisify-call": "2.0.4", + "proxy-agent": "3.0.1", + "tsscmp": "1.0.6" }, "dependencies": { "async": { @@ -5933,7 +5937,7 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } }, "debug": { @@ -5966,7 +5970,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "^1.0.0" + "object-visit": "1.0.1" } }, "math-random": { @@ -5981,10 +5985,10 @@ "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", "dev": true, "requires": { - "chalk": "^1.0.0", - "figures": "^1.0.1", - "gzip-size": "^1.0.0", - "pretty-bytes": "^1.0.0" + "chalk": "1.1.3", + "figures": "1.7.0", + "gzip-size": "1.0.0", + "pretty-bytes": "1.0.4" } }, "md5.js": { @@ -5993,8 +5997,8 @@ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "media-typer": { @@ -6009,16 +6013,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" }, "dependencies": { "minimist": { @@ -6035,19 +6039,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" } }, "miller-rabin": { @@ -6056,8 +6060,8 @@ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "bn.js": "4.11.8", + "brorand": "1.1.0" } }, "mime": { @@ -6078,7 +6082,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" } }, "minimalistic-assert": { @@ -6099,7 +6103,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -6114,8 +6118,8 @@ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "for-in": "1.0.2", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -6124,7 +6128,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -6172,7 +6176,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -6183,21 +6187,21 @@ "integrity": "sha512-NPs5N511VD1rrVJihSso/LiBShRbJALYBKzDW91uZYy7BpjnO4bGnZL3HjZ9yKcFdZUWwaYjDz9zxbuP7vKMuQ==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.0", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.0.2", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "defined": "1.0.0", + "detective": "5.1.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.6", + "resolve": "1.7.1", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "resolve": { @@ -6206,7 +6210,7 @@ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } } } @@ -6230,17 +6234,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "arr-diff": { @@ -6269,7 +6273,7 @@ "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", "dev": true, "requires": { - "xml-char-classes": "^1.0.0" + "xml-char-classes": "1.0.0" } }, "negotiator": { @@ -6291,18 +6295,18 @@ "integrity": "sha1-3D/FG6Cy+LOF2+BH9NoG9YCh/WE=", "dev": true, "requires": { - "acorn": "~2.6.4", - "alter": "~0.2.0", - "convert-source-map": "~1.1.2", - "optimist": "~0.6.1", - "ordered-ast-traverse": "~1.1.1", - "simple-fmt": "~0.1.0", - "simple-is": "~0.2.0", - "source-map": "~0.5.3", - "stable": "~0.1.5", - "stringmap": "~0.2.2", - "stringset": "~0.2.1", - "tryor": "~0.1.2" + "acorn": "2.6.4", + "alter": "0.2.0", + "convert-source-map": "1.1.3", + "optimist": "0.6.1", + "ordered-ast-traverse": "1.1.1", + "simple-fmt": "0.1.0", + "simple-is": "0.2.0", + "source-map": "0.5.7", + "stable": "0.1.8", + "stringmap": "0.2.2", + "stringset": "0.2.1", + "tryor": "0.1.2" }, "dependencies": { "acorn": { @@ -6325,7 +6329,7 @@ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "1.1.4" } }, "node-uuid": { @@ -6358,8 +6362,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.2", - "smart-buffer": "^1.0.4" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } } } @@ -6426,7 +6430,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.1.1" } }, "normalize-package-data": { @@ -6435,10 +6439,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -6447,7 +6451,15 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" } }, "number-is-nan": { @@ -6480,9 +6492,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" }, "dependencies": { "define-property": { @@ -6491,7 +6503,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -6508,7 +6520,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "^3.0.0" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6525,10 +6537,10 @@ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "has-symbols": "1.0.0", + "object-keys": "1.0.11" } }, "object.omit": { @@ -6537,8 +6549,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "object.pick": { @@ -6547,7 +6559,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6573,7 +6585,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "optimist": { @@ -6582,8 +6594,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.2" } }, "optionator": { @@ -6593,12 +6605,12 @@ "dev": true, "optional": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" }, "dependencies": { "wordwrap": { @@ -6616,7 +6628,7 @@ "integrity": "sha1-aEOhcLwO7otSDMjdwd3TqjD6BXw=", "dev": true, "requires": { - "ordered-esprima-props": "~1.1.0" + "ordered-esprima-props": "1.1.0" } }, "ordered-esprima-props": { @@ -6649,7 +6661,7 @@ "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", "dev": true, "requires": { - "shell-quote": "^1.4.2" + "shell-quote": "1.6.1" } }, "output-file-sync": { @@ -6658,9 +6670,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" } }, "pac-proxy-agent": { @@ -6670,14 +6682,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^3.0.0" + "agent-base": "4.2.1", + "debug": "3.1.0", + "get-uri": "2.0.2", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "pac-resolver": "3.0.0", + "raw-body": "2.3.3", + "socks-proxy-agent": "3.0.1" }, "dependencies": { "bytes": { @@ -6717,8 +6729,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" + "agent-base": "4.2.1", + "socks": "1.1.10" } } } @@ -6730,11 +6742,11 @@ "dev": true, "optional": true, "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" + "co": "4.6.0", + "degenerator": "1.0.4", + "ip": "1.1.5", + "netmask": "1.0.6", + "thunkify": "2.1.2" } }, "pako": { @@ -6749,7 +6761,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "parents": { @@ -6758,7 +6770,7 @@ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "requires": { - "path-platform": "~0.11.15" + "path-platform": "0.11.15" } }, "parse-asn1": { @@ -6767,11 +6779,11 @@ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.16" } }, "parse-glob": { @@ -6780,10 +6792,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-json": { @@ -6792,7 +6804,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "parseqs": { @@ -6801,7 +6813,7 @@ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseuri": { @@ -6810,7 +6822,7 @@ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseurl": { @@ -6825,8 +6837,8 @@ "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", "dev": true, "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "upper-case-first": "1.1.2" } }, "pascalcase": { @@ -6847,7 +6859,7 @@ "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "path-dirname": { @@ -6862,7 +6874,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-is-absolute": { @@ -6871,6 +6883,11 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -6890,7 +6907,7 @@ "dev": true, "optional": true, "requires": { - "inflection": "~1.3.0" + "inflection": "1.3.8" }, "dependencies": { "inflection": { @@ -6908,9 +6925,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pathval": { @@ -6925,11 +6942,11 @@ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "pend": { @@ -6950,15 +6967,15 @@ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", "dev": true, "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" + "es6-promise": "4.2.4", + "extract-zip": "1.6.7", + "fs-extra": "1.0.0", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.87.0", + "request-progress": "2.0.1", + "which": "1.3.1" } }, "pify": { @@ -6979,7 +6996,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "posix-character-classes": { @@ -7006,8 +7023,8 @@ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.1.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "private": { @@ -7041,7 +7058,7 @@ "dev": true, "optional": true, "requires": { - "with-callback": "^1.0.2" + "with-callback": "1.0.2" } }, "proxy-agent": { @@ -7051,14 +7068,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^2.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" + "agent-base": "4.2.1", + "debug": "3.1.0", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "lru-cache": "4.1.3", + "pac-proxy-agent": "2.0.2", + "proxy-from-env": "1.0.0", + "socks-proxy-agent": "4.0.1" }, "dependencies": { "debug": { @@ -7078,8 +7095,8 @@ "dev": true, "optional": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pseudomap": "1.0.2", + "yallist": "2.1.2" } } } @@ -7104,11 +7121,11 @@ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", + "randombytes": "2.0.6" } }, "punycode": { @@ -7147,9 +7164,9 @@ "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "dev": true, "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { "is-number": { @@ -7172,7 +7189,7 @@ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "safe-buffer": "5.1.2" } }, "randomfill": { @@ -7181,8 +7198,8 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "randombytes": "2.0.6", + "safe-buffer": "5.1.2" } }, "range-parser": { @@ -7197,8 +7214,8 @@ "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { - "bytes": "1", - "string_decoder": "0.10" + "bytes": "1.0.0", + "string_decoder": "0.10.31" }, "dependencies": { "string_decoder": { @@ -7215,7 +7232,7 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "read-pkg": { @@ -7224,9 +7241,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -7235,8 +7252,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "readable-stream": { @@ -7245,13 +7262,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -7260,10 +7277,10 @@ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.6", + "set-immediate-shim": "1.0.1" } }, "redent": { @@ -7272,8 +7289,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "2.1.0", + "strip-indent": "1.0.1" } }, "redis": { @@ -7283,9 +7300,9 @@ "dev": true, "optional": true, "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.5", + "redis-parser": "2.6.0" } }, "redis-commands": { @@ -7320,9 +7337,9 @@ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" } }, "regex-cache": { @@ -7331,7 +7348,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3" + "is-equal-shallow": "0.1.3" } }, "regex-not": { @@ -7340,8 +7357,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "regexpu-core": { @@ -7350,9 +7367,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -7367,7 +7384,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" }, "dependencies": { "jsesc": { @@ -7408,7 +7425,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "request": { @@ -7417,26 +7434,26 @@ "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "dev": true, "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" } }, "request-progress": { @@ -7445,7 +7462,7 @@ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", "dev": true, "requires": { - "throttleit": "^1.0.0" + "throttleit": "1.0.0" } }, "requestretry": { @@ -7455,10 +7472,10 @@ "dev": true, "optional": true, "requires": { - "extend": "^3.0.0", - "lodash": "^4.15.0", - "request": "^2.74.0", - "when": "^3.7.7" + "extend": "3.0.1", + "lodash": "4.17.10", + "request": "2.87.0", + "when": "3.7.8" } }, "requires-port": { @@ -7491,7 +7508,7 @@ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -7500,7 +7517,7 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "ripemd160": { @@ -7509,8 +7526,8 @@ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "safe-buffer": { @@ -7531,7 +7548,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "~0.1.10" + "ret": "0.1.15" } }, "safer-buffer": { @@ -7553,18 +7570,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" }, "dependencies": { "mime": { @@ -7587,8 +7604,8 @@ "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" + "no-case": "2.3.2", + "upper-case-first": "1.1.2" } }, "serve-static": { @@ -7597,9 +7614,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.2" } }, @@ -7615,10 +7632,10 @@ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" }, "dependencies": { "extend-shallow": { @@ -7627,7 +7644,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7644,8 +7661,8 @@ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "shasum": { @@ -7654,8 +7671,8 @@ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.11" } }, "shell-quote": { @@ -7664,10 +7681,10 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" } }, "signal-exit": { @@ -7695,7 +7712,7 @@ "dev": true, "optional": true, "requires": { - "requestretry": "^1.2.2" + "requestretry": "1.13.0" } }, "slash": { @@ -7728,9 +7745,9 @@ "dev": true }, "sn-stylekit": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-1.0.15.tgz", - "integrity": "sha512-QeWlaCMHtF/VhFWWICzmx39ger92DEj1uLiCW4VVLX9LtU7nKQ5plqHgrpvnctO+wNh9LIYdPBLLWxTwgXm6Eg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-1.1.7.tgz", + "integrity": "sha512-GIP5PZWZjrvGWV9FI1O0hCYpG8MtyjQIjFpsgi2oM4MT4G5X8sAdyLmtfo5fYNJgIpq91+xu5IY+GyzsnLLBXQ==", "dev": true }, "snake-case": { @@ -7739,7 +7756,7 @@ "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "snapdragon": { @@ -7748,14 +7765,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.1" }, "dependencies": { "define-property": { @@ -7764,7 +7781,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -7773,7 +7790,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7784,9 +7801,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" }, "dependencies": { "define-property": { @@ -7795,7 +7812,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -7804,7 +7821,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -7813,7 +7830,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -7822,9 +7839,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -7847,7 +7864,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "^3.2.0" + "kind-of": "3.2.2" } }, "sntp": { @@ -7857,7 +7874,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "socks": { @@ -7867,8 +7884,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } }, "socks-proxy-agent": { @@ -7878,8 +7895,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" + "agent-base": "4.2.1", + "socks": "2.2.1" }, "dependencies": { "smart-buffer": { @@ -7896,8 +7913,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" + "ip": "1.1.5", + "smart-buffer": "4.0.1" } } } @@ -7914,11 +7931,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "atob": "2.1.2", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" } }, "source-map-support": { @@ -7927,7 +7944,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.7" } }, "source-map-url": { @@ -7942,8 +7959,8 @@ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, "spdx-exceptions": { @@ -7958,8 +7975,8 @@ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" } }, "spdx-license-ids": { @@ -7974,7 +7991,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "^3.0.0" + "extend-shallow": "3.0.2" } }, "sprintf-js": { @@ -7989,14 +8006,14 @@ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" } }, "stable": { @@ -8017,8 +8034,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "define-property": "0.2.5", + "object-copy": "0.1.0" }, "dependencies": { "define-property": { @@ -8027,7 +8044,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -8044,8 +8061,8 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "stream-combiner2": { @@ -8054,8 +8071,8 @@ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" + "duplexer2": "0.1.4", + "readable-stream": "2.3.6" } }, "stream-http": { @@ -8064,11 +8081,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" } }, "stream-splicer": { @@ -8077,8 +8094,8 @@ "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "streamroller": { @@ -8087,10 +8104,10 @@ "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { - "date-format": "^1.2.0", - "debug": "^3.1.0", - "mkdirp": "^0.5.1", - "readable-stream": "^2.3.0" + "date-format": "1.2.0", + "debug": "3.1.0", + "mkdirp": "0.5.1", + "readable-stream": "2.3.6" }, "dependencies": { "debug": { @@ -8116,7 +8133,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } }, "stringmap": { @@ -8142,9 +8159,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -8153,7 +8169,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "strip-indent": { @@ -8162,7 +8178,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "^4.0.1" + "get-stdin": "4.0.1" } }, "subarg": { @@ -8171,7 +8187,7 @@ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "requires": { - "minimist": "^1.1.0" + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -8185,8 +8201,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "swap-case": { "version": "1.1.2", @@ -8194,8 +8209,8 @@ "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", "dev": true, "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" + "lower-case": "1.1.4", + "upper-case": "1.1.3" } }, "syntax-error": { @@ -8204,7 +8219,7 @@ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "requires": { - "acorn-node": "^1.2.0" + "acorn-node": "1.3.0" } }, "throttleit": { @@ -8225,8 +8240,8 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "readable-stream": "2.3.6", + "xtend": "4.0.1" } }, "thunkify": { @@ -8242,7 +8257,7 @@ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "requires": { - "process": "~0.11.0" + "process": "0.11.10" } }, "timespan": { @@ -8258,12 +8273,12 @@ "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" + "body": "5.1.0", + "debug": "3.1.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.3.0", + "object-assign": "4.1.1", + "qs": "6.5.2" }, "dependencies": { "debug": { @@ -8283,8 +8298,8 @@ "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "to-array": { @@ -8311,7 +8326,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "to-regex": { @@ -8320,10 +8335,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -8332,8 +8347,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "3.0.0", + "repeat-string": "1.6.1" }, "dependencies": { "is-number": { @@ -8342,7 +8357,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } } } @@ -8353,7 +8368,7 @@ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "trim-newlines": { @@ -8393,7 +8408,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "tweetnacl": { @@ -8409,7 +8424,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-detect": { @@ -8425,7 +8440,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" } }, "typedarray": { @@ -8440,10 +8455,10 @@ "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "async": "0.2.10", + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" }, "dependencies": { "async": { @@ -8473,13 +8488,13 @@ "dev": true }, "underscore.string": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz", - "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", "dev": true, "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" + "sprintf-js": "1.1.1", + "util-deprecate": "1.0.2" } }, "union-value": { @@ -8488,10 +8503,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" }, "dependencies": { "extend-shallow": { @@ -8500,7 +8515,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "set-value": { @@ -8509,10 +8524,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" } } } @@ -8529,8 +8544,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "has-value": "0.3.1", + "isobject": "3.0.1" }, "dependencies": { "has-value": { @@ -8539,9 +8554,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" }, "dependencies": { "isobject": { @@ -8587,7 +8602,7 @@ "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", "dev": true, "requires": { - "upper-case": "^1.1.1" + "upper-case": "1.1.3" } }, "uri-path": { @@ -8672,7 +8687,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "^1.1.1" + "user-home": "1.1.1" } }, "validate-npm-package-license": { @@ -8681,8 +8696,8 @@ "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "verror": { @@ -8691,9 +8706,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "^1.0.0", + "assert-plus": "1.0.0", "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "extsprintf": "1.3.0" } }, "vm-browserify": { @@ -8714,13 +8729,13 @@ "integrity": "sha512-7jWG0c3cKKm2hKScnSAMUEUjRJKXUShwMPk0ASVhICycQhwND3IMAdhJYmc1mxxKzBUJTSF5HZizfrKrS6BzkA==", "dev": true, "requires": { - "anymatch": "^1.3.0", - "browserify": "^16.1.0", - "chokidar": "^1.0.0", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "anymatch": "1.3.2", + "browserify": "16.2.2", + "chokidar": "1.7.0", + "defined": "1.0.0", + "outpipe": "1.1.1", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "websocket-driver": { @@ -8729,8 +8744,8 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" + "http-parser-js": "0.4.13", + "websocket-extensions": "0.1.3" } }, "websocket-extensions": { @@ -8752,7 +8767,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "window-size": { @@ -8812,9 +8827,9 @@ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" }, "dependencies": { @@ -8832,7 +8847,7 @@ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "fd-slicer": "1.0.1" } }, "yeast": { diff --git a/package.json b/package.json index 7c64b522a..6aed6a3dd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "bower": "^1.8.0", "chai": "^4.1.2", "connect": "^3.6.6", - "grunt": "^1.0.1", + "grunt": "^1.0.3", "grunt-angular-templates": "^1.1.0", "grunt-babel": "^6.0.0", "grunt-browserify": "^5.0.0", @@ -44,7 +44,10 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "1.0.15", + "sn-stylekit": "1.1.7", "standard-file-js": "0.3.19" + }, + "dependencies": { + "grunt-shell": "^2.1.0" } } From 7f07004d5f318eb4e84897381f34e295c0437575 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 10 Dec 2018 18:06:24 -0600 Subject: [PATCH 17/62] Styles --- app/assets/stylesheets/app/_editor.scss | 2 +- app/assets/stylesheets/app/_main.scss | 2 +- app/assets/templates/directives/permissions-modal.html.haml | 2 +- public/extensions/batch-manager | 2 +- public/extensions/extensions-manager | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 5cf5f3d6f..0e1ad718e 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -60,7 +60,7 @@ $heading-height: 75px; font-weight: normal; margin-top: 4px; text-align: right; - color: var(--sn-stylekit-contrast-background-color); + color: var(--sn-stylekit-neutral-color); } .editor-tags { diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index 329437ee2..caa68d27a 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -148,7 +148,7 @@ $footer-height: 32px; &.collapsed { opacity: 1; - background-color: #DDDDDD; + background-color: var(--sn-stylekit-contrast-background-color); } &.dragging { diff --git a/app/assets/templates/directives/permissions-modal.html.haml b/app/assets/templates/directives/permissions-modal.html.haml index dc8fb2af3..9c797a243 100644 --- a/app/assets/templates/directives/permissions-modal.html.haml +++ b/app/assets/templates/directives/permissions-modal.html.haml @@ -9,7 +9,7 @@ .sk-panel-content .sk-panel-section .sk-panel-row - .sk-h3 + .sk-h2 %strong {{component.name}} would like to interact with your {{permissionsString()}} diff --git a/public/extensions/batch-manager b/public/extensions/batch-manager index 3c8a9ffd7..04a930d26 160000 --- a/public/extensions/batch-manager +++ b/public/extensions/batch-manager @@ -1 +1 @@ -Subproject commit 3c8a9ffd7c8fc8d3d04c258d3e5fddb0633a74b9 +Subproject commit 04a930d26505cfa05a4bf6472fe2e7fdea26d940 diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index 68b78744c..dd7e1ade8 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit 68b78744cbcac3812f07dea59a407b670ab4c5e7 +Subproject commit dd7e1ade8d64ea51902fc0cd12d90afc2411fd43 From ba781f27656c01b507f9825b93285de1f87c83a5 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 11 Dec 2018 09:08:10 -0600 Subject: [PATCH 18/62] Style updates --- Gruntfile.js | 2 +- .../javascripts/app/controllers/editor.js | 18 ++++++++------ app/assets/stylesheets/app/_editor.scss | 5 ++-- app/assets/stylesheets/app/_lock-screen.scss | 2 +- app/assets/stylesheets/app/_main.scss | 2 +- .../directives/account-menu.html.haml | 24 ++++++++++--------- .../directives/password-wizard.html.haml | 6 ++--- app/assets/templates/editor.html.haml | 14 +++++------ app/assets/templates/footer.html.haml | 2 +- app/assets/templates/lock-screen.html.haml | 2 +- 10 files changed, 42 insertions(+), 35 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f35fa3316..ab803c3cc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -166,6 +166,6 @@ module.exports = function(grunt) { grunt.registerTask('default', ['haml', 'ngtemplates', 'sass', 'concat:app', 'babel', 'browserify', 'concat:lib', 'concat:dist', 'ngAnnotate', 'concat:css', 'uglify']); - grunt.registerTask('vendor', ['concat:app', 'babel', 'browserify', + grunt.registerTask('vendor', ['concat:app', 'sass', 'babel', 'browserify', 'concat:lib', 'concat:dist', 'ngAnnotate', 'concat:css', 'uglify']); }; diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 1edba4c77..c1a4416a3 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -170,19 +170,23 @@ angular.module('app') } } - this.onEditorMenuClick = function() { - // App bar menu item click - this.showEditorMenu = !this.showEditorMenu; - this.showMenu = false; - this.showExtensions = false; - } - this.closeAllMenus = function() { this.showEditorMenu = false; this.showMenu = false; this.showExtensions = false; } + this.toggleMenu = function(menu) { + this[menu] = !this[menu]; + + let allMenus = ['showMenu', 'showEditorMenu', 'showExtensions', 'showSessionHistory']; + for(var candidate of allMenus) { + if(candidate != menu) { + this[candidate] = false; + } + } + } + this.editorMenuOnSelect = function(component) { if(!component || component.area == "editor-editor") { // if plain editor or other editor diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index ed59df22a..65eb89e1f 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -60,7 +60,7 @@ $heading-height: 75px; font-weight: normal; margin-top: 4px; text-align: right; - color: var(--sn-stylekit-neutral-color); + color: var(--sn-stylekit-secondary-contrast-background-color); } .editor-tags { @@ -133,9 +133,10 @@ $heading-height: 75px; iframe { width: 100%; + background-color: var(--sn-stylekit-background-color); // we moved the border top from the .component-stack-item to the .iframe, as on parent, // it increases its height and caused unneccessary scrollbars on windows. - border-top: 1px solid var(--sn-component-border-color); + border-top: 1px solid var(--sn-stylekit-border-color); } } } diff --git a/app/assets/stylesheets/app/_lock-screen.scss b/app/assets/stylesheets/app/_lock-screen.scss index 4a7f57b66..5e135881e 100644 --- a/app/assets/stylesheets/app/_lock-screen.scss +++ b/app/assets/stylesheets/app/_lock-screen.scss @@ -12,7 +12,7 @@ bottom: 0; z-index: $z-index-lock-screen; - background-color: var(--sn-stylekit-background-color); + background-color: var(--sn-stylekit-contrast-background-color); color: var(--sn-stylekit-foreground-color); font-size: 16px; display: flex; diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index caa68d27a..ada2d1d9b 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -118,7 +118,7 @@ $footer-height: 32px; position: absolute; cursor: col-resize; // needs to be a color that works on main bg and contrast bg - background-color: var(--sn-stylekit-on-contrast-background-color); + background-color: var(--sn-stylekit-secondary-contrast-background-color); opacity: 0; border-top: none; border-bottom: none; diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index ae61a0577..9cff2a4b0 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -4,16 +4,16 @@ .sk-panel-header-title Account %a.sk-a.infoclose-button{"ng-click" => "close()"} Close .sk-panel-content - .sk-panel-section.hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} - .sk-panel-section-title Sign in or register to enable sync and end-to-end encryption. + .sk-panel-section.sk-panel-hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} .sk-panel-row + .sk-h1 Sign in or register to enable sync and end-to-end encryption. .sk-panel-row .sk-button-group.stretch .sk-button.info.featured{"ng-click" => "formData.showLogin = true"} .sk-label Sign In .sk-button.info.featured{"ng-click" => "formData.showRegister = true"} .sk-label Register - %p + .sk-panel-row.sk-p Standard Notes is free on every platform, and comes standard with sync and encryption. .sk-panel-section{"ng-if" => "formData.showLogin || formData.showRegister"} @@ -21,22 +21,22 @@ {{formData.showLogin ? "Sign In" : "Register"}} %form.sk-panel-form{"ng-submit" => "submitAuthForm()"} - %input{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} - %input{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} - %input{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf'} + %input.sk-input.contrast{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} + %input.sk-input.contrast{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} + %input.sk-input.contrast{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf'} %a.sk-panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} Advanced Options - .sk-notification.info{"ng-if" => "formData.showRegister"} + .sk-notification.neutral{"ng-if" => "formData.showRegister"} .sk-notification-title No Password Reset. .sk-notification-text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. - .sk-notification.unpadded.default.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} + .sk-notification.unpadded.contrast.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} .sk-panel-column.stretch .sk-notification-title.sk-panel-row.padded-row Advanced Options %div.bordered-row.padded-row %label.sk-label Sync Server Domain - %input.sk-input.mt-5.sk-input{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} + %input.sk-input.mt-5.sk-base{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} %label.sk-label.padded-row{"ng-if" => "formData.showLogin"} %input.sk-input{"type" => "checkbox", "ng-model" => "formData.strictSignin"} Use strict sign in @@ -47,9 +47,11 @@ %button.sk-button.info.featured{"type" => "submit", "ng-disabled" => "formData.authenticating"} .sk-label {{formData.showLogin ? "Sign In" : "Register"}} + .sk-panel-row %label %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} Stay signed in + .sk-panel-row %label{"ng-if" => "notesAndTagsCount() > 0"} %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} Merge local data ({{notesAndTagsCount()}} notes and tags) @@ -113,8 +115,8 @@ %form.sk-panel-form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} .sk-panel-row - %input.sk-input{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} - %input.sk-input{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} .sk-button-group.stretch.sk-panel-row.form-submit %button.sk-button.info{"type" => "submit"} .sk-label Set Passcode diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index 70a856aa2..207c9e8c9 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -68,9 +68,9 @@ .sk-panel-row .sk-panel-column.stretch %form.sk-panel-form - %input.sk-input{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} - %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} - %input.sk-input{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input.contrast{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} + %input.sk-input.contrast{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} %div{"ng-if" => "step == 4"} %p.sk-panel-row diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index d33f6f985..dfea92eed 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -25,7 +25,7 @@ .sn-component{"ng-if" => "ctrl.note"} .sk-app-bar.no-edges .left - .sk-app-bar-item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showMenu')", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} .sk-label Options .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} .sk-menu-panel-section @@ -41,24 +41,24 @@ .sk-menu-panel-header .sk-menu-panel-header-title Global Display - %menu-row{"label" => "'Monospace Font'", "circle" => "ctrl.monospaceFont ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('monospaceFont')", + %menu-row{"label" => "'Monospace Font'", "circle" => "ctrl.monospaceFont ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('monospaceFont')", "desc" => "'Toggles the font style for the default editor'", "subtitle" => "ctrl.selectedEditor ? 'Not available with editor extensions' : null", "disabled" => "ctrl.selectedEditor"} - %menu-row{"label" => "'Spellcheck'", "circle" => "ctrl.spellcheck ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('spellcheck')", + %menu-row{"label" => "'Spellcheck'", "circle" => "ctrl.spellcheck ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('spellcheck')", "desc" => "'Toggles spellcheck for the default editor'", "subtitle" => "ctrl.selectedEditor ? 'Not available with editor extensions' : null", "disabled" => "ctrl.selectedEditor"} - %menu-row{"label" => "'Margin Resizers'", "circle" => "ctrl.marginResizersEnabled ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('marginResizersEnabled')", + %menu-row{"label" => "'Margin Resizers'", "circle" => "ctrl.marginResizersEnabled ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('marginResizersEnabled')", "desc" => "'Allows for editor left and right margins to be resized'", "faded" => "!ctrl.marginResizersEnabled"} - .sk-app-bar-item{"ng-click" => "ctrl.onEditorMenuClick()", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showEditorMenu')", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} .sk-label Editor %editor-menu{"ng-if" => "ctrl.showEditorMenu", "callback" => "ctrl.editorMenuOnSelect", "selected-editor" => "ctrl.selectedEditor", "current-item" => "ctrl.note"} - .sk-app-bar-item{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showExtensions')", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} .sk-label Actions %actions-menu{"ng-if" => "ctrl.showExtensions", "item" => "ctrl.note"} - .sk-app-bar-item{"ng-click" => "ctrl.showSessionHistory = !ctrl.showSessionHistory; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showSessionHistory')", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} .sk-label Session History %session-history-menu{"ng-if" => "ctrl.showSessionHistory", "item" => "ctrl.note"} diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index edf43f615..41ac65bb7 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -3,7 +3,7 @@ .left .sk-app-bar-item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} .sk-app-bar-item-column - .sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} + .sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'neutral')"} .sk-app-bar-item-column .sk-label.title{"ng-class" => "{red: ctrl.error}"} Account %account-menu{"ng-click" => "$event.stopPropagation()", "ng-if" => "ctrl.showAccountMenu", "on-successful-auth" => "ctrl.onAuthSuccess", "close-function" => "ctrl.closeAccountMenu"} diff --git a/app/assets/templates/lock-screen.html.haml b/app/assets/templates/lock-screen.html.haml index 46cde4e19..890b495b2 100644 --- a/app/assets/templates/lock-screen.html.haml +++ b/app/assets/templates/lock-screen.html.haml @@ -6,7 +6,7 @@ .sk-panel-section %form.sk-panel-form.sk-panel-row{"ng-submit" => "submitPasscodeForm()"} .sk-panel-column.stretch - %input.sk-panel-row.sk-input{:type => 'password', + %input.center-text.sk-input.contrast{:type => 'password', "ng-model" => "formData.passcode", "autofocus" => "true", "sn-autofocus" => "true", "should-focus" => "true", "placeholder" => "Enter Passcode", "autocomplete" => "new-password"} .sk-button-group.stretch.sk-panel-row.form-submit From 65dc1838b9c2fc85787b904b50af3c8855161d5a Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 11 Dec 2018 10:59:36 -0600 Subject: [PATCH 19/62] Update sfjs --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a83c4b96..31193042a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8969,9 +8969,9 @@ "dev": true }, "standard-file-js": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.19.tgz", - "integrity": "sha512-H23VzukJescWRQp8WoSGm/arU7KzglC7bY7sGy8AwCcStxvAz278VqysGTnwQGpObxEHsp9hKucnV34RhASLtA==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.20.tgz", + "integrity": "sha512-KlJ3IbAaJDRVC8jKxHBi/LL80d8zIbL1nZqwbDmqif1XwDQpTb8BB7ejg5pzZExQKDRFeXLS0JDSeWGMD+Luhw==", "dev": true }, "static-extend": { diff --git a/package.json b/package.json index 8d878f237..c533efa89 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "serve-static": "^1.13.2", "sn-models": "0.1.9", "sn-stylekit": "file:~/Desktop/sn/dev/stylekit", - "standard-file-js": "0.3.19", + "standard-file-js": "0.3.20", "grunt-shell": "^2.1.0" } } From 3fb183b194568b0cfaf43d716003f90d9f2a4b2e Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 12 Dec 2018 11:59:50 -0600 Subject: [PATCH 20/62] Account panel UI --- .../app/directives/views/accountMenu.js | 7 ++- .../directives/account-menu.html.haml | 57 +++++++++++-------- .../directives/component-modal.html.haml | 4 +- public/extensions/extensions-manager | 2 +- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index ae33c16c2..67254176b 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -14,6 +14,11 @@ class AccountMenu { 'ngInject'; $scope.formData = {mergeLocal: true, ephemeral: false}; + + // testing: + // $scope.formData.status = "Generating Login Keys..."; + // $scope.formData.authenticating = true; + $scope.user = authManager.user; syncManager.getServerURL().then((url) => { @@ -171,7 +176,7 @@ class AccountMenu { $scope.openPrivilegesModal = async function() { $scope.close(); - + let run = () => { $timeout(() => { privilegesManager.presentPrivilegesManagementModal(); diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 436ef6a74..f16f8b4c8 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -21,12 +21,10 @@ {{formData.showLogin ? "Sign In" : "Register"}} %form.sk-panel-form{"ng-submit" => "submitAuthForm()"} - %input.sk-input.contrast{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} - %input.sk-input.contrast{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} - %input.sk-input.contrast{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf'} - - %a.sk-panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} - Advanced Options + .sk-panel-section + %input.sk-input.contrast{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} + %input.sk-input.contrast{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password', 'sn-enter' => 'submitAuthForm()'} + %input.sk-input.contrast{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf', 'sn-enter' => 'submitAuthForm()'} .sk-notification.unpadded.contrast.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} .sk-panel-column.stretch @@ -40,33 +38,46 @@ %span %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} (Learn more) - .sk-button-group.stretch.sk-panel-row.form-submit - %button.sk-button.info.featured{"type" => "submit", "ng-disabled" => "formData.authenticating"} + .sk-panel-section.form-submit{"ng-if" => "!formData.authenticating"} + .sk-button.info.featured{'ng-click' => 'submitAuthForm()', "ng-disabled" => "formData.authenticating"} .sk-label {{formData.showLogin ? "Sign In" : "Register"}} .sk-notification.neutral{"ng-if" => "formData.showRegister"} .sk-notification-title No Password Reset. .sk-notification-text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. - .sk-panel-row - %label - %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} - Stay signed in - %label{"ng-if" => "notesAndTagsCount() > 0"} - .sk-panel-row - %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} - Merge local data ({{notesAndTagsCount()}} notes and tags) + .sk-panel-section.no-bottom-pad{"ng-if" => "formData.status"} + .sk-horizontal-group + .sk-spinner.small.neutral + .sk-label {{formData.status}} - %em.block.center-align.mt-10{"ng-if" => "formData.status", "style" => "font-size: 14px;"} - {{formData.status}} + .sk-panel-section.no-bottom-pad{"ng-if" => "!formData.authenticating"} + %label.sk-panel-row.justify-left + .sk-horizontal-group + %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} + Stay signed in + %label.sk-panel-row.justify-left{"ng-if" => "notesAndTagsCount() > 0"} + .sk-panel-row + %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} + Merge local data ({{notesAndTagsCount()}} notes and tags) + .sk-panel-row + %a.sk-panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} + Advanced Options .sk-panel-section{"ng-if" => "formData.mfa"} - %form{"ng-submit" => "submitMfaForm()"} - %p {{formData.mfa.message}} - %input.sk-input.mt-10{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} - .sk-button-group.stretch.sk-panel-row.form-submit - %button.button.info.featured{"type" => "submit"} + %form.sk-panel-form{"ng-submit" => "submitMfaForm()"} + .sk-p.sk-panel-row {{formData.mfa.message}} + .sk-panel-row + %input.sk-input.contrast{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} + .sk-button-group.stretch.sk-panel-row.form-submit{"ng-if" => "!formData.status"} + %button.sk-button.info.featured{"type" => "submit"} .sk-label Sign In + .sk-panel-section.no-bottom-pad{"ng-if" => "formData.status"} + .sk-panel-row + .sk-panel-row + .sk-horizontal-group + .sk-spinner.small.neutral + .sk-label {{formData.status}} %div{"ng-if" => "!formData.showLogin && !formData.showRegister && !formData.mfa"} .sk-panel-section{"ng-if" => "user"} diff --git a/app/assets/templates/directives/component-modal.html.haml b/app/assets/templates/directives/component-modal.html.haml index cb50246e4..4501b11aa 100644 --- a/app/assets/templates/directives/component-modal.html.haml +++ b/app/assets/templates/directives/component-modal.html.haml @@ -1,6 +1,6 @@ -.background{"ng-click" => "dismiss()"} +.sk-modal-background{"ng-click" => "dismiss()"} -.content{"ng-attr-id" => "component-content-outer-{{component.uuid}}"} +.sk-modal-content{"ng-attr-id" => "component-content-outer-{{component.uuid}}"} .sn-component .sk-panel{"ng-attr-id" => "component-content-inner-{{component.uuid}}"} .sk-panel-header diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index dd7e1ade8..883b90515 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit dd7e1ade8d64ea51902fc0cd12d90afc2411fd43 +Subproject commit 883b90515c96923617cb08a2007d1a5bbfdc9c67 From cd8e94104e8364181e5ceaf750f9a0fde5cff161 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 12 Dec 2018 14:46:24 -0600 Subject: [PATCH 21/62] Cache active themes --- .../javascripts/app/services/themeManager.js | 71 +++++++++++++++++-- app/assets/stylesheets/app/_lock-screen.scss | 11 +-- app/assets/templates/lock-screen.html.haml | 5 +- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/app/services/themeManager.js b/app/assets/javascripts/app/services/themeManager.js index d5bec58e3..76a473ebe 100644 --- a/app/assets/javascripts/app/services/themeManager.js +++ b/app/assets/javascripts/app/services/themeManager.js @@ -1,9 +1,27 @@ class ThemeManager { - constructor(componentManager, desktopManager) { + constructor(componentManager, desktopManager, storageManager) { this.componentManager = componentManager; + this.storageManager = storageManager; + this.desktopManager = desktopManager; + this.activeThemes = []; - desktopManager.registerUpdateObserver((component) => { + ThemeManager.CachedThemesKey = "cachedThemes"; + + this.registerObservers(); + this.activateCachedThemes(); + } + + activateCachedThemes() { + let cachedThemes = this.getCachedThemes(); + let writeToCache = false; + for(var theme of cachedThemes) { + this.activateTheme(theme, writeToCache); + } + } + + registerObservers() { + this.desktopManager.registerUpdateObserver((component) => { // Reload theme if active if(component.active && component.isTheme()) { this.deactivateTheme(component); @@ -13,7 +31,7 @@ class ThemeManager { } }) - componentManager.registerHandler({identifier: "themeManager", areas: ["themes"], activationHandler: (component) => { + this.componentManager.registerHandler({identifier: "themeManager", areas: ["themes"], activationHandler: (component) => { if(component.active) { this.activateTheme(component); } else { @@ -33,9 +51,19 @@ class ThemeManager { this.componentManager.deactivateComponent(theme); } } + + this.decacheThemes(); } - activateTheme(theme) { + activateTheme(theme, writeToCache = true) { + if(_.find(this.activeThemes, {uuid: theme.uuid})) { + return; + } + + console.log("Activating theme", theme.uuid); + + this.activeThemes.push(theme); + var url = this.componentManager.urlForComponent(theme); var link = document.createElement("link"); link.href = url; @@ -44,6 +72,10 @@ class ThemeManager { link.media = "screen,print"; link.id = theme.uuid; document.getElementsByTagName("head")[0].appendChild(link); + + if(writeToCache) { + this.cacheThemes(); + } } deactivateTheme(theme) { @@ -52,6 +84,37 @@ class ThemeManager { element.disabled = true; element.parentNode.removeChild(element); } + + _.remove(this.activeThemes, {uuid: theme.uuid}); + + this.cacheThemes(); + } + + async cacheThemes() { + let mapped = await Promise.all(this.activeThemes.map(async (theme) => { + let transformer = new SFItemParams(theme); + let params = await transformer.paramsForLocalStorage(); + return params; + })); + let data = JSON.stringify(mapped); + console.log("Caching themes", data); + return this.storageManager.setItem(ThemeManager.CachedThemesKey, data, StorageManager.Fixed); + } + + async decacheThemes() { + return this.storageManager.removeItem(ThemeManager.CachedThemesKey, StorageManager.Fixed); + } + + getCachedThemes() { + let cachedThemes = this.storageManager.getItemSync(ThemeManager.CachedThemesKey, StorageManager.Fixed); + if(cachedThemes) { + let parsed = JSON.parse(cachedThemes); + return parsed.map((theme) => { + return new SNTheme(theme); + }); + } else { + return []; + } } } diff --git a/app/assets/stylesheets/app/_lock-screen.scss b/app/assets/stylesheets/app/_lock-screen.scss index f5faed28e..89ce4dfb4 100644 --- a/app/assets/stylesheets/app/_lock-screen.scss +++ b/app/assets/stylesheets/app/_lock-screen.scss @@ -12,24 +12,17 @@ bottom: 0; z-index: $z-index-lock-screen; - background-color: var(--sn-stylekit-contrast-background-color); + background-color: var(--sn-stylekit-background-color); color: var(--sn-stylekit-foreground-color); display: flex; flex-direction: column; align-items: center; justify-content: center; - .background { - position: absolute; - z-index: -1; - width: 100%; - height: 100%; - } - .sk-panel { width: 315px; flex-grow: 0; - border-radius: 0; + // border-radius: 0; .sk-panel-header { justify-content: center; diff --git a/app/assets/templates/lock-screen.html.haml b/app/assets/templates/lock-screen.html.haml index 222e6b704..72ebdd7d7 100644 --- a/app/assets/templates/lock-screen.html.haml +++ b/app/assets/templates/lock-screen.html.haml @@ -19,6 +19,7 @@ %div{"ng-if" => "formData.showRecovery"} .sk-p - If you forgot your local passcode, your only option is to clear all your local data from this device + If you forgot your local passcode, your only option is to clear your local data from this device and sign back in to your account. - %a.sk-a.danger{"ng-click" => "beginDeleteData()"} Delete Local Data + .sk-panel-row + %a.sk-a.danger.center-text{"ng-click" => "beginDeleteData()"} Delete Local Data From 1877412ebf3f5f08e6969f1825d22f9e3a3d6036 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 12 Dec 2018 16:21:19 -0600 Subject: [PATCH 22/62] Loading overlay for componentView --- .../app/directives/views/componentView.js | 63 ++++++++++++------- .../app/services/componentManager.js | 21 ++++--- .../javascripts/app/services/themeManager.js | 3 - app/assets/stylesheets/app/_modals.scss | 7 +++ .../directives/component-view.html.haml | 2 + 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index a68ea4be5..efe212198 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -45,34 +45,49 @@ class ComponentView { return; } - // activationHandlers may be called multiple times, design below to be idempotent - if(component.active) { - $scope.loading = true; - let iframe = componentManager.iframeForComponent(component); - if(iframe) { - // begin loading error handler. If onload isn't called in x seconds, display an error - if($scope.loadTimeout) { $timeout.cancel($scope.loadTimeout);} - $scope.loadTimeout = $timeout(() => { - if($scope.loading) { - $scope.issueLoading = true; - } - }, 3500); - iframe.onload = function(event) { - // console.log("iframe loaded for component", component.name, "cancelling load timeout", $scope.loadTimeout); - $timeout.cancel($scope.loadTimeout); - $scope.loading = false; - $scope.issueLoading = false; - componentManager.registerComponentWindow(component, iframe.contentWindow); - }.bind(this); - } - } - }, + $timeout(() => { + $scope.handleActivation(); + }) + }, actionHandler: (component, action, data) => { if(action == "set-size") { componentManager.handleSetSizeEvent(component, data); } - }} - ); + } + }); + + $scope.handleActivation = function() { + // activationHandlers may be called multiple times, design below to be idempotent + let component = $scope.component; + if(!component.active) { + return; + } + + $scope.loading = true; + + let iframe = componentManager.iframeForComponent(component); + if(iframe) { + // begin loading error handler. If onload isn't called in x seconds, display an error + if($scope.loadTimeout) { $timeout.cancel($scope.loadTimeout);} + $scope.loadTimeout = $timeout(() => { + if($scope.loading) { + $scope.issueLoading = true; + } + }, 3500); + iframe.onload = (event) => { + // console.log("iframe loaded for component", component.name, "cancelling load timeout", $scope.loadTimeout); + $timeout.cancel($scope.loadTimeout); + componentManager.registerComponentWindow(component, iframe.contentWindow); + + // Add small timeout to, as $scope.loading controls loading overlay, + // which is used to avoid flicker when enabling extensions while having an enabled theme + $timeout(() => { + $scope.loading = false; + $scope.issueLoading = false; + }, 5) + }; + } + } /* diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index dbeffcf90..b6a2bba0b 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -154,7 +154,7 @@ class ComponentManager { if(component.isTheme() || !component.active || !component.window) { continue; } - this.postActiveThemeToComponent(component); + this.postActiveThemesToComponent(component); } } @@ -162,14 +162,16 @@ class ComponentManager { return this.componentsForArea("themes").filter((theme) => {return theme.active}); } - postActiveThemeToComponent(component) { - var themes = this.getActiveThemes(); - var urls = themes.map((theme) => { + urlsForActiveThemes() { + let themes = this.getActiveThemes(); + return themes.map((theme) => { return this.urlForComponent(theme); }) - var data = { - themes: urls - } + } + + postActiveThemesToComponent(component) { + let urls = this.urlsForActiveThemes(); + let data = { themes: urls } this.sendMessageToComponent(component, {action: "themes", data: data}) } @@ -805,10 +807,11 @@ class ComponentManager { data: { uuid: component.uuid, environment: isDesktopApplication() ? "desktop" : "web", - platform: getPlatformString() + platform: getPlatformString(), + activeThemeUrls: this.urlsForActiveThemes() } }); - this.postActiveThemeToComponent(component); + this.postActiveThemesToComponent(component); this.desktopManager.notifyComponentActivation(component); } diff --git a/app/assets/javascripts/app/services/themeManager.js b/app/assets/javascripts/app/services/themeManager.js index 76a473ebe..c35a7d021 100644 --- a/app/assets/javascripts/app/services/themeManager.js +++ b/app/assets/javascripts/app/services/themeManager.js @@ -60,8 +60,6 @@ class ThemeManager { return; } - console.log("Activating theme", theme.uuid); - this.activeThemes.push(theme); var url = this.componentManager.urlForComponent(theme); @@ -97,7 +95,6 @@ class ThemeManager { return params; })); let data = JSON.stringify(mapped); - console.log("Caching themes", data); return this.storageManager.setItem(ThemeManager.CachedThemesKey, data, StorageManager.Fixed); } diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 09ac067f2..2e41059fa 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -178,6 +178,13 @@ min-width: 100%; } + .loading-overlay { + position: absolute; + background-color: var(--sn-stylekit-editor-background-color); + width: 100%; + height: 100%; + } + iframe { // We're disabling flex: 1; because on Firefox, it causes weird sizing issues with component stack items. // Not sure yet if totally required. diff --git a/app/assets/templates/directives/component-view.html.haml b/app/assets/templates/directives/component-view.html.haml index eba49d1c9..985e64a45 100644 --- a/app/assets/templates/directives/component-view.html.haml +++ b/app/assets/templates/directives/component-view.html.haml @@ -111,3 +111,5 @@ "sandbox" => "allow-scripts allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-modals allow-forms", "data-component-id" => "{{component.uuid}}"} Loading + +.loading-overlay{"ng-if" => "loading"} From 7cba67ce690f4da863c8bebd9e8f33f52419eead Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 12 Dec 2018 18:37:07 -0600 Subject: [PATCH 23/62] Dock shortcuts --- .../javascripts/app/controllers/footer.js | 57 +++++++++++++++++++ .../app/directives/functional/elemReady.js | 15 +++++ .../app/directives/views/componentView.js | 1 + .../app/services/componentManager.js | 31 ++++++---- app/assets/stylesheets/app/_footer.scss | 17 +++++- app/assets/templates/footer.html.haml | 11 ++++ 6 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 app/assets/javascripts/app/directives/functional/elemReady.js diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index 5aeb5b176..f0c37e9a8 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -138,11 +138,68 @@ angular.module('app') this.componentManager = componentManager; this.rooms = []; + this.themes = []; modelManager.addItemSyncObserver("room-bar", "SN|Component", (allItems, validItems, deletedItems, source) => { this.rooms = modelManager.components.filter((candidate) => {return candidate.area == "rooms" && !candidate.deleted}); }); + modelManager.addItemSyncObserver("footer-bar-themes", "SN|Theme", (allItems, validItems, deletedItems, source) => { + let themes = modelManager.validItemsForContentType("SN|Theme").filter((candidate) => {return !candidate.deleted}).sort((a, b) => { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }); + + let differ = themes.length != this.themes.length; + + this.themes = themes; + + if(differ) { + this.reloadDockShortcuts(); + } + }); + + this.reloadDockShortcuts = function() { + let shortcuts = []; + for(var theme of this.themes) { + var icon = theme.content.package_info.dock_icon; + if(!icon) { + continue; + } + shortcuts.push({ + component: theme, + icon: icon + }) + } + + this.dockShortcuts = shortcuts.sort((a, b) => { + // circles first, then images + + var aType = a.icon.type; + var bType = b.icon.type; + + if(aType == bType) { + return 0; + } else if(aType == "circle" && bType == "svg") { + return -1; + } else if(bType == "circle" && aType == "svg") { + return 1; + } + }); + } + + this.initSvgForShortcut = function(shortcut) { + var id = "dock-svg-" + shortcut.component.uuid; + var element = document.getElementById(id); + var parser = new DOMParser(); + var svg = shortcut.component.content.package_info.dock_icon.source; + var doc = parser.parseFromString(svg, "image/svg+xml"); + element.appendChild(doc.documentElement); + } + + this.selectShortcut = function(shortcut) { + componentManager.toggleComponent(shortcut.component); + } + componentManager.registerHandler({identifier: "roomBar", areas: ["rooms", "modal"], activationHandler: (component) => { // RIP: There used to be code here that checked if component.active was true, and if so, displayed the component. // However, we no longer want to persist active state for footer extensions. If you open Extensions on one computer, diff --git a/app/assets/javascripts/app/directives/functional/elemReady.js b/app/assets/javascripts/app/directives/functional/elemReady.js new file mode 100644 index 000000000..7eef56fa7 --- /dev/null +++ b/app/assets/javascripts/app/directives/functional/elemReady.js @@ -0,0 +1,15 @@ +angular +.module('app') +.directive( 'elemReady', function( $parse ) { + return { + restrict: 'A', + link: function( $scope, elem, attrs ) { + elem.ready(function(){ + $scope.$apply(function(){ + var func = $parse(attrs.elemReady); + func($scope); + }) + }) + } + } +}) diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index efe212198..459fdb3ad 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -81,6 +81,7 @@ class ComponentView { // Add small timeout to, as $scope.loading controls loading overlay, // which is used to avoid flicker when enabling extensions while having an enabled theme + // we don't use ng-show because it causes problems with rendering iframes after timeout, for some reason. $timeout(() => { $scope.loading = false; $scope.issueLoading = false; diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index b6a2bba0b..ccb255d4e 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -631,22 +631,33 @@ class ComponentManager { } handleToggleComponentMessage(sourceComponent, targetComponent, message) { - if(targetComponent.area == "modal") { - this.openModalComponent(targetComponent); + this.toggleComponent(targetComponent); + } + + toggleComponent(component) { + if(component.area == "modal") { + this.openModalComponent(component); } else { - if(targetComponent.active) { - this.deactivateComponent(targetComponent); + if(component.active) { + this.deactivateComponent(component); } else { - if(targetComponent.content_type == "SN|Theme" && !targetComponent.isLayerable()) { + if(component.content_type == "SN|Theme") { // Deactive currently active theme if new theme is not layerable var activeThemes = this.getActiveThemes(); - for(var theme of activeThemes) { - if(theme && !theme.isLayerable()) { - this.deactivateComponent(theme); - } + + // Activate current before deactivating others, so as not to flicker + this.activateComponent(component); + + if(!component.isLayerable()) { + setTimeout(() => { + for(var theme of activeThemes) { + if(theme && !theme.isLayerable()) { + this.deactivateComponent(theme); + } + } + }, 10); } } - this.activateComponent(targetComponent); } } } diff --git a/app/assets/stylesheets/app/_footer.scss b/app/assets/stylesheets/app/_footer.scss index f03c27adb..e5d46fe1f 100644 --- a/app/assets/stylesheets/app/_footer.scss +++ b/app/assets/stylesheets/app/_footer.scss @@ -21,6 +21,20 @@ z-index: $z-index-footer-bar-item-panel; margin-top: 15px; } + + &.dock-shortcut:hover .sk-app-bar-item-column { + border-bottom: 2px solid var(--sn-stylekit-info-color); + } + + svg { + width: 12px; + height: 12px; + fill: var(--sn-stylekit-foreground-color); + + &:hover { + fill: var(--sn-stylekit-info-color); + } + } } #account-panel { @@ -41,6 +55,5 @@ a.disabled { #footer-lock-icon { margin-left: 5px; - padding-left: 8px; - border-left: 1px solid gray; + padding-left: 5px; } diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index 40717084e..31192f7eb 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -1,6 +1,7 @@ .sn-component #footer-bar.sk-app-bar.no-edges .left + .sk-app-bar-item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.clickOutsideAccountMenu()", "is-open" => "ctrl.showAccountMenu"} .sk-app-bar-item-column .sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'neutral')"} @@ -39,6 +40,16 @@ .sk-app-bar-item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} .sk-label Refresh + .sk-app-bar-item.border{"ng-if" => "ctrl.dockShortcuts.length > 0"} + + .sk-app-bar-item.dock-shortcut{"ng-repeat" => "shortcut in ctrl.dockShortcuts"} + .sk-app-bar-item-column{"ng-click" => "ctrl.selectShortcut(shortcut)", "ng-class" => "{'underline': shortcut.component.active}"} + .div{"ng-if" => "shortcut.icon.type == 'circle'"} + .sk-circle.small{"ng-style" => "{'background-color': shortcut.icon.background_color, 'border-color': shortcut.icon.border_color}"} + .div{"ng-if" => "shortcut.icon.type == 'svg'"} + .svg-item{"ng-attr-id" => "dock-svg-{{shortcut.component.uuid}}", "elem-ready" => "ctrl.initSvgForShortcut(shortcut)"} + + .sk-app-bar-item.border{"ng-if" => "ctrl.hasPasscode()"} .sk-app-bar-item#lock-item{"ng-if" => "ctrl.hasPasscode()", "title" => "Locks application and wipes unencrypted data from memory."} .sk-label %i.icon.ion-locked#footer-lock-icon{"ng-if" => "ctrl.hasPasscode()", "ng-click" => "ctrl.lockApp()"} From 9200055616669d148b26c0559a87a81baae716ff Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 01:38:22 -0600 Subject: [PATCH 24/62] editor-menu-bar id --- app/assets/javascripts/app/controllers/editor.js | 2 +- .../javascripts/app/services/componentManager.js | 13 +++++++------ app/assets/templates/editor.html.haml | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index ed97fe6a8..986584343 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -516,7 +516,7 @@ angular.module('app') this.loadPreferences = function() { this.monospaceFont = authManager.getUserPrefValue("monospaceFont", "monospace"); this.spellcheck = authManager.getUserPrefValue("spellcheck", true); - this.marginResizersEnabled = authManager.getUserPrefValue("marginResizersEnabled", false); + this.marginResizersEnabled = authManager.getUserPrefValue("marginResizersEnabled", true); if(!document.getElementById("editor-content")) { // Elements have not yet loaded due to ng-if around wrapper diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index ccb255d4e..c611f8e41 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -33,7 +33,7 @@ class ComponentManager { desktopManager.registerUpdateObserver((component) => { // Reload theme if active if(component.active && component.isTheme()) { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } }) @@ -147,13 +147,14 @@ class ComponentManager { }); } - postActiveThemeToAllComponents() { + postActiveThemesToAllComponents() { for(var component of this.components) { // Skip over components that are themes themselves, // or components that are not active, or components that don't have a window if(component.isTheme() || !component.active || !component.window) { continue; } + this.postActiveThemesToComponent(component); } } @@ -862,7 +863,7 @@ class ComponentManager { } if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } } @@ -895,7 +896,7 @@ class ComponentManager { }) if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } } @@ -922,7 +923,7 @@ class ComponentManager { }) if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } // @@ -944,7 +945,7 @@ class ComponentManager { } if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } }) } diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index ec5c34da7..70ceb1b4e 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -10,8 +10,8 @@ #editor-title-bar.section-title-bar{"ng-show" => "ctrl.note && !ctrl.note.errorDecrypting", "ng-class" => "{'locked' : ctrl.note.locked }"} .title %input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)", - "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", - "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} + "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", + "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} #save-status{"ng-class" => "{'warning bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} @@ -23,7 +23,7 @@ "spellcheck" => "false", "ng-disabled" => "ctrl.note.locked"} .sn-component{"ng-if" => "ctrl.note"} - .sk-app-bar.no-edges + .sk-app-bar.no-edges#editor-menu-bar .left .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showMenu')", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} .sk-label Options From 24bfe5db30ae0b225af675fc4b929e0c58797298 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 02:02:43 -0600 Subject: [PATCH 25/62] Fix password manager continue lock --- Gruntfile.js | 2 +- .../app/directives/views/componentView.js | 2 +- .../app/directives/views/passwordWizard.js | 9 +++++++-- .../directives/password-wizard.html.haml | 15 +++++++-------- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ab803c3cc..a4c4cbf0f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ module.exports = function(grunt) { watch: { haml: { files: ['app/assets/templates/**/*.haml'], - tasks: ['newer:haml', 'ngtemplates', 'concat:app', 'babel', 'browserify', 'concat:dist'], + tasks: ['newer:haml', 'ngtemplates', 'concat:app', 'babel', 'browserify', 'concat:dist', 'ngAnnotate'], options: { spawn: false, }, diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index 459fdb3ad..de807f819 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -85,7 +85,7 @@ class ComponentView { $timeout(() => { $scope.loading = false; $scope.issueLoading = false; - }, 5) + }, 7) }; } } diff --git a/app/assets/javascripts/app/directives/views/passwordWizard.js b/app/assets/javascripts/app/directives/views/passwordWizard.js index f93bed6d5..7c78e2cbb 100644 --- a/app/assets/javascripts/app/directives/views/passwordWizard.js +++ b/app/assets/javascripts/app/directives/views/passwordWizard.js @@ -102,6 +102,9 @@ class PasswordWizard { if(preprocessor) { preprocessor(() => { next(); + }, () => { + // on fail + $scope.isContinuing = false; }) } else { next(); @@ -114,7 +117,7 @@ class PasswordWizard { $scope.preprocessorForStep = function(step) { if(step == PasswordStep) { - return (callback) => { + return (onSuccess, onFail) => { $scope.showSpinner = true; $scope.continueTitle = "Generating Keys..."; $timeout(() => { @@ -122,7 +125,9 @@ class PasswordWizard { $scope.showSpinner = false; $scope.continueTitle = DefaultContinueTitle; if(success) { - callback(); + onSuccess(); + } else { + onFail && onFail(); } }); }) diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index 207c9e8c9..e2a004e35 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -14,8 +14,7 @@ %p.sk-p Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. If you have many items, syncing your data can take several minutes. - %p.sk-p - %strong You must keep the application window open during this process. + %p.sk-p.sk-panel-row You must keep the application window open during this process. %div{"ng-if" => "securityUpdate"} %p.sk-p A new update is available for your account. Updates address improvements and enhancements to our security specification. @@ -75,7 +74,7 @@ %div{"ng-if" => "step == 4"} %p.sk-panel-row Your data is being re-encrypted with your new keys and synced to your account. - %p.sk-panel-row.danger + %p.sk-panel-row.danger{"ng-if" => "lockContinue"} Do not close this window until this process completes. .sk-panel-row @@ -89,14 +88,14 @@ %div{"ng-if" => "step == 5"} %div{"ng-if" => "changePassword"} - %p.sk-panel-row Your password has been successfully changed. + %p.sk-p.sk-panel-row.info-i Your password has been successfully changed. %div{"ng-if" => "securityUpdate"} - %p.sk-panel-row + %p.sk-p.sk-panel-row The security update has been successfully applied to your account. - %p.sk-panel-row - %strong Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. + %p.sk-p.sk-panel-row + Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. - %p.sk-panel-row You may now sign back in on all your devices and close this window. + %p.sk-p.sk-panel-row You may now sign back in on all your devices and close this window. .sk-panel-footer .empty From c08a33fd57dbf5882c954f117f5246dec29f9e40 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 12:19:18 -0600 Subject: [PATCH 26/62] Sort reverse option --- .../javascripts/app/controllers/notes.js | 12 +++++++---- app/assets/javascripts/app/filters/sortBy.js | 13 ++++++++---- app/assets/stylesheets/app/_ionicons.scss | 19 ++++++++++++++---- app/assets/stylesheets/app/_notes.scss | 13 +++++++++++- app/assets/templates/notes.html.haml | 18 ++++++++++------- dist/assets/ionicons.eot | Bin 1930 -> 2090 bytes dist/assets/ionicons.svg | 16 +++++++++------ dist/assets/ionicons.ttf | Bin 1752 -> 1912 bytes dist/assets/ionicons.woff | Bin 1260 -> 1348 bytes 9 files changed, 65 insertions(+), 26 deletions(-) mode change 100644 => 100755 dist/assets/ionicons.svg mode change 100644 => 100755 dist/assets/ionicons.ttf mode change 100644 => 100755 dist/assets/ionicons.woff diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 6c0f54644..068a40362 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -44,6 +44,7 @@ angular.module('app') let prevSortValue = this.sortBy; this.sortBy = authManager.getUserPrefValue("sortBy", "created_at"); + this.sortReverse = authManager.getUserPrefValue("sortReverse", false); if(this.sortBy == "updated_at") { // use client_updated_at instead @@ -55,7 +56,6 @@ angular.module('app') this.selectFirstNote(); }) } - this.sortDescending = this.sortBy != "title"; this.showArchived = authManager.getUserPrefValue("showArchived", false); this.hidePinned = authManager.getUserPrefValue("hidePinned", false); @@ -301,17 +301,21 @@ angular.module('app') this.selectedSortByCreated = function() { this.setSortBy("created_at"); - this.sortDescending = true; } this.selectedSortByUpdated = function() { this.setSortBy("client_updated_at"); - this.sortDescending = true; } this.selectedSortByTitle = function() { this.setSortBy("title"); - this.sortDescending = false; + } + + this.toggleReverseSort = function() { + this.selectedMenuItem(); + this.sortReverse = !this.sortReverse; + authManager.setUserPrefValue("sortReverse", this.sortReverse); + authManager.syncUserPreferences(); } this.setSortBy = function(type) { diff --git a/app/assets/javascripts/app/filters/sortBy.js b/app/assets/javascripts/app/filters/sortBy.js index e182b19a5..c1fa496a8 100644 --- a/app/assets/javascripts/app/filters/sortBy.js +++ b/app/assets/javascripts/app/filters/sortBy.js @@ -1,6 +1,6 @@ angular.module('app') .filter('sortBy', function ($filter) { - return function(items, sortBy) { + return function(items, sortBy, reverse) { let sortValueFn = (a, b, pinCheck = false) => { if(!pinCheck) { if(a.pinned && b.pinned) { @@ -14,6 +14,11 @@ angular.module('app') var bValue = b[sortBy] || ""; let vector = 1; + + if(reverse) { + vector *= -1; + } + if(sortBy == "title") { aValue = aValue.toLowerCase(); bValue = bValue.toLowerCase(); @@ -21,11 +26,11 @@ angular.module('app') if(aValue.length == 0 && bValue.length == 0) { return 0; } else if(aValue.length == 0 && bValue.length != 0) { - return 1; + return 1 * vector; } else if(aValue.length != 0 && bValue.length == 0) { - return -1; + return -1 * vector; } else { - vector = -1; + vector *= -1; } } diff --git a/app/assets/stylesheets/app/_ionicons.scss b/app/assets/stylesheets/app/_ionicons.scss index 884e1f781..70647fb73 100644 --- a/app/assets/stylesheets/app/_ionicons.scss +++ b/app/assets/stylesheets/app/_ionicons.scss @@ -11,14 +11,25 @@ Modified icons to fit ionicon’s grid from original. */ @font-face { font-family: "Ionicons"; src: url("../assets/ionicons.eot?v=2.0.0"); src: url("../assets/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"), url("../assets/ionicons.ttf?v=2.0.1") format("truetype"), url("../assets/ionicons.woff?v=2.0.1") format("woff"), url("../assets/ionicons.svg?v=2.0.1#Ionicons") format("svg"); font-weight: normal; font-style: normal; } -.ion, .ionicons, .ion-ios-box:before, .ion-bookmark:before, .ion-locked:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +.ion, .ionicons, +.ion-ios-box:before, +.ion-bookmark:before, +.ion-locked:before, +.ion-arrow-return-left:before, +.ion-arrow-return-right:before +{ + display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; +} .ion-ios-box:before { content: "\f3ec"; } .ion-locked:before { content: "\f200"; } -.ion-bookmark:before { - content: "\f26b"; -} +.ion-bookmark:before { content: "\f26b"; } + +.ion-arrow-return-left:before { content: "\f265"; } + +.ion-arrow-return-right:before { content: "\f266"; } /*# sourceMappingURL=ionicons.css.map */ diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index fb659a42a..d087ca044 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -153,6 +153,17 @@ opacity: 0.6; } + .note-flags { + display: flex; + flex-direction: row; + align-items: center; + + .pinned, .archived { + color: var(--sn-stylekit-info-color); + margin-right: 10px; + } + } + progress { background-color: var(--sn-stylekit-contrast-background-color); color: var(--sn-stylekit-info-color); @@ -170,7 +181,7 @@ background-color: var(--sn-stylekit-info-color); color: var(--sn-stylekit-info-contrast-color); - .pinned { + .pinned, .archived { color: var(--sn-stylekit-info-contrast-color); } diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index 7e82d7719..fc27d7772 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -24,6 +24,9 @@ .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} .sk-menu-panel-header .sk-menu-panel-header-title Sort By + .sk-button.sk-secondary-contrast{"ng-click" => "ctrl.toggleReverseSort()"} + .sk-label + %i.icon{"ng-class" => "{'ion-arrow-return-left' : ctrl.sortReverse == false, 'ion-arrow-return-right' : ctrl.sortReverse == true }"} %menu-row{"label" => "'Date Added'", "circle" => "ctrl.sortBy == 'created_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()", "desc" => "'Sort notes by newest first'"} %menu-row{"label" => "'Date Modified'", "circle" => "ctrl.sortBy == 'client_updated_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()", "desc" => "'Sort notes with the most recently updated first'"} @@ -41,18 +44,19 @@ .scrollable .infinite-scroll#notes-scrollable{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} - .note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy | limitTo:ctrl.notesToDisplay)) track by note.uuid", + .note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy:ctrl.sortReverse | limitTo:ctrl.notesToDisplay)) track by note.uuid", "ng-click" => "ctrl.selectNote(note, true)", "ng-class" => "{'selected' : ctrl.selectedNote == note}"} %strong.red.medium-text{"ng-if" => "note.conflict_of"} Conflicted copy %strong.red.medium-text{"ng-if" => "note.errorDecrypting"} Unable to Decrypt - .pinned.tinted{"ng-if" => "note.pinned", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} - %i.icon.ion-bookmark - %strong.medium-text Pinned + .note-flags + .pinned{"ng-if" => "note.pinned"} + %i.icon.ion-bookmark + %strong.medium-text Pinned - .archived.tinted{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} - %i.icon.ion-ios-box - %strong.medium-text Archived + .archived{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()"} + %i.icon.ion-ios-box + %strong.medium-text Archived .tags-string{"ng-if" => "ctrl.shouldShowTags(note)"} .faded {{note.savedTagsString || note.tagsString()}} diff --git a/dist/assets/ionicons.eot b/dist/assets/ionicons.eot index 9edec390724f6b60699890755bc10e13069a594a..84145da254ce268171db6307fcd2fa877cb740d3 100644 GIT binary patch delta 686 zcmY*XKWGzi6#m}*{Z-p0sf~-RCRT|p1k+0!B32tw97?r<8MFvVh-p$x+F+x^#T*@q zxRo0m6m$_pa1c?%K_ZAQ4h|7INQi?{#Gyom48`~^Jw*@R{l4$L_q{*&yPK|uZf!&W zWqnnPD3i5%V>Py1SxFcLK)(QBVCL*Wh8@qzajr_a|O)?;n6f#l@x4adjmN zXf2M`uAd~Jf7m%zf4eO$#6V?U|(zMkpj-0ivDy~|cSc_Zy1{W|X88EV$L z{I+73@p0cI`hXqYurWyeL;k%-XzVbJ4|xM-ONd|Zg=kedCnh$82njQm?6m)@Bb`(K zmy&5#|40eRn8`X;$G9DjYClynp<6GMTY>#}-Koc)j~Cf=unIQ?9IQdmlvP%Pfhm;j z<&`eZb>pjpRo+2$u*SNm^-g`PhY`dm3~O0CpoD{?hV@9hZ0*+l!~C~#VTmM?Ngwt>Vw^QC^ zu2O+w{VI7dm6>|jcV+Mv{VwLWr$@X8H7o7_y)TT;GzHZ!DSGwf(R4OHQ?N^@qp(Kd zWM(|+$vJSCY9@EHULl8G4AN&qM8>@A$o8ehR?f~)JIsww=J!ARU^7jQ9tdB?@u{r&)E!5~j -Created by FontForge 20170925 at Fri Jan 19 12:18:20 2018 +Created by FontForge 20170925 at Thu Dec 13 12:01:05 2018 By mo Copyright (c) 2018, mo - + - - + + + diff --git a/dist/assets/ionicons.ttf b/dist/assets/ionicons.ttf old mode 100644 new mode 100755 index 01db5bbde6fa8d93db391190fc81b876258dffc1..ca804f472261c8a633570e1e89c6aaa1b9a52056 GIT binary patch delta 698 zcmY*WJ7`m36#mYA{?(>!YT}?NrdEjx!Stq$0c(vY8A@MZ1}%Z)64RuZw82J+i@8&A z_6`mTf*`nxC{7YVbnQ?fgOqkqL>we41T5BbldIwnhx7Wr^ZJ{fc3&L?zyk|1=99_P z%v#1M1A3aHfw_w(jdRa3aeywdpUsuc%BRa8E9^H}7IHVLL3rr`AdhigDVVF3-CeE( zJ;lB#lx{Be`1il#{50bq7xU&7Z~x{b=ial#ip6~0l;>%QlRgd{DVD1>{R6!0zhFOD zTFIHTL$|pA4}rn5S*u_MJRCWGaM>*9Up|_6#l61+5>-}KtLN3V0-&`yztCBZ7u?$1 zIGgF8_<_9=hk<5%cB`wU+3h=YN*5iZuqSDVrtLJ9(qwTH7BpBVSn~|71Ug_K#S!Ov z0Vr_B*#iLyQVXrc*41xc_!3|{-?jT>&jZiB-h&R~sZTmY`YqhYb8Of#`EA`P6C{hW z7zFnDqs9>VMurccp|R66KH?8qZ6SWG3(;;cCLz8G5fN4*+iCxoM><3Qr;=qg{!j_o zgvC5&C%7Gt>bwRosoO%i8#;>DoqBvsUS!9$RSZzbwKWKuvfn7-&=hLU@=6b52k_ao zRo+2$ZH;+x`+)jHk0Ojw81}k)Oo@g^4g05h%`R!f#|5`1{xykYQb;9DzrMVbG$N6% Sj*YuIWY>0eSa0|VP0ps0+0u)dMw)_5@n2F3^=KOs3c zvEWnd%L73E1t1PeE-O)B5M*>=U|?1O%Cn>=78m^g4>XB^Z3~dkk)BhT=3^V<3zWA2 zsyE3tuEZeY&= zJ-FuNQ@(h9o39MqOh918=eZ-5?!v-p^KXYxogFm6_1l4oSDVVE`9i~0EER+dHT zDh!9fMgUz1)ch05W@QjyRDrVD7&sW+C;PGLs(Ub0fGlL;1gaHacn)Q=GAJ-ILD_6T zeWsHav2J9wWYA?WoE*ib!EC8(IJu3jX!1`s1yMGjBN-W(7?~KE8Clp%^D^Cx3=Aea Mv1{=leEjSU0AVI>;s5{u diff --git a/dist/assets/ionicons.woff b/dist/assets/ionicons.woff old mode 100644 new mode 100755 index 20532652fd7c2f2ad0fcbd0551a7461534a4fbe1..83246bd1ff1f6250c7c8153a858314633b4660c6 GIT binary patch literal 1348 zcmZuxYfw{16yBRaf{27T2seTnl!u^(SHW1LqF@9yh7r&qlj6;T3z-mLAdP`45S0i8 zDxelnYEe@jVi7@cQW+7VYMZ}*<>eCOVCcIWJV zE}IPy0Ec}PSYTVpO56N@gUycTK;25{^MLSF?+cM};{rnfKs3;fhQKyo-NzKk1epL3 z9H6}$`gr4szh{aRaysPrkhA*;DiW0<$c8$5$OD_!!Dl(ZZi>f|tPFGS7LlaNSQbIQw;yL6*;_AL?pU^ z7&a+hhX6c)c>O=W344TNI6!>qxEK_#3mRA10f!85;bXkOEU4A#?&^TXfTHNoS@T{} zjM|Mv@+IxTNlcfBAR6H@KMq~IG5A2p0Pk6XgkAQLoECobeBwB1aVi;b4(MW8Pivu!^b{%jd&8PR?)^+J_>CD9=amI$J zhZ!HNDHv#r^Ge%@56^bC=V;F6o-L>-Ll`=}op&`Fi>$cWN(SyIwGNQ}F}ts4FO%_4q=c@^re zaGw}cE>m^&sRFT4-@{Ew!OlrpReszv&n#m}u{uHlnP1?zm@lKY_-Pe{SA8A4oYP|$ zmiweVdE9bB(UR~+S}B?cElEV$8^6rImh{^>Wn1~r5=Y(4(sk)30t0#Qet1pK&C8Xy zBEySLEfGIAH158#BQ!c!ZjvglHhHL92C57b(<@83la~k5|FrzrAsxT;)5!fj%{AF4 z#+keNZ|@>sFK9EIJV@&YFT+d5GGETN$xG*5CFapJgVZdSkmHqyL-m6 zKWX4I{Zm$!U^3uZn56K~4Zo>Y0cp?H9HY#k=6FYXc)Tkk5I=`Km>HOE3#;}Tt$E$q z5s6QRw{sGs7fNgHh1I6w6*1>p#-CP7d)D$3{@9*6lz1myQP|2jB}$g|8E^5V+82LO z8lrZt_|#)UaM(&ly=kq8Gi)(TC>Dxwu|S+G76ta+lZS=`6+FW0V~tMR*Q+F=y(vI7 lwtxXc5qK{V{_PJjIMn>A{vxSw?drLu5fev2!X~l``~wW?{l@?R literal 1260 zcmZuxc~BEq9DbXPD`2>+LlZC@ErS&mHbJ0JPJ!SNAPUGRST>sj9IjNk9OXt4X)O$b z5YbSlX*E=#h((~lR*^#rgiASej9OX*IRtF$R83!KXZlay&i8)veee6;dwaZ13*qqq z0$`)R0EW7Xjp_RTYdl_95cH|xm<7bf+;?PNNT?$h0OV`PcS8`qH>1r&2|^hFG(E@z z;n=>Vlg}wpYO*!d1W==|!W8k35gvs;dN<@cubx&5(3tpRQs@)IoH@jHzGqZWtVF2e zIP`EJTnuZC!eXHaHK+qNge@vSVqz1L)1kHqIa3Gv6fliX5wbhzSBbb>5^{ zy1P7iLZXq9ASZ5a;8VZnt_+6O3U|RBz!5hlH3U*T46|VH-%Qk^7Rj>|p{NPi#lylV z3`jphoBkUoL~1D^1&E!sR16B;@aY^n&~pPhsSY2|}7purMBGvWP4(e>!1?q1Js!KA*u*Fuf#Mnaf)5+`C;re^MH_UbT+F z9A|2xc-5B0UK^-x`~?CgGK^RN!1oGgwO_qRa01A6bF+(EgYV!b*$brH%GdUSOTguz z(vf|k93S&d%6)!i%H!u#XVh0~DS1hR&(=o=cG~g0Y3PT3(b<)2);ztG{B4LLxNSKH zV}MJa8PXZIwwcb?-}^Xk;nqlG^nri|>?_;djpwd2*jYCW%HHSK3Gn_)mVX?NdQi&< zSe9dpX&p3UnV~C)xHE{_4L6nBg>nj891OzU-2(%AaQ4d{wQS|OWYX+#l37uo{;bvS zN5&Vv=xS|Cid2-(ZEKuVrtMhqaI~zRed^N}w}TvfqoGx^Te^q+O>RDF*&Gx)Ux&vy z-EhEF-l?h!+gZZ1HK+PV4d;g`{ep{bo%+UT!P=_JTHfK{s~uJM1I>3GTYO8tGA^C+ zSfhJ38E3ywyp1#S2W$k*Vf>5Q9K?40c!@o-#XcbdYc>nmdz#MS`r12=7EJf9u$o_y z4~^KT&%KGxR4f=#Y_DqBvH22g|MW9wS-!JxXd`?mA~>#(ree3 zjR*HLH5^&T!$ykj@yt`k?~Bkl_y^=1U&*3q2sW0=}t{t6; znZ#yqv$sSR-M1S(*z4SA)f=*>L3d_Ikf&YCv}M&HF7QYYq?i;-#X`rv-ee~(o~@P! t6BA>jEYMx4R}ViqfWZF;O_w7GG03f1_~tuo@WF(l_0&)jAhh~I@HaYu&bt5r From bc634ca7da5d9ffbb6da1e200ab7279573d80cc9 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 12:24:30 -0600 Subject: [PATCH 27/62] Privileges for downloading backup from password wizard --- .../app/directives/views/accountMenu.js | 12 +---- .../app/services/archiveManager.js | 49 ++++++++++++------- .../directives/password-wizard.html.haml | 8 +-- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index 67254176b..82901adfd 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -351,17 +351,7 @@ class AccountMenu { */ $scope.downloadDataArchive = async function() { - let run = () => { - archiveManager.downloadBackup($scope.archiveFormData.encrypted); - } - - if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { - privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { - run(); - }); - } else { - run(); - } + archiveManager.downloadBackup($scope.archiveFormData.encrypted); } /* diff --git a/app/assets/javascripts/app/services/archiveManager.js b/app/assets/javascripts/app/services/archiveManager.js index 4c60c6b13..6517cf204 100644 --- a/app/assets/javascripts/app/services/archiveManager.js +++ b/app/assets/javascripts/app/services/archiveManager.js @@ -1,9 +1,10 @@ class ArchiveManager { - constructor(passcodeManager, authManager, modelManager) { + constructor(passcodeManager, authManager, modelManager, privilegesManager) { this.passcodeManager = passcodeManager; this.authManager = authManager; this.modelManager = modelManager; + this.privilegesManager = privilegesManager; } /* @@ -15,26 +16,36 @@ class ArchiveManager { } async downloadBackupOfItems(items, encrypted) { - // download in Standard File format - var keys, authParams; - if(encrypted) { - if(this.authManager.offline() && this.passcodeManager.hasPasscode()) { - keys = this.passcodeManager.keys(); - authParams = this.passcodeManager.passcodeAuthParams(); - } else { - keys = await this.authManager.keys(); - authParams = await this.authManager.getAuthParams(); + let run = async () => { + // download in Standard File format + var keys, authParams; + if(encrypted) { + if(this.authManager.offline() && this.passcodeManager.hasPasscode()) { + keys = this.passcodeManager.keys(); + authParams = this.passcodeManager.passcodeAuthParams(); + } else { + keys = await this.authManager.keys(); + authParams = await this.authManager.getAuthParams(); + } } - } - this.__itemsData(items, keys, authParams).then((data) => { - let modifier = encrypted ? "Encrypted" : "Decrypted"; - this.__downloadData(data, `Standard Notes ${modifier} Backup - ${this.__formattedDate()}.txt`); + this.__itemsData(items, keys, authParams).then((data) => { + let modifier = encrypted ? "Encrypted" : "Decrypted"; + this.__downloadData(data, `Standard Notes ${modifier} Backup - ${this.__formattedDate()}.txt`); - // download as zipped plain text files - if(!keys) { - this.__downloadZippedItems(items); - } - }) + // download as zipped plain text files + if(!keys) { + this.__downloadZippedItems(items); + } + }) + } + + if(await this.privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { + this.privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { + run(); + }); + } else { + run(); + } } /* diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index e2a004e35..336ed3de1 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -11,7 +11,7 @@ %div{"ng-if" => "step == 0"} %div{"ng-if" => "changePassword"} - %p.sk-p + %p.sk-p.sk-panel-row Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. If you have many items, syncing your data can take several minutes. %p.sk-p.sk-panel-row You must keep the application window open during this process. @@ -50,9 +50,9 @@ %p.sk-p.bold.sk-panel-row.info-i Please sign out of all applications (excluding this one), including: %ul - %li Desktop - %li Web (Chrome, Firefox, Safari) - %li Mobile (iOS and Android) + %li.sk-p Desktop + %li.sk-p Web (Chrome, Firefox, Safari) + %li.sk-p Mobile (iOS and Android) %p.sk-p.sk-panel-row If you do not currently have access to a device you're signed in on, you may proceed, but must make signing out and back in the first step upon gaining access to that device. From 0e4a6d718bc942c82aea268bd76cf8ef7b28e0ce Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 13:03:25 -0600 Subject: [PATCH 28/62] Distinguish between locked and protected notes --- .../javascripts/app/controllers/editor.js | 5 +++++ .../javascripts/app/controllers/notes.js | 4 ++-- .../javascripts/app/services/authManager.js | 2 +- .../app/services/privilegesManager.js | 16 ++++++++-------- .../app/services/storageManager.js | 4 ++++ app/assets/stylesheets/app/_ionicons.scss | 11 ++++++++++- app/assets/stylesheets/app/_notes.scss | 9 ++++++--- .../privileges-management-modal.html.haml | 4 ++-- app/assets/templates/editor.html.haml | 1 + app/assets/templates/notes.html.haml | 8 +++++--- dist/assets/ionicons.eot | Bin 2090 -> 2978 bytes dist/assets/ionicons.svg | 18 +++++++++++++++--- dist/assets/ionicons.ttf | Bin 1912 -> 2800 bytes dist/assets/ionicons.woff | Bin 1348 -> 1944 bytes 14 files changed, 59 insertions(+), 23 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 986584343..5855c2a0a 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -422,6 +422,11 @@ angular.module('app') this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); } + this.toggleProtectNote = function() { + this.note.content.protected = !this.note.content.protected; + this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); + } + this.toggleNotePreview = function() { this.note.content.hidePreview = !this.note.content.hidePreview; this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 068a40362..0247d0088 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -218,8 +218,8 @@ angular.module('app') }) } - if(note.locked && await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionViewLockedNotes)) { - privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionViewLockedNotes, () => { + if(note.content.protected && await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionViewProtectedNotes)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionViewProtectedNotes, () => { run(); }); } else { diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 3e4381e1f..d92e9d1e5 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -44,7 +44,7 @@ class AuthManager extends SFAuthManager { this.storageManager.setItemsMode(StorageManager.Ephemeral); } else { this.storageManager.setModelStorageMode(StorageManager.Fixed); - this.storageManager.setItemsMode(this.storageManager.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Fixed); + this.storageManager.setItemsMode(this.storageManager.bestStorageMode()); this.storageManager.setItem("ephemeral", JSON.stringify(false), StorageManager.Fixed); } } diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 97d489338..1d9028f9e 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -16,7 +16,7 @@ class PrivilegesManager { PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; PrivilegesManager.ActionManageBackups = "ActionManageBackups"; - PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; + PrivilegesManager.ActionViewProtectedNotes = "ActionViewProtectedNotes"; PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; PrivilegesManager.ActionManagePasscode = "ActionManagePasscode"; PrivilegesManager.ActionDeleteNote = "ActionDeleteNote"; @@ -34,7 +34,7 @@ class PrivilegesManager { PrivilegesManager.ActionManageExtensions, PrivilegesManager.ActionManageBackups, PrivilegesManager.ActionManagePasscode, - PrivilegesManager.ActionViewLockedNotes, + PrivilegesManager.ActionViewProtectedNotes, PrivilegesManager.ActionDeleteNote ] @@ -174,8 +174,8 @@ class PrivilegesManager { label: "Download/Import Backups" }; - metadata[PrivilegesManager.ActionViewLockedNotes] = { - label: "View Locked Notes" + metadata[PrivilegesManager.ActionViewProtectedNotes] = { + label: "View Protected Notes" }; metadata[PrivilegesManager.ActionManagePrivileges] = { @@ -224,8 +224,8 @@ class PrivilegesManager { let expiresAt = addToNow(length); return Promise.all([ - this.storageManager.setItem(PrivilegesManager.SessionExpiresAtKey, JSON.stringify(expiresAt), StorageManager.FixedEncrypted), - this.storageManager.setItem(PrivilegesManager.SessionLengthKey, JSON.stringify(length), StorageManager.FixedEncrypted), + this.storageManager.setItem(PrivilegesManager.SessionExpiresAtKey, JSON.stringify(expiresAt), this.storageManager.bestStorageMode()), + this.storageManager.setItem(PrivilegesManager.SessionLengthKey, JSON.stringify(length), this.storageManager.bestStorageMode()), ]) } @@ -234,7 +234,7 @@ class PrivilegesManager { } async getSelectedSessionLength() { - let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, StorageManager.FixedEncrypted); + let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, this.storageManager.bestStorageMode()); if(length) { return JSON.parse(length); } else { @@ -243,7 +243,7 @@ class PrivilegesManager { } async getSessionExpirey() { - let expiresAt = await this.storageManager.getItem(PrivilegesManager.SessionExpiresAtKey, StorageManager.FixedEncrypted); + let expiresAt = await this.storageManager.getItem(PrivilegesManager.SessionExpiresAtKey, this.storageManager.bestStorageMode()); if(expiresAt) { return new Date(JSON.parse(expiresAt)); } else { diff --git a/app/assets/javascripts/app/services/storageManager.js b/app/assets/javascripts/app/services/storageManager.js index 908490747..87b46eb56 100644 --- a/app/assets/javascripts/app/services/storageManager.js +++ b/app/assets/javascripts/app/services/storageManager.js @@ -174,6 +174,10 @@ class StorageManager extends SFStorageManager { return this.getItemSync("encryptedStorage", StorageManager.Fixed) !== null; } + bestStorageMode() { + return this.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Fixed; + } + /* Model Storage diff --git a/app/assets/stylesheets/app/_ionicons.scss b/app/assets/stylesheets/app/_ionicons.scss index 70647fb73..6390e6f48 100644 --- a/app/assets/stylesheets/app/_ionicons.scss +++ b/app/assets/stylesheets/app/_ionicons.scss @@ -17,7 +17,10 @@ .ion-bookmark:before, .ion-locked:before, .ion-arrow-return-left:before, -.ion-arrow-return-right:before +.ion-arrow-return-right:before, +.ion-key:before, +.ion-lock-combination:before, +.ion-eye-disabled:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -32,4 +35,10 @@ .ion-arrow-return-right:before { content: "\f266"; } +.ion-key:before { content: "\f296"; } + +.ion-lock-combination:before { content: "\f4d4"; } + +.ion-eye-disabled:before { content: "\f306"; } + /*# sourceMappingURL=ionicons.css.map */ diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index d087ca044..06adfc630 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -153,13 +153,16 @@ opacity: 0.6; } + .note-flag { + color: var(--sn-stylekit-info-color); + } + .note-flags { display: flex; flex-direction: row; align-items: center; - .pinned, .archived { - color: var(--sn-stylekit-info-color); + .note-flag { margin-right: 10px; } } @@ -181,7 +184,7 @@ background-color: var(--sn-stylekit-info-color); color: var(--sn-stylekit-info-contrast-color); - .pinned, .archived { + .note-flag { color: var(--sn-stylekit-info-contrast-color); } diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 03a4bfb11..95e897156 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -24,8 +24,8 @@ %input{"type" => "checkbox", "ng-disabled" => "!credentialDisplayInfo[credential].availability", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} .sk-panel-section{"ng-if" => "sessionExpirey && !sessionExpired"} - .sk-p You will not be asked to authenticate until {{sessionExpirey}}. - %a.sk-a {"ng-click" => "clearSession()"} Clear Session + .sk-p.sk-panel-row You will not be asked to authenticate until {{sessionExpirey}}. + %a.sk-a.sk-panel-row.info{"ng-click" => "clearSession()"} Clear Session .sk-panel-footer .sk-h2 About Privileges .sk-panel-section.no-bottom-pad diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 70ceb1b4e..593cdb990 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -34,6 +34,7 @@ %menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"} %menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"} %menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"} + %menu-row{"label" => "ctrl.note.content.protected ? 'Unprotect' : 'Protect'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleProtectNote()", "desc" => "'Protecting a note will require credentials to view it (Manage Privileges via Account menu)'"} %menu-row{"label" => "'Preview'", "circle" => "ctrl.note.content.hidePreview ? 'danger' : 'success'", "circle-align" => "'right'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} %menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"} diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index fc27d7772..cdccad9e2 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -50,11 +50,11 @@ %strong.red.medium-text{"ng-if" => "note.errorDecrypting"} Unable to Decrypt .note-flags - .pinned{"ng-if" => "note.pinned"} + .pinned.note-flag{"ng-if" => "note.pinned"} %i.icon.ion-bookmark %strong.medium-text Pinned - .archived{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()"} + .archived.note-flag{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()"} %i.icon.ion-ios-box %strong.medium-text Archived @@ -62,8 +62,10 @@ .faded {{note.savedTagsString || note.tagsString()}} .name{"ng-if" => "note.title"} - %span.locked.tinted{"ng-if" => "note.locked", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} + %span.note-flag{"ng-show" => "note.locked"} %i.icon.ion-locked.medium-text + %span.note-flag{"ng-show" => "note.content.protected"} + %i.icon.ion-eye-disabled {{note.title}} .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview && !note.locked"} diff --git a/dist/assets/ionicons.eot b/dist/assets/ionicons.eot index 84145da254ce268171db6307fcd2fa877cb740d3..b2e176a7b4fbe8726f42c8236b3514c5e8f69143 100644 GIT binary patch delta 1437 zcmZ8hO>7%Q6rS0g-PzsodYxsxYbSQn+9WOr*(=itutMs>Y8@(x1UE(h(1`j2NH ztN{KAXl44X)ibCKgI?r%a-(*;esY3Du>TIQa%17`xm?u?K)(v=z4_VNOxu;CmqE7& z6wHG_{0hGdzAV6x&o8bvSo3Gp27<3a@YKTcbWMC9&4Yti0H+pfjXJuDz6E^+@R_CB z;_Nq{_V2)6;|K}3zI=Q2R({|D1TX>m2ExFBrtci=yk_+OftUaSgnp>Jxcu*YvW;N? zRuHJ4;|gwsw@gtfeT3vl!ad_iRz<}~Lh$%zTo{Z!+Wp5>b#qcE z-bCBnJ5Uv94evTHlGBfEjulasBxy_NAwFO?X@SRf)M zFhn8|0+Xu769%S2m@&J%&tEJ`R04A$)k5ZD zL`+yO4E_op%uK6XP(~=Ajh;aLP)gg0lYFi~3t>-T5SLvibR^3OA+g{BmXrK5pOYQ8 z8Tej-+GRI{yt#pmCrf=PD=3`Lx=)TdBc0Dy=gt?4W6tqGqC@Jm6$O`_Y`6bXx1VrD zNz*#*xR!BnuIo~}RkAG`Y?5P_FFMaVpLe7>RKxDlm?XMw!CKIrNtH3Bc9+}%ea+9g zce5^qP3RhEyfx?p1EtYfNMQqg$dmZ{EFfyvPUe$=>-fCFW~xsp^U}sHmnAqnbsT2?nN0 zB^ntpkqJx`PFpB(Dl0KVi77mi5<**_N!@}2cPIR%0v0gucL~cFS{bXGd$fDV?F;Ce jORrxp_qOIs7bENqd)x~C-M?-O01tnA|4W!oT}yugPfPRS delta 522 zcmYLG!AcuZ6g~INBpDNprc?#ZA`6>E3n|zlE<%h%cWQ;Yuu`x?8k15-2Mi_M)GUg) zm07wl2!gl`f-BK~NWq1KanaI+t60H>Fg-J^c;UXe=bX9so%i1U;89=rxdGH7JK-^X zqSbbH^4~W{EgL0pP$K~3s@lX4JV<)KVCF2q&n!VbUxo)^Jc-i z^skOCUwyAZEs03e@^OPvjM3<0+om}i$=+$%qaK6Qc IqK|j*7dmHa_y7O^ diff --git a/dist/assets/ionicons.svg b/dist/assets/ionicons.svg index 16f73af22..41ab5a832 100755 --- a/dist/assets/ionicons.svg +++ b/dist/assets/ionicons.svg @@ -5,7 +5,7 @@ --> -Created by FontForge 20170925 at Thu Dec 13 12:01:05 2018 +Created by FontForge 20170925 at Thu Dec 13 12:46:07 2018 By mo Copyright (c) 2018, mo @@ -19,16 +19,28 @@ Copyright (c) 2018, mo panose-1="2 0 5 3 0 0 0 0 0 0" ascent="448" descent="-64" - bbox="0 -32 384 416" + bbox="0 -64 448 448" underline-thickness="25.6" underline-position="-51.2" - unicode-range="U+F200-F3EC" + unicode-range="U+F200-F4D4" /> + + + 7%Q6rQ&`yR$!Dud}Ro?Z!@8o5ZC;c3AI^(>94w(?lqQ2Gy!sC~2+yG(djb zG$3 z#J^x)o_crXDCq!{i(F2x)o(QR_Rtd1en6~Tn}2UMSM@`bub}wB+)RDCl%pbRhl?@$>UbQ+4s4G=~N*BTg;Un+-m9G=s*qS&314Y;M50??p`rZ|3!2GX+nOgTw2zB7QO%LJ5XO68PYrZL&SP{r2{!JMzwNyIYuR&dfZ` z#6{zl@r7~S5Mo(9Jg|la{%f#N64IbR3YOufu(km3Dt$v z0kWQy zJ}0|gD-8SsbIM+XadQO+E|&UJc33!>^-hetqg^jmXHOQ3LkZU&bY6*Uw5WDRnzI#bV>9&!qu=RlPUvaPPg2N zmCl{+Tfal27S<6~;wn~#Nz&vPhVU`@j0f@LEYNGuN#>KG=LS5()EjPIX-~b<>DbSu*1ZOQ$l88>VI&s!lb=Qc_xM z$r4S`6k{q?akpk#s>rBrC2Un{@77IC$K9%&rW>W{tFY0#>9pG7lN^|;0QLX zqQ^~iVRG$9bfMOK!_t}2!D326Q)DHsBo$kuhG0mBEE|Ft6Jk`em85DY(x9SRN{neX z(=Al6R3@>uf-dTUE((V=lsJ=>n5o1R?n#M|ja}L!xH_*uyom(h^)7)7SjwQTpI|*h pUVq5mS$uP(+;=daJ=4biu+O#dZ{EK{5ZwRclW%Z(>Y}=|^bbie@1_6% delta 522 zcmY*VJ4ho@6g_ullFUY9h?p(b6e-k3h!90Af*;&XrCAqKsEBch`G}4V7(^>m1q-_= zx7akhY##(Gar-S@uvjD(iiL$l1q)$3Gr_{g+&Ax>^X_@~-uvit*8v1T2vw+RQRzu^fj^2xN)% z(&m2gL-gZ6>NC9myIe5VBH_z%YX2Fd<#OS`Q0HWwVh@SFvRT;+Tq8n!LLA@R&KvR~ zhcsXj=r)Z#3$tKx;^O$0VHQq*rvC8lM?ev4d#5t(tCax%Gxa5}IX2k5JfFygQ%~qn zNCOvRnP&UHlDPt$rc|X)LPuMtKfk)uL_(_WMebzYE!|^u47&YtxtZc|lSp`sCNuW3 zjCVfV$(eITt2*NLFG*x%($n2MH)38EkR@_oi9v(gUeK#YX`xkYZ9Lp@vf#PUK6k01 zAEED^y^uy)84wNUK%=6XVlVnrjc~H99LGQVVJn+6IU$-&cNG=eED05rDJthj7Z1O_W458qkNiH5&5shT>xM3j zOI?R7mE!9BI4%9SX(=X6{rx;XSM^H`#i>3l z7C-^G@TI_DZr7iji~qM+tbpy%mkDc&pe*ykJrDT!+cN+_RlwW}3UTj6Hb)BB@c^Lb z!8{1o67N&H5+hTRD3Ea=!+wzwYBP_$M+}YlBnalr^K?3Z;q6Z6LSq&Hm_yJzXzj*y zm`p|sH%;tpY z(&G!*X>cwIUPKHi5K@3YPzl+BC;)IISTKhNP;FJNm*eC1z@Nj<4c!8jmat@$NDyGx!;WGU39P^d4@;RfvHz+3}15vfopZYUIES4yud6pz2Dy2RMR zXr$3-^m>MaA{*p%kfbBB_O8hSwaVl=MrTMHqmz+%pzmO9a3gs-;cZy{bTD=3Hp#(6OrS69ee;HD=(N$w@3@@% zK7dlwqo1xkTIBNcU)&$qy)mUG1-?hCq{w6{|a;tsnP?MH;_m~%zl8hfVKEF>y>WgOPr-yu_S-e{im?twma`IF^cEo$l zqI#N5eUIxFaq)tk-kIRGr^WWO`BtgLo_KZ7&}dJ?Ke4fR^(Xt9({IsKib2bYY00mH zTLU_28SW3q_R_{)t;#r|AV@V^jzvqIr2M zvb3F=QC;z#5&lk-eR2NQh1XP~M$5JJZzP&+i+MPIo>-(g$ZJqlRXvx|Cd}pg%+GC= ztUNLDs>7o8V_WKShxwnB_C>Uk#R(gjxDyKsqdmw^qf>TO?qAwob{}_r6Is0b)7@X{ z6RC#l9Un+jjxX0RGWmfiB}UafQ>v+FpYP4Ai9OpF@04-YXGd6NYqOJcvlF^F@%W#7 z$^2qjHM?AVVQ0;@hVetOeys5$g8m~yzuc+nKEE-8j=dA^>BBm)42iR}I$CK(j;kA;nVGh>vuvKeR?vF&m8W(=c+=90i&~djZld{` zwoMXaY>sg0T$`BfwZ2!3+l2GCkDWQ0a79xsN!vBL$l}tqa(Qj3Tq~tKuPBhMirE;( z*{sxY@>@251{G!n%2`O^a*zm41c%FEbD}tr9NsW8%(3rOB{?u?SzX-f9|nkCF7ABq kd5`*mSBrCQw6Uo%`0k1EY%xX8oM1i0W&+P+~3WOfsp|SSX~%+K{R^>h{Oim+(LYT>NJ3I(m*WJ7H^d6AFOZ0z`(c! z$oBx^1jnuM7RkAZ1q=*K96){$P%i34wyYcff5WL z#T@_tGcc#;RHgwHmH;(|1Mvz@QL(ETsfj5-wgFI$ArPAh^53(|015)dfZ`0YK&-+X zz?hklTLN@E;~OAf28b2dpE3yMxo>V+#XAJ%c<*A%ibN zOkQGcDgy)a8K8tDPy^$>r8Wl(@{55EVR->mV*$ib&a7?e6}OTTQW6pv9U_A&r4iO(89Xq0`dfMI#FXM?S+UumOo*66YK^aOwcVlFJej z5_cAU31{T!J;xl zB7jl(@CJ4UaS6d5pwEEu3?#L{Fo~g#VGhGKhAW^D37uf?f2iI;;@JJ|qE)?SnT<(G z^}n7AdC6?~5~afEDPATvL&EB#XiWYWZ3*!*@t033lBvU5G)cfnmmc$$?4GLH}>tbdj7djEdJQ8l%hF3XwH)0 zAAc9yFzvi^Yi7<=1>dA))1)gEn*=5*sxKDQv}il3r+srxA(_d}5^V|2)&Bpr@ z$s(5zY+mW^TQc9**wnXiW#pT)0Uf=sKmFu)(F;DcnV(IY(T@+9f)bKal2X!A5>rxB zlJ(D?E-^MTXt)UbN~PV From 2e9324f4408d0c889663283c71d8e29735d38311 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 13 Dec 2018 16:28:11 -0600 Subject: [PATCH 29/62] UI updates --- app/assets/javascripts/app/services/componentManager.js | 2 ++ app/assets/templates/notes.html.haml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index c611f8e41..628561489 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -658,6 +658,8 @@ class ComponentManager { } }, 10); } + } else { + this.activateComponent(component); } } } diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index cdccad9e2..1053c5038 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -4,7 +4,7 @@ .padded .section-title-bar-header .title {{ctrl.panelTitle()}} - .sk-button.contrast.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + .sk-button.sk-secondary.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} .sk-label + .filter-section{"role" => "search"} %input.filter-bar#search-bar.mousetrap{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", From ee86e686318449566ced17f804646aee8ff47427 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 00:46:21 -0600 Subject: [PATCH 30/62] Set loading to false after error load component view --- app/assets/javascripts/app/directives/views/componentView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index de807f819..98012d08f 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -71,6 +71,7 @@ class ComponentView { if($scope.loadTimeout) { $timeout.cancel($scope.loadTimeout);} $scope.loadTimeout = $timeout(() => { if($scope.loading) { + $scope.loading = false; $scope.issueLoading = true; } }, 3500); From fee6bdd0580eacad2e29cc9daebc2b73de6b7901 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 00:58:47 -0600 Subject: [PATCH 31/62] Reload component if issue loading --- .../app/directives/views/componentView.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index 98012d08f..8553f0326 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -30,6 +30,16 @@ class ComponentView { controller($scope, $rootScope, $timeout, componentManager, desktopManager, themeManager) { 'ngInject'; + $scope.onVisibilityChange = function() { + if(document.visibilityState == "hidden") { + return; + } + + if($scope.issueLoading) { + $scope.reloadComponent(); + } + } + $scope.themeHandlerIdentifier = "component-view-" + Math.random(); componentManager.registerHandler({identifier: $scope.themeHandlerIdentifier, areas: ["themes"], activationHandler: (component) => { $scope.reloadThemeStatus(); @@ -73,6 +83,14 @@ class ComponentView { if($scope.loading) { $scope.loading = false; $scope.issueLoading = true; + + if(!$scope.didAttemptReload) { + $scope.didAttemptReload = true; + $scope.reloadComponent(); + } else { + // We'll attempt to reload when the tab gains focus + document.addEventListener("visibilitychange", $scope.onVisibilityChange); + } } }, 3500); iframe.onload = (event) => { @@ -206,6 +224,7 @@ class ComponentView { } desktopManager.deregisterUpdateObserver($scope.updateObserver); + document.removeEventListener("visibilitychange", $scope.onVisibilityChange); } $scope.$on("$destroy", function() { From d5bf543990c469a889e26ec378e3f1bba4e8b0cf Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 01:24:00 -0600 Subject: [PATCH 32/62] Dont display previews for protected notes --- app/assets/templates/notes.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index 1053c5038..d43a50974 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -68,7 +68,7 @@ %i.icon.ion-eye-disabled {{note.title}} - .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview && !note.locked"} + .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview && !note.content.protected"} .html-preview{"ng-if" => "note.content.preview_html", "ng-bind-html" => "note.content.preview_html"} .plain-preview{"ng-if" => "!note.content.preview_html && note.content.preview_plain"} {{note.content.preview_plain}} .default-preview{"ng-if" => "!note.content.preview_html && !note.content.preview_plain"} {{note.text}} From b5c44f643dfe37a9b2f40574fc96f26ca75bd02f Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 01:28:00 -0600 Subject: [PATCH 33/62] Loading overlay relative parent --- app/assets/stylesheets/app/_modals.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 2e41059fa..1bd3141d9 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -168,6 +168,7 @@ flex-grow: 1; display: flex; flex-direction: column; + position: relative; // not sure why we need this. Removed because it creates unncessary scroll bars. Tested on folders extension, creates horizontal scrollbar at bottom on windows // overflow: auto; @@ -183,6 +184,8 @@ background-color: var(--sn-stylekit-editor-background-color); width: 100%; height: 100%; + left: 0; + top: 0; } iframe { From 6dad78715b8c69c9fa575f72c4ad8191dd44a963 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 14:12:02 -0600 Subject: [PATCH 34/62] Use editors for revision preview --- .../javascripts/app/controllers/editor.js | 12 +---- .../directives/views/revisionPreviewModal.js | 46 +++++++++++++++++-- .../app/services/componentManager.js | 37 ++++++++++++++- .../revision-preview-modal.html.haml | 4 +- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 5855c2a0a..830585bd8 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -158,17 +158,7 @@ angular.module('app') } this.editorForNote = function(note) { - let editors = componentManager.componentsForArea("editor-editor"); - for(var editor of editors) { - if(editor.isExplicitlyEnabledForItem(note)) { - return editor; - } - } - - // No editor found for note. Use default editor, if note does not prefer system editor - if(!note.getAppDataItem("prefersPlainEditor")) { - return editors.filter((e) => {return e.isDefaultEditor()})[0]; - } + return componentManager.editorForNote(note); } this.closeAllMenus = function() { diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js index d5d6313d3..03fde5113 100644 --- a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -10,15 +10,51 @@ class RevisionPreviewModal { } link($scope, el, attrs) { - - $scope.dismiss = function() { - el.remove(); - } + $scope.el = el; } - controller($scope, modelManager, syncManager) { + controller($scope, modelManager, syncManager, componentManager) { 'ngInject'; + $scope.dismiss = function() { + $scope.el.remove(); + $scope.$destroy(); + } + + $scope.$on("$destroy", function() { + componentManager.deregisterHandler($scope.identifier); + }); + + $scope.note = new SFItem({content: $scope.content, content_type: "Note"}); + // Set UUID to editoForNote can find proper editor, + // but then generate new uuid for note as not to save changes to original, if editor makes changes. + $scope.note.uuid = $scope.uuid; + let editor = componentManager.editorForNote($scope.note); + $scope.note.uuid = SFJS.crypto.generateUUIDSync(); + + if(editor) { + // Create temporary copy, as a lot of componentManager is uuid based, + // so might interfere with active editor. Be sure to copy only the content, as the + // top level editor object has non-copyable properties like .window, which cannot be transfered + $scope.editor = new SNComponent({content: editor.content}); + $scope.editor.readonly = true; + $scope.identifier = $scope.editor.uuid; + + componentManager.registerHandler({identifier: $scope.identifier, areas: ["editor-editor"], + contextRequestHandler: (component) => { + if(component == $scope.editor) { + return $scope.note; + } + }, + componentForSessionKeyHandler: (key) => { + if(key == $scope.editor.sessionKey) { + return $scope.editor; + } + } + }); + } + + $scope.restore = function(asCopy) { if(!asCopy && !confirm("Are you sure you want to replace the current note's contents with what you see in this preview?")) { return; diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 628561489..ac0b4d34a 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -294,7 +294,15 @@ class ComponentManager { } componentForSessionKey(key) { - return _.find(this.components, {sessionKey: key}); + let component = _.find(this.components, {sessionKey: key}); + if(!component) { + for(let handler of this.handlers) { + if(handler.componentForSessionKeyHandler) { + component = handler.componentForSessionKeyHandler(key); + } + } + } + return component; } handleMessage(component, message) { @@ -350,7 +358,7 @@ class ComponentManager { // Notify observers for(let handler of this.handlers) { - if(handler.areas.includes(component.area) || handler.areas.includes("*")) { + if(handler.actionHandler && (handler.areas.includes(component.area) || handler.areas.includes("*"))) { this.timeout(function(){ handler.actionHandler(component, message.action, message.data); }) @@ -465,6 +473,13 @@ class ComponentManager { } handleSaveItemsMessage(component, message) { + if(component.readonly) { + // A component can be marked readonly if changes should not be saved. + // Particullary used for revision preview windows where the notes should not be savable. + alert(`The extension ${component.name} is trying to save, but it is in a locked state and cannot accept changes.`); + return; + } + var responseItems = message.data.items; var requiredPermissions; @@ -798,6 +813,10 @@ class ComponentManager { deregisterHandler(identifier) { var handler = _.find(this.handlers, {identifier: identifier}); + if(!handler) { + console.log("Attempting to deregister non-existing handler"); + return; + } this.handlers.splice(this.handlers.indexOf(handler), 1); } @@ -1021,6 +1040,20 @@ class ComponentManager { } } + editorForNote(note) { + let editors = this.componentsForArea("editor-editor"); + for(var editor of editors) { + if(editor.isExplicitlyEnabledForItem(note)) { + return editor; + } + } + + // No editor found for note. Use default editor, if note does not prefer system editor + if(!note.getAppDataItem("prefersPlainEditor")) { + return editors.filter((e) => {return e.isDefaultEditor()})[0]; + } + } + } diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml index d9b8e3b87..bd0a5158a 100644 --- a/app/assets/templates/directives/revision-preview-modal.html.haml +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -10,6 +10,8 @@ %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .sk-panel-content.selectable + .sk-panel-content.selectable{"ng-if" => "!editor"} .sk-h2 {{content.title}} %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} + + %component-view.component-view{"ng-if" => "editor", "component" => "editor"} From dde857c4e1584a73eb13ea1dce21a82f14f36ee3 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 17:52:56 -0600 Subject: [PATCH 35/62] Save status display updates --- app/assets/javascripts/app/controllers/editor.js | 6 +++--- app/assets/stylesheets/app/_editor.scss | 6 +++++- app/assets/stylesheets/app/_main.scss | 1 - app/assets/templates/directives/account-menu.html.haml | 3 +-- app/assets/templates/editor.html.haml | 6 ++++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 830585bd8..8bdb9a05d 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -324,7 +324,7 @@ angular.module('app') } this.showSavingStatus = function() { - this.noteStatus = $sce.trustAsHtml("Saving..."); + this.noteStatus = {message: "Saving..."}; } this.showAllChangesSavedStatus = function() { @@ -335,7 +335,7 @@ angular.module('app') if(authManager.offline()) { status += " (offline)"; } - this.noteStatus = $sce.trustAsHtml(status); + this.noteStatus = {message: status}; } this.showErrorStatus = function(error) { @@ -347,7 +347,7 @@ angular.module('app') } this.saveError = true; this.syncTakingTooLong = false; - this.noteStatus = $sce.trustAsHtml(`${error.message}
${error.desc}`) + this.noteStatus = error; } this.contentChanged = function() { diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index aac1a7994..712bb4043 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -63,7 +63,11 @@ $heading-height: 75px; font-weight: normal; margin-top: 4px; text-align: right; - color: var(--sn-stylekit-secondary-contrast-background-color); + + .desc, .message:not(.warning):not(.danger) { + // color: var(--sn-stylekit-editor-foreground-color); + opacity: 0.35; + } } .editor-tags { diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index ada2d1d9b..6031bf199 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -53,7 +53,6 @@ input, button, select, textarea { } a { - color: var(--sn-stylekit-info-color); text-decoration: none; &.no-decoration { diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index f16f8b4c8..3bf603c4d 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -84,8 +84,7 @@ .sk-notification.danger{"ng-if" => "syncStatus.error"} .sk-notification-title Sync Unreachable .sk-notification-text Hmm...we can't seem to sync your account. The reason: {{syncStatus.error.message}} - %p - %a{"href" => "https://standardnotes.org/help", "target" => "_blank"} Need help? + %a.sk-a.info-contrast.sk-bold.sk-panel-row{"href" => "https://standardnotes.org/help", "target" => "_blank"} Need help? .sk-panel-row .sk-panel-column diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 593cdb990..5750ff563 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -1,4 +1,4 @@ -.section.editor#editor-column{"aria-label" => "Note"} +.section.editor#editor-column.sn-component{"aria-label" => "Note"} .sn-component .sk-app-bar.no-edges{"ng-if" => "ctrl.note.locked", "ng-init" => "ctrl.lockText = 'Note Locked'", "ng-mouseover" => "ctrl.lockText = 'Unlock'", "ng-mouseleave" => "ctrl.lockText = 'Note Locked'"} .left @@ -13,7 +13,9 @@ "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} - #save-status{"ng-class" => "{'warning bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} + #save-status + .message{"ng-class" => "{'warning sk-bold': ctrl.syncTakingTooLong, 'danger sk-bold': ctrl.saveError}"} {{ctrl.noteStatus.message}} + .desc{"ng-show" => "ctrl.noteStatus.desc"} {{ctrl.noteStatus.desc}} .editor-tags #note-tags-component-container{"ng-if" => "ctrl.tagsComponent"} From f7dfec36f88c4e0882e3b4821b75c697efaadca6 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 14 Dec 2018 22:09:41 -0600 Subject: [PATCH 36/62] Singleton manager uuid change observer --- .../app/directives/views/accountMenu.js | 4 ---- .../javascripts/app/services/privilegesManager.js | 2 -- .../javascripts/app/services/singletonManager.js | 14 ++++++++++++++ package-lock.json | 6 +++--- package.json | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index 82901adfd..f163892ce 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -15,10 +15,6 @@ class AccountMenu { $scope.formData = {mergeLocal: true, ephemeral: false}; - // testing: - // $scope.formData.status = "Generating Login Keys..."; - // $scope.formData.authenticating = true; - $scope.user = authManager.user; syncManager.getServerURL().then((url) => { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 1d9028f9e..f79177784 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -124,7 +124,6 @@ class PrivilegesManager { if(!this.privileges.content.desktopPrivileges) { this.privileges.content.desktopPrivileges = {}; } - console.log("Resolved existing privs", resolvedSingleton.uuid); resolve(resolvedSingleton); }, (valueCallback) => { // Safe to create. Create and return object. @@ -133,7 +132,6 @@ class PrivilegesManager { privs.setDirty(true); this.$rootScope.sync(); valueCallback(privs); - console.log("Creating new privs", privs.uuid); resolve(privs); }); }); diff --git a/app/assets/javascripts/app/services/singletonManager.js b/app/assets/javascripts/app/services/singletonManager.js index 3df8cbbdd..ddee5b64a 100644 --- a/app/assets/javascripts/app/services/singletonManager.js +++ b/app/assets/javascripts/app/services/singletonManager.js @@ -26,6 +26,20 @@ class SingletonManager { this.resolveSingletons(modelManager.allItems, null, true); }) + /* + If an item alternates its uuid on registration, singletonHandlers might need to update + their local refernece to the object, since the object reference will change on uuid alternation + */ + modelManager.addModelUuidChangeObserver("singleton-manager", (oldModel, newModel) => { + for(var handler of this.singletonHandlers) { + if(handler.singleton && SFPredicate.ItemSatisfiesPredicates(newModel, handler.predicates)) { + // Reference is now invalid, calling resolveSingleton should update it + handler.singleton = null; + this.resolveSingletons([newModel]); + } + } + }) + $rootScope.$on("sync:completed", (event, data) => { // The reason we also need to consider savedItems in consolidating singletons is in case of sync conflicts, // a new item can be created, but is never processed through "retrievedItems" since it is only created locally then saved. diff --git a/package-lock.json b/package-lock.json index 5bf46c70b..1fdc31c67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8969,9 +8969,9 @@ "dev": true }, "standard-file-js": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.20.tgz", - "integrity": "sha512-KlJ3IbAaJDRVC8jKxHBi/LL80d8zIbL1nZqwbDmqif1XwDQpTb8BB7ejg5pzZExQKDRFeXLS0JDSeWGMD+Luhw==", + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.21.tgz", + "integrity": "sha512-MLic68jA/EPqmNHbI2qrQn3V6/ZgazzM7C4AD6o2mORu3ZrFk64K0FPIrpN4LuA8IJi3sOqOFKsp1/caVw0zrw==", "dev": true }, "static-extend": { diff --git a/package.json b/package.json index 12eb97359..e5c4c0613 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "serve-static": "^1.13.2", "sn-models": "0.1.9", "sn-stylekit": "file:~/Desktop/sn/dev/stylekit", - "standard-file-js": "0.3.20", + "standard-file-js": "0.3.21", "grunt-shell": "^2.1.0" } } From dcd44083acd27109deb8675353677ac9f3dd6e53 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sat, 15 Dec 2018 12:22:41 -0600 Subject: [PATCH 37/62] Editor stack app bar, expired components enter readonly state --- .../javascripts/app/controllers/editor.js | 7 +- .../app/directives/views/componentView.js | 16 +++-- .../app/directives/views/editorMenu.js | 11 --- .../app/services/componentManager.js | 25 +++++-- app/assets/stylesheets/app/_editor.scss | 8 ++- .../directives/component-view.html.haml | 70 ++++--------------- .../directives/editor-menu.html.haml | 9 --- app/assets/templates/editor.html.haml | 8 +++ 8 files changed, 64 insertions(+), 90 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 8bdb9a05d..d416f2565 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -674,9 +674,14 @@ angular.module('app') } }}); + this.reloadComponentContext = function() { // componentStack is used by the template to ng-repeat - this.componentStack = componentManager.componentsForArea("editor-stack"); + this.componentStack = componentManager.componentsForArea("editor-stack").sort((a, b) => { + // Careful here. For some reason, sorting by updated_at (or any other property that may always be changing) + // causes weird problems with ext communication when changing notes or activating/deactivating in quick succession + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }); /* In the past, we were doing this looping code even if the note wasn't currently defined. The problem is if an editor stack item loaded first, requested to stream items, and the note was undefined, diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index 8553f0326..d73dc8476 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -149,7 +149,7 @@ class ComponentView { $scope.reloading = true; let previouslyValid = $scope.componentValid; - var expired, offlineRestricted, urlError; + var offlineRestricted, urlError; offlineRestricted = component.offlineOnly && !isDesktopApplication(); @@ -158,13 +158,19 @@ class ComponentView { || (isDesktopApplication() && (!component.local_url && !component.hasValidHostedUrl())) - expired = component.valid_until && component.valid_until <= new Date(); + $scope.expired = component.valid_until && component.valid_until <= new Date(); - $scope.componentValid = !offlineRestricted && !urlError && !expired; + component.readonly = $scope.expired; + + $scope.componentValid = !offlineRestricted && !urlError; + + if(!$scope.componentValid) { + // required to disable overlay + $scope.loading = false; + } if(offlineRestricted) $scope.error = 'offline-restricted'; else if(urlError) $scope.error = 'url-missing'; - else if(expired) $scope.error = 'expired'; else $scope.error = null; if($scope.componentValid !== previouslyValid) { @@ -174,7 +180,7 @@ class ComponentView { } } - if(expired && doManualReload) { + if($scope.expired && doManualReload) { // Try reloading, handled by footer, which will open Extensions window momentarily to pull in latest data // Upon completion, this method, reloadStatus, will be called, upon where doManualReload will be false to prevent recursion. $rootScope.$broadcast("reload-ext-data"); diff --git a/app/assets/javascripts/app/directives/views/editorMenu.js b/app/assets/javascripts/app/directives/views/editorMenu.js index 8736f484b..47bde5dd2 100644 --- a/app/assets/javascripts/app/directives/views/editorMenu.js +++ b/app/assets/javascripts/app/directives/views/editorMenu.js @@ -19,10 +19,6 @@ class EditorMenu { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); - $scope.stack = componentManager.componentsForArea("editor-stack").sort((a, b) => { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; - }); - $scope.isDesktop = isDesktopApplication(); $scope.defaultEditor = $scope.editors.filter((e) => {return e.isDefaultEditor()})[0]; @@ -77,17 +73,10 @@ class EditorMenu { if(component == $scope.selectedEditor) { return true; - } else if(component.area == "editor-stack") { - return $scope.stackComponentEnabled(component); } else { return false; } } - - $scope.stackComponentEnabled = function(component) { - return component.active && !component.isExplicitlyDisabledForItem($scope.currentItem); - } - } } diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index ac0b4d34a..ebc707029 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -313,6 +313,24 @@ class ComponentManager { return; } + // Actions that won't succeeed with readonly mode + let readwriteActions = [ + "save-items", + "associate-item", + "deassociate-item", + "create-item", + "create-items", + "delete-items", + "set-component-data" + ]; + + if(component.readonly && readwriteActions.includes(message.action)) { + // A component can be marked readonly if changes should not be saved. + // Particullary used for revision preview windows where the notes should not be savable. + alert(`The extension ${component.name} is trying to save, but it is in a locked state and cannot accept changes.`); + return; + } + /** Possible Messages: set-size @@ -473,13 +491,6 @@ class ComponentManager { } handleSaveItemsMessage(component, message) { - if(component.readonly) { - // A component can be marked readonly if changes should not be saved. - // Particullary used for revision preview windows where the notes should not be savable. - alert(`The extension ${component.name} is trying to save, but it is in a locked state and cannot accept changes.`); - return; - } - var responseItems = message.data.items; var requiredPermissions; diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 712bb4043..66ffa9678 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -132,7 +132,13 @@ $heading-height: 75px; width: 100%; // When two component stack items are expired and eat up full screen, this is required to scroll them. - overflow: auto; + // overflow: auto; + // When expired components, without this, requires scroll + overflow: visible; + + #component-stack-menu-bar { + border-bottom: none; + } .component-stack-item { width: 100%; diff --git a/app/assets/templates/directives/component-view.html.haml b/app/assets/templates/directives/component-view.html.haml index 985e64a45..e68436225 100644 --- a/app/assets/templates/directives/component-view.html.haml +++ b/app/assets/templates/directives/component-view.html.haml @@ -18,62 +18,20 @@ .sk-app-bar-item{"ng-click" => "disableActiveTheme()"} .sk-label Disable Active Theme -.sn-component{"ng-if" => "error == 'expired'"} - .sk-panel.static - .sk-panel-content - .sk-panel-section.stretch - .sk-panel-sectin-title Unable to load Standard Notes Extended - %p Your Extended subscription expired on {{component.dateToLocalizedString(component.valid_until)}}. - %p - Please visit - %a{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} dashboard.standardnotes.org - to renew your subscription. - .sk-panel-row - .sk-panel-column - %p - %strong To reload your account status: - %p - %ol - %li - Open the - %strong Extensions - menu located in the lower left corner of the app to refresh your account status. - %li Click Reload below. - - .sk-panel-row - .sk-button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} - .sk-label Reload - .sk-spinner.info.small{"ng-if" => "reloading"} - - .sk-panel-row - .sk-panel-section - %p{"ng-if" => "component.isEditor()"} - Otherwise, please follow the steps below to disable any external editors, - so you can edit your note using the plain text editor instead. - - %p To temporarily disable this extension: - - .sk-panel-row - .sk-button.info{"ng-click" => "destroy()"} - .sk-label Disable Extension - .sk-spinner.info.small{"ng-if" => "reloading"} - - .sk-panel-row - - %div{"ng-if" => "component.isEditor()"} - %p To disassociate this note from this editor: - - %ol - %li Click the "Editor" menu item above (under the note title). - %li Select "Plain Editor". - %li Repeat this for every note you'd like to access. You can also delete the editor completely to disable it for all notes. To do so, click "Extensions" in the lower left corner of the app, then, for every editor, click "Uninstall". - - %p - Need help? Please email us at - %a{"href" => "mailto:hello@standardnotes.org", "target" => "_blank"} hello@standardnotes.org - or check out the - %a{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help - page. +.sn-component{"ng-if" => "expired"} + .sk-app-bar + .left + .sk-app-bar-item + .sk-app-bar-item-column + .sk-circle.danger.small + .sk-app-bar-item-column + %a.sk-label.sk-base{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} + Your Extended subscription expired on {{component.dateToLocalizedString(component.valid_until)}}. + Extensions are in a read-only state. + .right + .sk-app-bar-item + .sk-app-bar-item-column + %a.sk-label{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help .sn-component{"ng-if" => "error == 'offline-restricted'"} .sk-panel.static diff --git a/app/assets/templates/directives/editor-menu.html.haml b/app/assets/templates/directives/editor-menu.html.haml index 4bd52d9a0..cc0ff2dcd 100644 --- a/app/assets/templates/directives/editor-menu.html.haml +++ b/app/assets/templates/directives/editor-menu.html.haml @@ -15,12 +15,3 @@ %a.no-decoration{"ng-if" => "editors.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"} %menu-row{"label" => "'Download More Editors'"} - - .sk-menu-panel-section{"ng-if" => "stack.length > 0"} - .sk-menu-panel-header - .sk-menu-panel-header-title Editor Stack - %menu-row{"ng-repeat" => "component in stack", "action" => "selectComponent(component)", "label" => "component.name", - "circle" => "stackComponentEnabled(component) ? 'success' : 'danger'"} - .sk-menu-panel-column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"} - %strong.danger.medium-text{"ng-if" => "component.conflict_of"} Conflicted copy - .sk-sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 5750ff563..8078ef1e2 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -82,6 +82,14 @@ %p.medium-padding{"style" => "padding-top: 0 !important;"} There was an error decrypting this item. Ensure you are running the latest version of this app, then sign out and sign back in to try again. #editor-pane-component-stack + #component-stack-menu-bar.sk-app-bar + .left + .sk-app-bar-item{"ng-repeat" => "component in ctrl.componentStack", "ng-click" => "ctrl.toggleStackComponentForCurrentItem(component)"} + .sk-app-bar-item-column + .sk-circle.small{"ng-class" => "{'info' : !component.hidden && component.active, 'neutral' : component.hidden || !component.active}"} + .sk-app-bar-item-column + .sk-label {{component.name}} + .sn-component %component-view.component-view.component-stack-item{"ng-repeat" => "component in ctrl.componentStack", "ng-if" => "component.active", "ng-show" => "!component.hidden", "manual-dealloc" => "true", "component" => "component"} From 1d59fb7c902e44fe40951f36caa03ee473749f3b Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 16 Dec 2018 12:05:40 -0600 Subject: [PATCH 38/62] Add collapsed classes on app element --- app/assets/javascripts/app/controllers/home.js | 11 +++++++++++ app/assets/javascripts/app/controllers/notes.js | 6 +++++- app/assets/javascripts/app/controllers/tags.js | 6 +++++- .../javascripts/app/directives/views/panelResizer.js | 8 ++++++-- app/assets/stylesheets/app/_main.scss | 3 ++- app/assets/templates/editor.html.haml | 2 +- app/assets/templates/home.html.haml | 6 +++--- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/app/controllers/home.js b/app/assets/javascripts/app/controllers/home.js index 72e095a93..2581f72cc 100644 --- a/app/assets/javascripts/app/controllers/home.js +++ b/app/assets/javascripts/app/controllers/home.js @@ -11,6 +11,17 @@ angular.module('app') $rootScope.$broadcast('new-update-available', version); } + $rootScope.$on("panel-resized", (event, info) => { + if(info.panel == "notes") { this.notesCollapsed = info.collapsed; } + if(info.panel == "tags") { this.tagsCollapsed = info.collapsed; } + + let appClass = ""; + if(this.notesCollapsed) { appClass += "collapsed-notes"; } + if(this.tagsCollapsed) { appClass += " collapsed-tags"; } + + $scope.appClass = appClass; + }) + /* Used to avoid circular dependencies where syncManager cannot be imported but rootScope can */ $rootScope.sync = function(source) { syncManager.sync(); diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 0247d0088..194771af9 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -66,14 +66,18 @@ angular.module('app') let width = authManager.getUserPrefValue("notesPanelWidth"); if(width) { this.panelController.setWidth(width); + if(this.panelController.isCollapsed) { + $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: this.panelController.isCollapsed}) + } } } this.loadPreferences(); - this.onPanelResize = function(newWidth) { + this.onPanelResize = function(newWidth, lastLeft, isAtMaxWidth, isCollapsed) { authManager.setUserPrefValue("notesPanelWidth", newWidth); authManager.syncUserPreferences(); + $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: isCollapsed}) } angular.element(document).ready(() => { diff --git a/app/assets/javascripts/app/controllers/tags.js b/app/assets/javascripts/app/controllers/tags.js index 52d15de84..dc808b43f 100644 --- a/app/assets/javascripts/app/controllers/tags.js +++ b/app/assets/javascripts/app/controllers/tags.js @@ -47,13 +47,17 @@ angular.module('app') let width = authManager.getUserPrefValue("tagsPanelWidth"); if(width) { this.panelController.setWidth(width); + if(this.panelController.isCollapsed) { + $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: this.panelController.isCollapsed}) + } } } this.loadPreferences(); - this.onPanelResize = function(newWidth) { + this.onPanelResize = function(newWidth, lastLeft, isAtMaxWidth, isCollapsed) { authManager.setUserPrefValue("tagsPanelWidth", newWidth, true); + $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: isCollapsed}) } this.componentManager = componentManager; diff --git a/app/assets/javascripts/app/directives/views/panelResizer.js b/app/assets/javascripts/app/directives/views/panelResizer.js index fc31c0ca6..492c2084f 100644 --- a/app/assets/javascripts/app/directives/views/panelResizer.js +++ b/app/assets/javascripts/app/directives/views/panelResizer.js @@ -32,6 +32,10 @@ class PanelResizer { scope.control.flash = function() { scope.flash(); } + + scope.control.isCollapsed = function() { + return scope.isCollapsed(); + } } controller($scope, $element, modelManager, actionsManager, $timeout, $compile) { @@ -61,7 +65,7 @@ class PanelResizer { $scope.setWidth(minWidth); } $scope.finishSettingWidth(); - $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth()); + $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth(), collapsed); }) } @@ -274,7 +278,7 @@ class PanelResizer { let isMaxWidth = $scope.isAtMaxWidth(); if($scope.onResizeFinish) { - $scope.onResizeFinish()(lastWidth, lastLeft, isMaxWidth); + $scope.onResizeFinish()(lastWidth, lastLeft, isMaxWidth, $scope.isCollapsed()); } $scope.finishSettingWidth(); diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index 6031bf199..3209ae1d0 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -147,7 +147,8 @@ $footer-height: 32px; &.collapsed { opacity: 1; - background-color: var(--sn-stylekit-contrast-background-color); + // so it blends in with editor a bit more + background-color: var(--sn-stylekit-editor-background-color); } &.dragging { diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 8078ef1e2..91b3678ec 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -82,7 +82,7 @@ %p.medium-padding{"style" => "padding-top: 0 !important;"} There was an error decrypting this item. Ensure you are running the latest version of this app, then sign out and sign back in to try again. #editor-pane-component-stack - #component-stack-menu-bar.sk-app-bar + #component-stack-menu-bar.sk-app-bar.no-edges{"ng-if" => "ctrl.componentStack.length"} .left .sk-app-bar-item{"ng-repeat" => "component in ctrl.componentStack", "ng-click" => "ctrl.toggleStackComponentForCurrentItem(component)"} .sk-app-bar-item-column diff --git a/app/assets/templates/home.html.haml b/app/assets/templates/home.html.haml index b8d03b4d3..4ca4c5695 100644 --- a/app/assets/templates/home.html.haml +++ b/app/assets/templates/home.html.haml @@ -1,11 +1,11 @@ .main-ui-view{"ng-class" => "platform"} + %lock-screen{"ng-if" => "needsUnlock", "on-success" => "onSuccessfulUnlock"} - .app#app{"ng-if" => "!needsUnlock"} + + .app#app{"ng-if" => "!needsUnlock", "ng-class" => "appClass"} %tags-section{"save" => "tagsSave", "add-new" => "tagsAddNew", "selection-made" => "tagsSelectionMade", "all-tag" => "allTag", "archive-tag" => "archiveTag", "tags" => "tags", "remove-tag" => "removeTag"} - %notes-section{"add-new" => "notesAddNew", "selection-made" => "notesSelectionMade", "tag" => "selectedTag"} - %editor-section{"note" => "selectedNote", "remove" => "deleteNote", "update-tags" => "updateTagsForNote"} %footer{"ng-if" => "!needsUnlock"} From 31d44af52ef0575590f2a06c6daecff3bac5dfe1 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 16 Dec 2018 12:43:29 -0600 Subject: [PATCH 39/62] componentManager duplicate-item message --- .../javascripts/app/controllers/editor.js | 3 +- .../app/services/componentManager.js | 20 + package-lock.json | 886 +----------------- package.json | 4 +- 4 files changed, 31 insertions(+), 882 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index d416f2565..61284ea0f 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -678,7 +678,8 @@ angular.module('app') this.reloadComponentContext = function() { // componentStack is used by the template to ng-repeat this.componentStack = componentManager.componentsForArea("editor-stack").sort((a, b) => { - // Careful here. For some reason, sorting by updated_at (or any other property that may always be changing) + // Careful here. For some reason (probably because re-assigning array everytime quickly destroys componentView elements, causing deallocs), + // sorting by updated_at (or any other property that may always be changing) // causes weird problems with ext communication when changing notes or activating/deactivating in quick succession return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index ebc707029..a62a92fe7 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -372,6 +372,8 @@ class ComponentManager { this.handleInstallLocalComponentMessage(component, message); } else if(message.action === "present-conflict-resolution") { this.handlePresentConflictResolutionMessage(component, message); + } else if(message.action === "duplicate-item") { + this.handleDuplicateItemMessage(component, message); } // Notify observers @@ -568,6 +570,24 @@ class ComponentManager { }); } + handleDuplicateItemMessage(component, message) { + var itemParams = message.data.item; + var item = this.modelManager.findItem(itemParams.uuid); + var requiredPermissions = [ + { + name: "stream-items", + content_types: [item.content_type] + } + ]; + + this.runWithPermissions(component, requiredPermissions, () => { + var duplicate = this.modelManager.duplicateItem(item); + this.syncManager.sync(); + + this.replyToMessage(component, message, {item: this.jsonForItem(duplicate, component)}); + }); + } + handleCreateItemsMessage(component, message) { var responseItems = message.data.item ? [message.data.item] : message.data.items; let uniqueContentTypes = _.uniq(responseItems.map((item) => {return item.content_type})); diff --git a/package-lock.json b/package-lock.json index 1fdc31c67..a9571bc93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7819,882 +7819,10 @@ "dev": true }, "sn-stylekit": { - "version": "file:../stylekit", - "dev": true, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true - }, - "argparse": { - "version": "1.0.9", - "bundled": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-find-index": { - "version": "1.0.2", - "bundled": true - }, - "async": { - "version": "1.5.2", - "bundled": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "body-parser": { - "version": "1.14.2", - "bundled": true, - "requires": { - "bytes": "2.2.0", - "content-type": "1.0.4", - "debug": "2.2.0", - "depd": "1.1.1", - "http-errors": "1.3.1", - "iconv-lite": "0.4.13", - "on-finished": "2.3.0", - "qs": "5.2.0", - "raw-body": "2.1.7", - "type-is": "1.6.15" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "bundled": true, - "requires": { - "ms": "0.7.1" - } - }, - "iconv-lite": { - "version": "0.4.13", - "bundled": true - }, - "ms": { - "version": "0.7.1", - "bundled": true - }, - "qs": { - "version": "5.2.0", - "bundled": true - } - } - }, - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true - }, - "bytes": { - "version": "2.2.0", - "bundled": true - }, - "camelcase": { - "version": "2.1.1", - "bundled": true - }, - "camelcase-keys": { - "version": "2.1.0", - "bundled": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "coffee-script": { - "version": "1.10.0", - "bundled": true - }, - "colors": { - "version": "1.1.2", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "content-type": { - "version": "1.0.4", - "bundled": true - }, - "cross-spawn": { - "version": "0.2.9", - "bundled": true, - "requires": { - "lru-cache": "2.7.3" - } - }, - "currently-unhandled": { - "version": "0.4.1", - "bundled": true, - "requires": { - "array-find-index": "1.0.2" - } - }, - "dargs": { - "version": "4.1.0", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "dateformat": { - "version": "1.0.12", - "bundled": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true - }, - "depd": { - "version": "1.1.1", - "bundled": true - }, - "ee-first": { - "version": "1.1.1", - "bundled": true - }, - "error-ex": { - "version": "1.3.1", - "bundled": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "esprima": { - "version": "2.7.3", - "bundled": true - }, - "eventemitter2": { - "version": "0.4.14", - "bundled": true - }, - "exit": { - "version": "0.1.2", - "bundled": true - }, - "faye-websocket": { - "version": "0.10.0", - "bundled": true, - "requires": { - "websocket-driver": "0.7.0" - } - }, - "find-up": { - "version": "1.1.2", - "bundled": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "findup-sync": { - "version": "0.3.0", - "bundled": true, - "requires": { - "glob": "5.0.15" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "bundled": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "gaze": { - "version": "1.1.2", - "bundled": true, - "requires": { - "globule": "1.2.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "bundled": true - }, - "getobject": { - "version": "0.1.0", - "bundled": true - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globule": { - "version": "1.2.0", - "bundled": true, - "requires": { - "glob": "7.1.2", - "lodash": "4.17.4", - "minimatch": "3.0.4" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "grunt": { - "version": "1.0.1", - "bundled": true, - "requires": { - "coffee-script": "1.10.0", - "dateformat": "1.0.12", - "eventemitter2": "0.4.14", - "exit": "0.1.2", - "findup-sync": "0.3.0", - "glob": "7.0.6", - "grunt-cli": "1.2.0", - "grunt-known-options": "1.1.0", - "grunt-legacy-log": "1.0.0", - "grunt-legacy-util": "1.0.0", - "iconv-lite": "0.4.19", - "js-yaml": "3.5.5", - "minimatch": "3.0.4", - "nopt": "3.0.6", - "path-is-absolute": "1.0.1", - "rimraf": "2.2.8" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "bundled": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "grunt-cli": { - "version": "1.2.0", - "bundled": true, - "requires": { - "findup-sync": "0.3.0", - "grunt-known-options": "1.1.0", - "nopt": "3.0.6", - "resolve": "1.1.7" - } - } - } - }, - "grunt-contrib-sass": { - "version": "1.0.0", - "bundled": true, - "requires": { - "async": "0.9.2", - "chalk": "1.1.3", - "cross-spawn": "0.2.9", - "dargs": "4.1.0", - "which": "1.2.14" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "bundled": true - } - } - }, - "grunt-contrib-watch": { - "version": "1.0.0", - "bundled": true, - "requires": { - "async": "1.5.2", - "gaze": "1.1.2", - "lodash": "3.10.1", - "tiny-lr": "0.2.1" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "bundled": true - } - } - }, - "grunt-haml2html": { - "version": "0.3.1", - "bundled": true, - "requires": { - "dargs": "0.1.0" - }, - "dependencies": { - "dargs": { - "version": "0.1.0", - "bundled": true - } - } - }, - "grunt-known-options": { - "version": "1.1.0", - "bundled": true - }, - "grunt-legacy-log": { - "version": "1.0.0", - "bundled": true, - "requires": { - "colors": "1.1.2", - "grunt-legacy-log-utils": "1.0.0", - "hooker": "0.2.3", - "lodash": "3.10.1", - "underscore.string": "3.2.3" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "bundled": true - } - } - }, - "grunt-legacy-log-utils": { - "version": "1.0.0", - "bundled": true, - "requires": { - "chalk": "1.1.3", - "lodash": "4.3.0" - }, - "dependencies": { - "lodash": { - "version": "4.3.0", - "bundled": true - } - } - }, - "grunt-legacy-util": { - "version": "1.0.0", - "bundled": true, - "requires": { - "async": "1.5.2", - "exit": "0.1.2", - "getobject": "0.1.0", - "hooker": "0.2.3", - "lodash": "4.3.0", - "underscore.string": "3.2.3", - "which": "1.2.14" - }, - "dependencies": { - "lodash": { - "version": "4.3.0", - "bundled": true - } - } - }, - "grunt-newer": { - "version": "1.3.0", - "bundled": true, - "requires": { - "async": "1.5.2", - "rimraf": "2.6.2" - }, - "dependencies": { - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "7.1.2" - } - } - } - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "hooker": { - "version": "0.2.3", - "bundled": true - }, - "hosted-git-info": { - "version": "2.5.0", - "bundled": true - }, - "http-errors": { - "version": "1.3.1", - "bundled": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.4.0" - } - }, - "http-parser-js": { - "version": "0.4.9", - "bundled": true - }, - "iconv-lite": { - "version": "0.4.19", - "bundled": true - }, - "indent-string": { - "version": "2.1.0", - "bundled": true, - "requires": { - "repeating": "2.0.1" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-utf8": { - "version": "0.2.1", - "bundled": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true - }, - "js-yaml": { - "version": "3.5.5", - "bundled": true, - "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" - } - }, - "livereload-js": { - "version": "2.2.2", - "bundled": true - }, - "load-json-file": { - "version": "1.1.0", - "bundled": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - } - }, - "lodash": { - "version": "4.17.4", - "bundled": true - }, - "loud-rejection": { - "version": "1.6.0", - "bundled": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, - "lru-cache": { - "version": "2.7.3", - "bundled": true - }, - "map-obj": { - "version": "1.0.1", - "bundled": true - }, - "media-typer": { - "version": "0.3.0", - "bundled": true - }, - "meow": { - "version": "3.7.0", - "bundled": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "mime-db": { - "version": "1.30.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.17", - "bundled": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1.1.1" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "on-finished": { - "version": "2.3.0", - "bundled": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "parse-json": { - "version": "2.2.0", - "bundled": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "parseurl": { - "version": "1.3.2", - "bundled": true - }, - "path-exists": { - "version": "2.1.0", - "bundled": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "path-type": { - "version": "1.1.0", - "bundled": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pify": { - "version": "2.3.0", - "bundled": true - }, - "pinkie": { - "version": "2.0.4", - "bundled": true - }, - "pinkie-promise": { - "version": "2.0.1", - "bundled": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "qs": { - "version": "5.1.0", - "bundled": true - }, - "raw-body": { - "version": "2.1.7", - "bundled": true, - "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.13", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "2.4.0", - "bundled": true - }, - "iconv-lite": { - "version": "0.4.13", - "bundled": true - } - } - }, - "read-pkg": { - "version": "1.1.0", - "bundled": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "bundled": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, - "redent": { - "version": "1.0.0", - "bundled": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, - "repeating": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "resolve": { - "version": "1.1.7", - "bundled": true - }, - "rimraf": { - "version": "2.2.8", - "bundled": true - }, - "semver": { - "version": "5.4.1", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "spdx-correct": { - "version": "1.0.2", - "bundled": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "bundled": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "bundled": true - }, - "sprintf-js": { - "version": "1.0.3", - "bundled": true - }, - "statuses": { - "version": "1.4.0", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "bundled": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-indent": { - "version": "1.0.1", - "bundled": true, - "requires": { - "get-stdin": "4.0.1" - } - }, - "supports-color": { - "version": "2.0.0", - "bundled": true - }, - "tiny-lr": { - "version": "0.2.1", - "bundled": true, - "requires": { - "body-parser": "1.14.2", - "debug": "2.2.0", - "faye-websocket": "0.10.0", - "livereload-js": "2.2.2", - "parseurl": "1.3.2", - "qs": "5.1.0" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "bundled": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "bundled": true - } - } - }, - "trim-newlines": { - "version": "1.0.0", - "bundled": true - }, - "type-is": { - "version": "1.6.15", - "bundled": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.17" - } - }, - "underscore.string": { - "version": "3.2.3", - "bundled": true - }, - "unpipe": { - "version": "1.0.0", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "bundled": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "websocket-driver": { - "version": "0.7.0", - "bundled": true, - "requires": { - "http-parser-js": "0.4.9", - "websocket-extensions": "0.1.2" - } - }, - "websocket-extensions": { - "version": "0.1.2", - "bundled": true - }, - "which": { - "version": "1.2.14", - "bundled": true, - "requires": { - "isexe": "2.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - } - } + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.11.tgz", + "integrity": "sha512-Tp3VEir5VrITfRbe6gJ+I1BaGw9SZ12do7ZPnGiYJoVw28b9BPsCeFUcZnUlrMK3g6Hs1pU23qSHA7CfHJGTNQ==", + "dev": true }, "snake-case": { "version": "2.1.0", @@ -8969,9 +8097,9 @@ "dev": true }, "standard-file-js": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.21.tgz", - "integrity": "sha512-MLic68jA/EPqmNHbI2qrQn3V6/ZgazzM7C4AD6o2mORu3ZrFk64K0FPIrpN4LuA8IJi3sOqOFKsp1/caVw0zrw==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.22.tgz", + "integrity": "sha512-nezAUHLX0K0DVtdofrWv2wuznXD8xPJLC/F/usGqtxvtqWbpH+MG99WtHidOd3D38qlGY7PER1nRbFT0WbA92w==", "dev": true }, "static-extend": { diff --git a/package.json b/package.json index e5c4c0613..6689a40aa 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "file:~/Desktop/sn/dev/stylekit", - "standard-file-js": "0.3.21", + "sn-stylekit": "2.0.11", + "standard-file-js": "0.3.22", "grunt-shell": "^2.1.0" } } From 0ce88bc9293b58f0a9e08dd7aa3fc4927ab46b11 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 16 Dec 2018 15:25:14 -0600 Subject: [PATCH 40/62] desktopManager window blur event --- .../app/services/desktopManager.js | 4 +++ .../app/services/passcodeManager.js | 27 ++++++++++++++----- app/assets/stylesheets/app/_stylekit-sub.scss | 4 +++ .../directives/account-menu.html.haml | 2 +- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/app/services/desktopManager.js b/app/assets/javascripts/app/services/desktopManager.js index d437fa296..bbbb6673c 100644 --- a/app/assets/javascripts/app/services/desktopManager.js +++ b/app/assets/javascripts/app/services/desktopManager.js @@ -79,6 +79,10 @@ class DesktopManager { this.searchHandler = handler; } + desktop_windowLostFocus() { + this.$rootScope.$broadcast("window-lost-focus"); + } + desktop_onComponentInstallationComplete(componentData, error) { console.log("Web|Component Installation/Update Complete", componentData, error); diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index d203f5aba..55948953d 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,9 +1,20 @@ class PasscodeManager { - constructor(authManager, storageManager) { - document.addEventListener('visibilitychange', (e) => { - this.documentVisibilityChanged(document.visibilityState); - }); + constructor($rootScope, authManager, storageManager) { + if(isDesktopApplication()) { + // desktop only + $rootScope.$on("window-lost-focus", () => { + let visible = false; + this.documentVisibilityChanged(visible); + }) + } else { + // tab visibility listender, web only + document.addEventListener('visibilitychange', (e) => { + let visible = document.visibilityState == "visible"; + this.documentVisibilityChanged(visible); + }); + } + this.authManager = authManager; this.storageManager = storageManager; @@ -13,6 +24,7 @@ class PasscodeManager { const MillisecondsPerSecond = 1000; PasscodeManager.AutoLockIntervalNone = 0; + PasscodeManager.AutoLockIntervalImmediate = 1; PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; @@ -26,6 +38,10 @@ class PasscodeManager { value: PasscodeManager.AutoLockIntervalNone, label: "None" }, + { + value: PasscodeManager.AutoLockIntervalImmediate, + label: "Immediately" + }, { value: PasscodeManager.AutoLockIntervalOneMinute, label: "1 Min" @@ -41,8 +57,7 @@ class PasscodeManager { ] } - documentVisibilityChanged(visbility) { - let visible = document.visibilityState == "visible"; + documentVisibilityChanged(visible) { if(!visible) { this.beginAutoLockTimer(); } else { diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index 77a666bc0..796007d19 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -53,3 +53,7 @@ opacity: 1.0 } } + +button.sk-button { + border: none; +} diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 3bf603c4d..698d11105 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -148,7 +148,7 @@ .sk-horizontal-group .sk-h4.sk-bold Autolock %a.sk-a.info{"ng-repeat" => "option in passcodeAutoLockOptions", "ng-click" => "selectAutoLockInterval(option.value)", - "ng-class" => "{'info boxed' : option.value == selectedAutoLockInterval}"} + "ng-class" => "{'boxed' : option.value == selectedAutoLockInterval}"} {{option.label}} .sk-p The autolock timer begins when the window or tab loses focus. From 2130cecacedbbe29826565ce17b1099886ea95ef Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 16 Dec 2018 16:03:22 -0600 Subject: [PATCH 41/62] Panel collapse fixes --- app/assets/javascripts/app/controllers/notes.js | 4 ++-- app/assets/javascripts/app/controllers/tags.js | 4 ++-- .../javascripts/app/directives/views/panelResizer.js | 9 ++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 194771af9..de50ed575 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -66,8 +66,8 @@ angular.module('app') let width = authManager.getUserPrefValue("notesPanelWidth"); if(width) { this.panelController.setWidth(width); - if(this.panelController.isCollapsed) { - $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: this.panelController.isCollapsed}) + if(this.panelController.isCollapsed()) { + $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: this.panelController.isCollapsed()}) } } } diff --git a/app/assets/javascripts/app/controllers/tags.js b/app/assets/javascripts/app/controllers/tags.js index dc808b43f..4d6daa3a7 100644 --- a/app/assets/javascripts/app/controllers/tags.js +++ b/app/assets/javascripts/app/controllers/tags.js @@ -47,8 +47,8 @@ angular.module('app') let width = authManager.getUserPrefValue("tagsPanelWidth"); if(width) { this.panelController.setWidth(width); - if(this.panelController.isCollapsed) { - $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: this.panelController.isCollapsed}) + if(this.panelController.isCollapsed()) { + $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: this.panelController.isCollapsed()}) } } } diff --git a/app/assets/javascripts/app/directives/views/panelResizer.js b/app/assets/javascripts/app/directives/views/panelResizer.js index 492c2084f..0be60fffa 100644 --- a/app/assets/javascripts/app/directives/views/panelResizer.js +++ b/app/assets/javascripts/app/directives/views/panelResizer.js @@ -56,16 +56,19 @@ class PanelResizer { // Handle Double Click Event var widthBeforeLastDblClick = 0; resizerColumn.ondblclick = () => { - var collapsed = $scope.isCollapsed(); $timeout(() => { - if(collapsed) { + var preClickCollapseState = $scope.isCollapsed(); + if(preClickCollapseState) { $scope.setWidth(widthBeforeLastDblClick || $scope.defaultWidth); } else { widthBeforeLastDblClick = lastWidth; $scope.setWidth(minWidth); } + $scope.finishSettingWidth(); - $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth(), collapsed); + + var newCollapseState = !preClickCollapseState; + $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth(), newCollapseState); }) } From 363fb7bd7f59712fb01cd424ac4f46f89491995b Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 16 Dec 2018 16:38:19 -0600 Subject: [PATCH 42/62] Resave session history on passcode change --- .../app/directives/views/accountMenu.js | 3 +- .../directives/views/revisionPreviewModal.js | 4 +- .../app/services/passcodeManager.js | 156 ++++++++++-------- .../app/services/sessionHistory.js | 7 + 4 files changed, 100 insertions(+), 70 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index f163892ce..6407cc2f3 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -440,6 +440,8 @@ class AccountMenu { fn(passcode, () => { $timeout(() => { + $scope.formData.passcode = null; + $scope.formData.confirmPasscode = null; $scope.formData.showPasscodeForm = false; var offline = authManager.offline(); @@ -457,7 +459,6 @@ class AccountMenu { $timeout(() => { $scope.formData.changingPasscode = true; $scope.addPasscodeClicked(); - $scope.formData.changingPasscode = false; }) } diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js index 03fde5113..534189f8c 100644 --- a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -22,7 +22,9 @@ class RevisionPreviewModal { } $scope.$on("$destroy", function() { - componentManager.deregisterHandler($scope.identifier); + if($scope.identifier) { + componentManager.deregisterHandler($scope.identifier); + } }); $scope.note = new SFItem({content: $scope.content, content_type: "Note"}); diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 55948953d..765ac7345 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,83 +1,20 @@ class PasscodeManager { constructor($rootScope, authManager, storageManager) { - if(isDesktopApplication()) { - // desktop only - $rootScope.$on("window-lost-focus", () => { - let visible = false; - this.documentVisibilityChanged(visible); - }) - } else { - // tab visibility listender, web only - document.addEventListener('visibilitychange', (e) => { - let visible = document.visibilityState == "visible"; - this.documentVisibilityChanged(visible); - }); - } - - this.authManager = authManager; this.storageManager = storageManager; + this.$rootScope = $rootScope; this._hasPasscode = this.storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; this._locked = this._hasPasscode; - const MillisecondsPerSecond = 1000; - PasscodeManager.AutoLockIntervalNone = 0; - PasscodeManager.AutoLockIntervalImmediate = 1; - PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; - PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; - PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; + this.passcodeChangeObservers = []; - PasscodeManager.AutoLockIntervalKey = "AutoLockIntervalKey"; + this.configureAutoLock(); } - getAutoLockIntervalOptions() { - return [ - { - value: PasscodeManager.AutoLockIntervalNone, - label: "None" - }, - { - value: PasscodeManager.AutoLockIntervalImmediate, - label: "Immediately" - }, - { - value: PasscodeManager.AutoLockIntervalOneMinute, - label: "1 Min" - }, - { - value: PasscodeManager.AutoLockIntervalFiveMinutes, - label: "5 Min" - }, - { - value: PasscodeManager.AutoLockIntervalOneHour, - label: "1 Hr" - } - ] - } - - documentVisibilityChanged(visible) { - if(!visible) { - this.beginAutoLockTimer(); - } else { - this.cancelAutoLockTimer(); - } - } - - async beginAutoLockTimer() { - var interval = await this.getAutoLockInterval(); - if(interval == PasscodeManager.AutoLockIntervalNone) { - return; - } - - this.lockTimeout = setTimeout(() => { - this.lockApplication(); - }, interval); - } - - cancelAutoLockTimer() { - clearTimeout(this.lockTimeout); + addPasscodeChangeObserver(callback) { + this.passcodeChangeObservers.push(callback); } lockApplication() { @@ -171,6 +108,8 @@ class PasscodeManager { // After it's cleared, it's safe to write to it this.storageManager.setItem("offlineParams", JSON.stringify(authParams), StorageManager.Fixed); callback(true); + + this.notifyObserversOfPasscodeChange(); }); } @@ -183,6 +122,14 @@ class PasscodeManager { this.storageManager.removeItem("offlineParams", StorageManager.Fixed); this._keys = null; this._hasPasscode = false; + + this.notifyObserversOfPasscodeChange(); + } + + notifyObserversOfPasscodeChange() { + for(var observer of this.passcodeChangeObservers) { + observer(); + } } encryptLocalStorage(keys, authParams) { @@ -196,6 +143,79 @@ class PasscodeManager { this.storageManager.setKeys(keys, authParams); return this.storageManager.decryptStorage(); } + + configureAutoLock() { + if(isDesktopApplication()) { + // desktop only + this.$rootScope.$on("window-lost-focus", () => { + let visible = false; + this.documentVisibilityChanged(visible); + }) + } else { + // tab visibility listender, web only + document.addEventListener('visibilitychange', (e) => { + let visible = document.visibilityState == "visible"; + this.documentVisibilityChanged(visible); + }); + } + + const MillisecondsPerSecond = 1000; + PasscodeManager.AutoLockIntervalNone = 0; + PasscodeManager.AutoLockIntervalImmediate = 1; + PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; + + PasscodeManager.AutoLockIntervalKey = "AutoLockIntervalKey"; + } + + getAutoLockIntervalOptions() { + return [ + { + value: PasscodeManager.AutoLockIntervalNone, + label: "None" + }, + { + value: PasscodeManager.AutoLockIntervalImmediate, + label: "Immediately" + }, + { + value: PasscodeManager.AutoLockIntervalOneMinute, + label: "1 Min" + }, + { + value: PasscodeManager.AutoLockIntervalFiveMinutes, + label: "5 Min" + }, + { + value: PasscodeManager.AutoLockIntervalOneHour, + label: "1 Hr" + } + ] + } + + documentVisibilityChanged(visible) { + if(!visible) { + this.beginAutoLockTimer(); + } else { + this.cancelAutoLockTimer(); + } + } + + async beginAutoLockTimer() { + var interval = await this.getAutoLockInterval(); + if(interval == PasscodeManager.AutoLockIntervalNone) { + return; + } + + this.lockTimeout = setTimeout(() => { + this.lockApplication(); + }, interval); + } + + cancelAutoLockTimer() { + clearTimeout(this.lockTimeout); + } } angular.module('app').service('passcodeManager', PasscodeManager); diff --git a/app/assets/javascripts/app/services/sessionHistory.js b/app/assets/javascripts/app/services/sessionHistory.js index d64dec37f..7b5ac9f04 100644 --- a/app/assets/javascripts/app/services/sessionHistory.js +++ b/app/assets/javascripts/app/services/sessionHistory.js @@ -6,10 +6,17 @@ class SessionHistory extends SFSessionHistoryManager { "Note" : NoteHistoryEntry } + // Session History can be encrypted with passcode keys. If it changes, we need to resave session + // history with the new keys. + passcodeManager.addPasscodeChangeObserver(() => { + this.saveToDisk(); + }) + var keyRequestHandler = async () => { let offline = authManager.offline(); let auth_params = offline ? passcodeManager.passcodeAuthParams() : await authManager.getAuthParams(); let keys = offline ? passcodeManager.keys() : await authManager.keys(); + return { keys: keys, offline: offline, From 2f20e92af1d248c31e222957b77f6b33d3b48204 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 09:52:25 -0600 Subject: [PATCH 43/62] Fixes issue with components in revision preview not iframe loading, misc css/html updates --- .../javascripts/app/controllers/editor.js | 4 ++- .../javascripts/app/controllers/home.js | 6 ++-- .../app/directives/views/componentView.js | 14 +++++--- .../directives/views/revisionPreviewModal.js | 35 +++++++++--------- .../app/services/componentManager.js | 36 ++++++++++++------- app/assets/stylesheets/app/_editor.scss | 4 +-- app/assets/stylesheets/app/_main.scss | 7 ++-- app/assets/stylesheets/app/_notes.scss | 2 ++ app/assets/stylesheets/app/_tags.scss | 5 ++- .../directives/input-modal.html.haml | 6 ++-- .../privileges-auth-modal.html.haml | 2 +- app/assets/templates/tags.html.haml | 3 +- 12 files changed, 73 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 61284ea0f..9aa1c96ae 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -613,7 +613,9 @@ angular.module('app') this.reloadComponentContext(); } }, contextRequestHandler: (component) => { - return this.note; + if(component == this.selectedEditor || this.componentStack.includes(component)) { + return this.note; + } }, focusHandler: (component, focused) => { if(component.isEditor() && focused) { this.closeAllMenus(); diff --git a/app/assets/javascripts/app/controllers/home.js b/app/assets/javascripts/app/controllers/home.js index 2581f72cc..0c155635f 100644 --- a/app/assets/javascripts/app/controllers/home.js +++ b/app/assets/javascripts/app/controllers/home.js @@ -208,7 +208,7 @@ angular.module('app') modelManager.setItemToBeDeleted(tag); syncManager.sync().then(() => { // force scope tags to update on sub directives - $scope.safeApply(); + $rootScope.safeApply(); }); } } @@ -230,7 +230,7 @@ angular.module('app') Shared Callbacks */ - $scope.safeApply = function(fn) { + $rootScope.safeApply = function(fn) { var phase = this.$root.$$phase; if(phase == '$apply' || phase == '$digest') this.$eval(fn); @@ -262,7 +262,7 @@ angular.module('app') // when deleting items while ofline, we need to explictly tell angular to refresh UI setTimeout(function () { $rootScope.notifyDelete(); - $scope.safeApply(); + $rootScope.safeApply(); }, 50); } else { $timeout(() => { diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index d73dc8476..03a06b6e9 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -94,7 +94,6 @@ class ComponentView { } }, 3500); iframe.onload = (event) => { - // console.log("iframe loaded for component", component.name, "cancelling load timeout", $scope.loadTimeout); $timeout.cancel($scope.loadTimeout); componentManager.registerComponentWindow(component, iframe.contentWindow); @@ -141,7 +140,11 @@ class ComponentView { $scope.reloadComponent = function() { console.log("Reloading component", $scope.component); - componentManager.reloadComponent($scope.component); + // force iFrame to deinit, allows new one to be created + $scope.componentValid = false; + componentManager.reloadComponent($scope.component).then(() => { + $scope.reloadStatus(); + }); } $scope.reloadStatus = function(doManualReload = true) { @@ -160,7 +163,11 @@ class ComponentView { $scope.expired = component.valid_until && component.valid_until <= new Date(); - component.readonly = $scope.expired; + // Here we choose our own readonly state based on custom logic. However, if a parent + // wants to implement their own readonly logic, they can lock it. + if(!component.lockReadonly) { + component.readonly = $scope.expired; + } $scope.componentValid = !offlineRestricted && !urlError; @@ -234,7 +241,6 @@ class ComponentView { } $scope.$on("$destroy", function() { - // console.log("Deregistering handler", $scope.identifier, $scope.component.name); $scope.destroy(); }); } diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js index 534189f8c..70891f354 100644 --- a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -13,7 +13,7 @@ class RevisionPreviewModal { $scope.el = el; } - controller($scope, modelManager, syncManager, componentManager) { + controller($scope, modelManager, syncManager, componentManager, $timeout) { 'ngInject'; $scope.dismiss = function() { @@ -31,29 +31,32 @@ class RevisionPreviewModal { // Set UUID to editoForNote can find proper editor, // but then generate new uuid for note as not to save changes to original, if editor makes changes. $scope.note.uuid = $scope.uuid; - let editor = componentManager.editorForNote($scope.note); + let editorForNote = componentManager.editorForNote($scope.note); $scope.note.uuid = SFJS.crypto.generateUUIDSync(); - if(editor) { + if(editorForNote) { // Create temporary copy, as a lot of componentManager is uuid based, // so might interfere with active editor. Be sure to copy only the content, as the // top level editor object has non-copyable properties like .window, which cannot be transfered - $scope.editor = new SNComponent({content: editor.content}); - $scope.editor.readonly = true; - $scope.identifier = $scope.editor.uuid; + let editorCopy = new SNComponent({content: editorForNote.content}); + editorCopy.readonly = true; + editorCopy.lockReadonly = true; + $scope.identifier = editorCopy.uuid; componentManager.registerHandler({identifier: $scope.identifier, areas: ["editor-editor"], - contextRequestHandler: (component) => { - if(component == $scope.editor) { - return $scope.note; + contextRequestHandler: (component) => { + if(component == $scope.editor) { + return $scope.note; + } + }, + componentForSessionKeyHandler: (key) => { + if(key == $scope.editor.sessionKey) { + return $scope.editor; + } } - }, - componentForSessionKeyHandler: (key) => { - if(key == $scope.editor.sessionKey) { - return $scope.editor; - } - } - }); + }); + + $scope.editor = editorCopy; } diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index a62a92fe7..045ceb93a 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -299,6 +299,9 @@ class ComponentManager { for(let handler of this.handlers) { if(handler.componentForSessionKeyHandler) { component = handler.componentForSessionKeyHandler(key); + if(component) { + break; + } } } } @@ -881,25 +884,29 @@ class ComponentManager { } /* Performs func in timeout, but syncronously, if used `await waitTimeout` */ - async waitTimeout(func) { - return new Promise((resolve, reject) => { - this.timeout(() => { - func(); - resolve(); - }); - }) - } + // No longer used. See comment in activateComponent. + // async waitTimeout(func) { + // return new Promise((resolve, reject) => { + // this.timeout(() => { + // func(); + // resolve(); + // }); + // }) + // } async activateComponent(component, dontSync = false) { var didChange = component.active != true; component.active = true; - for(var handler of this.handlers) { + for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { // We want to run the handler in a $timeout so the UI updates, but we also don't want it to run asyncronously // so that the steps below this one are run before the handler. So we run in a waitTimeout. - await this.waitTimeout(() => { + // Update 12/18: We were using this.waitTimeout previously, however, that caused the iframe.onload callback to never be called + // for some reason for iframes on desktop inside the revision-preview-modal. So we'll use safeApply instead. I'm not quite sure + // where the original "so the UI updates" comment applies to, but we'll have to keep an eye out to see if this causes problems somewhere else. + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -926,7 +933,8 @@ class ComponentManager { for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -960,7 +968,8 @@ class ComponentManager { for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -986,7 +995,8 @@ class ComponentManager { component.active = true; for(var handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 66ffa9678..bdf91317f 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -29,7 +29,7 @@ $heading-height: 75px; overflow: visible; > .title { - font-size: 18px; + font-size: var(--sn-stylekit-font-size-h1); font-weight: bold; padding-top: 0px; width: 100%; @@ -58,7 +58,7 @@ $heading-height: 75px; position: absolute; right: 20px; - font-size: 12px; + font-size: var(--sn-stylekit-font-size-h5); text-transform: none; font-weight: normal; margin-top: 4px; diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index 3209ae1d0..514b8843a 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -22,7 +22,7 @@ body { -webkit-font-smoothing: antialiased; min-height: 100%; height: 100%; - font-size: 14px; + font-size: var(--sn-stylekit-base-font-size); margin: 0; color: var(--sn-stylekit-foreground-color); background-color: var(--sn-stylekit-background-color); @@ -172,7 +172,6 @@ $footer-height: 32px; padding-bottom: 0px; height: 100%; max-height: calc(100vh - #{$footer-height}); - font-size: 17px; position: relative; overflow: hidden; @@ -190,7 +189,6 @@ $footer-height: 32px; .section-title-bar { font-weight: bold; - font-size: 14px; .padded { padding: 0 14px; @@ -200,7 +198,8 @@ $footer-height: 32px; display: flex; justify-content: space-between; align-items: center; - overflow: hidden; + // This was causing problems with tags + button cutting off on right when the panel is a certain size + // overflow: hidden; > .title { white-space: nowrap; diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index 06adfc630..5e6a549cc 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -2,6 +2,8 @@ border-left: 1px solid var(--sn-stylekit-border-color); border-right: 1px solid var(--sn-stylekit-border-color); + font-size: var(--sn-stylekit-font-size-h2); + width: 350px; flex-grow: 0; user-select: none; diff --git a/app/assets/stylesheets/app/_tags.scss b/app/assets/stylesheets/app/_tags.scss index c23d15108..8049e4b88 100644 --- a/app/assets/stylesheets/app/_tags.scss +++ b/app/assets/stylesheets/app/_tags.scss @@ -13,8 +13,8 @@ #tags-title-bar { color: var(--sn-stylekit-secondary-foreground-color); - padding-top: 14px; - padding-bottom: 16px; + padding-top: 15px; + padding-bottom: 8px; padding-left: 12px; padding-right: 12px; font-size: 12px; @@ -43,7 +43,6 @@ cursor: pointer; transition: height .1s ease-in-out; position: relative; - font-size: 14px; > .info { height: 20px; diff --git a/app/assets/templates/directives/input-modal.html.haml b/app/assets/templates/directives/input-modal.html.haml index 716e7a4eb..66d36f10e 100644 --- a/app/assets/templates/directives/input-modal.html.haml +++ b/app/assets/templates/directives/input-modal.html.haml @@ -5,15 +5,15 @@ .sn-component .sk-panel .sk-panel-header - %h1.sk-panel-header-title {{title}} + .sk-h1.sk-panel-header-title {{title}} %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close .sk-panel-content .sk-panel-section - %p.sk-panel-row {{message}} + .sk-p.sk-panel-row {{message}} .sk-panel-row .sk-panel-column.stretch %form{"ng-submit" => "submit()"} - %input.sk-input{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input.contrast{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} .sk-panel-footer %a.sk-a.info.right{"ng-click" => "submit()"} diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index c48f6a9d2..95d41c9a5 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -21,7 +21,7 @@ .sk-horizontal-group .sk-p.sk-bold Remember For %a.sk-a.info{"ng-repeat" => "option in sessionLengthOptions", "ng-click" => "selectSessionLength(option.value)", - "ng-class" => "{'info boxed' : option.value == selectedSessionLength}"} + "ng-class" => "{'boxed' : option.value == selectedSessionLength}"} {{option.label}} .sk-panel-footer.extra-padding diff --git a/app/assets/templates/tags.html.haml b/app/assets/templates/tags.html.haml index 1df7a327f..0af5c93b6 100644 --- a/app/assets/templates/tags.html.haml +++ b/app/assets/templates/tags.html.haml @@ -6,7 +6,8 @@ #tags-content.content{"ng-if" => "!(ctrl.component && ctrl.component.active)"} #tags-title-bar.section-title-bar .section-title-bar-header - .title Tags + .sk-h3.title + %span.sk-bold Tags .sk-button.sk-secondary-contrast.wide{"ng-click" => "ctrl.clickedAddNewTag()", "title" => "Create a new tag"} .sk-label + From d3f97e7bae61c90c53b4658249d293c84df5eb76 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 17:57:08 -0600 Subject: [PATCH 44/62] Cached themes updates --- .../javascripts/app/services/themeManager.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/app/services/themeManager.js b/app/assets/javascripts/app/services/themeManager.js index c35a7d021..84921e12e 100644 --- a/app/assets/javascripts/app/services/themeManager.js +++ b/app/assets/javascripts/app/services/themeManager.js @@ -1,6 +1,6 @@ class ThemeManager { - constructor(componentManager, desktopManager, storageManager) { + constructor(componentManager, desktopManager, storageManager, passcodeManager) { this.componentManager = componentManager; this.storageManager = storageManager; this.desktopManager = desktopManager; @@ -9,7 +9,19 @@ class ThemeManager { ThemeManager.CachedThemesKey = "cachedThemes"; this.registerObservers(); - this.activateCachedThemes(); + + // When a passcode is added, all local storage will be encrypted (it doesn't know what was + // originally saved as Fixed or FixedEncrypted). We want to rewrite cached themes here to Fixed + // so that it's readable without authentication. + passcodeManager.addPasscodeChangeObserver(() => { + this.cacheThemes(); + }) + + // The desktop application won't have its applicationDataPath until the angular document is ready, + // so it wont be able to resolve local theme urls until thats ready + angular.element(document).ready(() => { + this.activateCachedThemes(); + }); } activateCachedThemes() { From 74fb3b6ca5bad73578167e90f94b09054d3e103f Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 18:08:54 -0600 Subject: [PATCH 45/62] Show privileges manager if protection not set up --- .../javascripts/app/controllers/editor.js | 7 +++++++ .../app/services/privilegesManager.js | 14 ++++++++----- .../privileges-management-modal.html.haml | 21 ++++++++++--------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 9aa1c96ae..98620e836 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -415,6 +415,13 @@ angular.module('app') this.toggleProtectNote = function() { this.note.content.protected = !this.note.content.protected; this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); + + // Show privilegesManager if Protection is not yet set up + privilegesManager.actionHasPrivilegesConfigured(PrivilegesManager.ActionViewProtectedNotes).then((configured) => { + if(!configured) { + privilegesManager.presentPrivilegesManagementModal(); + } + }) } this.toggleNotePreview = function() { diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index f79177784..a1c83f077 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -30,12 +30,12 @@ class PrivilegesManager { PrivilegesManager.SessionLengthOneWeek = 604800; this.availableActions = [ - PrivilegesManager.ActionManagePrivileges, - PrivilegesManager.ActionManageExtensions, - PrivilegesManager.ActionManageBackups, - PrivilegesManager.ActionManagePasscode, PrivilegesManager.ActionViewProtectedNotes, - PrivilegesManager.ActionDeleteNote + PrivilegesManager.ActionDeleteNote, + PrivilegesManager.ActionManagePasscode, + PrivilegesManager.ActionManageBackups, + PrivilegesManager.ActionManageExtensions, + PrivilegesManager.ActionManagePrivileges, ] this.availableCredentials = [ @@ -249,6 +249,10 @@ class PrivilegesManager { } } + async actionHasPrivilegesConfigured(action) { + return (await this.netCredentialsForAction(action)).length > 0; + } + async actionRequiresPrivilege(action) { let expiresAt = await this.getSessionExpirey(); if(expiresAt > new Date()) { diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 95e897156..fb9654a05 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -27,14 +27,15 @@ .sk-p.sk-panel-row You will not be asked to authenticate until {{sessionExpirey}}. %a.sk-a.sk-panel-row.info{"ng-click" => "clearSession()"} Clear Session .sk-panel-footer - .sk-h2 About Privileges + .sk-h2.sk-bold About Privileges .sk-panel-section.no-bottom-pad - .text-content - %p - Privileges represent interface level authentication for accessing certain items and features. - Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. - Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. - %p - Privileges sync across your other devices (not including mobile); however, note that if you require - a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode - requirement will be ignored on that device. + .sk-panel-row + .text-content + .sk-p + Privileges represent interface level authentication for accessing certain items and features. + Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. + Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. + %p.sk-p + Privileges sync across your other devices (not including mobile); however, note that if you require + a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode + requirement will be ignored on that device. From 302420385a1fee024ac7e75606a5663f5e377954 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 18:57:40 -0600 Subject: [PATCH 46/62] component-view position fixes for note-tags-component-container --- app/assets/stylesheets/app/_editor.scss | 7 ++++++- app/assets/stylesheets/app/_modals.scss | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index bdf91317f..47d3f2c66 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -58,7 +58,7 @@ $heading-height: 75px; position: absolute; right: 20px; - font-size: var(--sn-stylekit-font-size-h5); + font-size: calc(var(--sn-stylekit-base-font-size) - 2px); text-transform: none; font-weight: normal; margin-top: 4px; @@ -80,6 +80,11 @@ $heading-height: 75px; height: 50px; overflow: auto; // Required for expired sub to not overflow + .component-view { + // see comment under main .component-view css defintion + position: inherit; + } + iframe { height: 50px; width: 100%; diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 1bd3141d9..e277f2dcc 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -168,6 +168,9 @@ flex-grow: 1; display: flex; flex-direction: column; + + // required so that .loading-overlay absolute works properly wrt to modal components. However, seems to break #note-tags-component-container. + // I couldn't find any solution to this other than to customize .component-view position back to inherit for note-tags-component-container. position: relative; // not sure why we need this. Removed because it creates unncessary scroll bars. Tested on folders extension, creates horizontal scrollbar at bottom on windows From 6a00353eefff81eab5bbc9eb4e860638f9220c5d Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 19:09:41 -0600 Subject: [PATCH 47/62] UI updates --- app/assets/templates/directives/account-menu.html.haml | 6 +++--- app/assets/templates/directives/password-wizard.html.haml | 6 +++--- app/assets/templates/editor.html.haml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 698d11105..0979db77c 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -25,6 +25,9 @@ %input.sk-input.contrast{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} %input.sk-input.contrast{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password', 'sn-enter' => 'submitAuthForm()'} %input.sk-input.contrast{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf', 'sn-enter' => 'submitAuthForm()'} + .sk-panel-row + %a.sk-panel-row.sk-bold{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} + Advanced Options .sk-notification.unpadded.contrast.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} .sk-panel-column.stretch @@ -60,9 +63,6 @@ .sk-panel-row %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} Merge local data ({{notesAndTagsCount()}} notes and tags) - .sk-panel-row - %a.sk-panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} - Advanced Options .sk-panel-section{"ng-if" => "formData.mfa"} %form.sk-panel-form{"ng-submit" => "submitMfaForm()"} diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index 336ed3de1..b51f3cff3 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -16,10 +16,10 @@ If you have many items, syncing your data can take several minutes. %p.sk-p.sk-panel-row You must keep the application window open during this process. %div{"ng-if" => "securityUpdate"} - %p.sk-p + %p.sk-p.sk-panel-row A new update is available for your account. Updates address improvements and enhancements to our security specification. This process will guide you through the update, and perform the steps necessary with your supervision. - %p.sk-p + %p.sk-p.sk-panel-row For more information about security updates, please visit %a.sk-a.info{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. @@ -90,7 +90,7 @@ %div{"ng-if" => "changePassword"} %p.sk-p.sk-panel-row.info-i Your password has been successfully changed. %div{"ng-if" => "securityUpdate"} - %p.sk-p.sk-panel-row + %p.sk-p.sk-panel-row.info-i The security update has been successfully applied to your account. %p.sk-p.sk-panel-row Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 91b3678ec..25386c77a 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -81,7 +81,7 @@ .section{"ng-if" => "ctrl.note.errorDecrypting"} %p.medium-padding{"style" => "padding-top: 0 !important;"} There was an error decrypting this item. Ensure you are running the latest version of this app, then sign out and sign back in to try again. - #editor-pane-component-stack + #editor-pane-component-stack{"ng-show" => "ctrl.note"} #component-stack-menu-bar.sk-app-bar.no-edges{"ng-if" => "ctrl.componentStack.length"} .left .sk-app-bar-item{"ng-repeat" => "component in ctrl.componentStack", "ng-click" => "ctrl.toggleStackComponentForCurrentItem(component)"} From 59531bc963d143aeb323fcddd089aaa1b51fdd05 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 17 Dec 2018 19:28:48 -0600 Subject: [PATCH 48/62] Desktop manager gained focus event --- app/assets/javascripts/app/services/desktopManager.js | 6 ++++++ public/extensions/extensions-manager | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/services/desktopManager.js b/app/assets/javascripts/app/services/desktopManager.js index bbbb6673c..7478b432b 100644 --- a/app/assets/javascripts/app/services/desktopManager.js +++ b/app/assets/javascripts/app/services/desktopManager.js @@ -79,6 +79,12 @@ class DesktopManager { this.searchHandler = handler; } + desktop_windowGainedFocus() { + if(!this.passcodeManager.isLocked()) { + this.syncManager.sync(); + } + } + desktop_windowLostFocus() { this.$rootScope.$broadcast("window-lost-focus"); } diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index 883b90515..7da85fbfb 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit 883b90515c96923617cb08a2007d1a5bbfdc9c67 +Subproject commit 7da85fbfb130dc913ed8aa6db495e92f988a66fd From c0bbe4f3bade2aa22b24bdeb5d08b3c0d6d1d703 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 19 Dec 2018 15:36:30 -0600 Subject: [PATCH 49/62] Remove redundant scrollbar css --- app/assets/stylesheets/app/_scrollbars.scss | 31 ------------------- app/assets/stylesheets/main.css.scss | 3 +- .../directives/account-menu.html.haml | 2 +- 3 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 app/assets/stylesheets/app/_scrollbars.scss diff --git a/app/assets/stylesheets/app/_scrollbars.scss b/app/assets/stylesheets/app/_scrollbars.scss deleted file mode 100644 index 415aa0ac9..000000000 --- a/app/assets/stylesheets/app/_scrollbars.scss +++ /dev/null @@ -1,31 +0,0 @@ -.windows-web, .windows-desktop, .linux-web, .linux-desktop { - - $thumb-color: #dfdfdf; - $track-border-color: #E7E7E7; - $thumb-width: 4px; - - ::-webkit-scrollbar { - width: 17px; - height: 18px; - border-left: 0.5px solid $track-border-color; - } - - ::-webkit-scrollbar-thumb { - height: 6px; - border: $thumb-width solid rgba(0, 0, 0, 0); - background-clip: padding-box; - -webkit-border-radius: 10px; - background-color: $thumb-color; - -webkit-box-shadow: inset -1px -1px 0px rgba(0, 0, 0, 0.05), inset 1px 1px 0px rgba(0, 0, 0, 0.05); - } - - ::-webkit-scrollbar-button { - width: 0; - height: 0; - display: none; - } - - ::-webkit-scrollbar-corner { - background-color: transparent; - } -} diff --git a/app/assets/stylesheets/main.css.scss b/app/assets/stylesheets/main.css.scss index 77c84f236..9e28dc002 100644 --- a/app/assets/stylesheets/main.css.scss +++ b/app/assets/stylesheets/main.css.scss @@ -1,6 +1,5 @@ @import "app/main"; @import "app/ui"; -@import "app/scrollbars"; @import "app/footer"; @import "app/tags"; @import "app/notes"; @@ -9,4 +8,4 @@ @import "app/modals"; @import "app/lock-screen"; @import "app/stylekit-sub"; -@import "app/ionicons"; \ No newline at end of file +@import "app/ionicons"; diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 0979db77c..6a6f21386 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -2,7 +2,7 @@ .sk-panel#account-panel .sk-panel-header .sk-panel-header-title Account - %a.sk-a.infoclose-button{"ng-click" => "close()"} Close + %a.sk-a.info.close-button{"ng-click" => "close()"} Close .sk-panel-content .sk-panel-section.sk-panel-hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} .sk-panel-row From 513a5e32c93ca00058c2e576f49ea9686c16c3b7 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 19 Dec 2018 15:58:43 -0600 Subject: [PATCH 50/62] Remove default input css rule --- app/assets/stylesheets/app/_stylekit-sub.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index 796007d19..3405cedaa 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -35,11 +35,6 @@ } } - input { - min-height: 39px; - } - - .sk-button-group.stretch { .sk-button:not(.featured) { // Default buttons that are not featured and stretched should have larger vertical padding From ff15c1900dc2a37a068c5c20d5e6bef4964cb97d Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 19 Dec 2018 20:20:05 -0600 Subject: [PATCH 51/62] Fix notes add button class --- app/assets/templates/notes.html.haml | 2 +- public/extensions/batch-manager | 2 +- public/extensions/extensions-manager | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index d43a50974..475d35711 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -4,7 +4,7 @@ .padded .section-title-bar-header .title {{ctrl.panelTitle()}} - .sk-button.sk-secondary.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + .sk-button.contrast.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} .sk-label + .filter-section{"role" => "search"} %input.filter-bar#search-bar.mousetrap{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", diff --git a/public/extensions/batch-manager b/public/extensions/batch-manager index 04a930d26..db7b790e3 160000 --- a/public/extensions/batch-manager +++ b/public/extensions/batch-manager @@ -1 +1 @@ -Subproject commit 04a930d26505cfa05a4bf6472fe2e7fdea26d940 +Subproject commit db7b790e3302f4c3ca37cd9502d842e4ae936500 diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index 7da85fbfb..50a53c646 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit 7da85fbfb130dc913ed8aa6db495e92f988a66fd +Subproject commit 50a53c6469db7a92ddfe2562da09c8cacd7c9901 From f7e3ff2debdf5d1360adaaabeb183b0db81698d2 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 19 Dec 2018 20:26:09 -0600 Subject: [PATCH 52/62] Component stack, require to be explicitely enabled for item --- app/assets/javascripts/app/controllers/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 98620e836..247107ab0 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -706,7 +706,7 @@ angular.module('app') if(this.note) { for(var component of this.componentStack) { if(component.active) { - component.hidden = component.isExplicitlyDisabledForItem(this.note); + component.hidden = !component.isExplicitlyEnabledForItem(this.note); } } } From cb6f44da3ac708c19cacd16429f384a13cb89f59 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 19 Dec 2018 20:36:03 -0600 Subject: [PATCH 53/62] 3.0.0-beta1 --- package-lock.json | 8 ++++---- package.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9571bc93..ee6414031 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.4.0-beta1", + "version": "3.0.0-beta1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -7819,9 +7819,9 @@ "dev": true }, "sn-stylekit": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.11.tgz", - "integrity": "sha512-Tp3VEir5VrITfRbe6gJ+I1BaGw9SZ12do7ZPnGiYJoVw28b9BPsCeFUcZnUlrMK3g6Hs1pU23qSHA7CfHJGTNQ==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.13.tgz", + "integrity": "sha512-rGDc2cc0/r84lQn/HJOw6GvJz5VonSK2UVdLTS9TFo+wwbAtRnww8aj7VILgNneUAnqwdCKdY5O/Fk3rN0Hw7g==", "dev": true }, "snake-case": { diff --git a/package.json b/package.json index 6689a40aa..c75637f8b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.4.0-beta1", + "version": "3.0.0-beta1", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -44,7 +44,7 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "2.0.11", + "sn-stylekit": "2.0.13", "standard-file-js": "0.3.22", "grunt-shell": "^2.1.0" } From 711fdc061c14e6399018baa03f39eee0e16019ad Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 20 Dec 2018 10:17:34 -0600 Subject: [PATCH 54/62] Wait for initial data load before resolving singletons --- app/assets/javascripts/app/services/singletonManager.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/javascripts/app/services/singletonManager.js b/app/assets/javascripts/app/services/singletonManager.js index ddee5b64a..6c4ce588b 100644 --- a/app/assets/javascripts/app/services/singletonManager.js +++ b/app/assets/javascripts/app/services/singletonManager.js @@ -24,6 +24,7 @@ class SingletonManager { $rootScope.$on("initial-data-loaded", (event, data) => { this.resolveSingletons(modelManager.allItems, null, true); + this.initialDataLoaded = true; }) /* @@ -41,6 +42,11 @@ class SingletonManager { }) $rootScope.$on("sync:completed", (event, data) => { + // Wait for initial data load before handling any sync. If we don't want for initial data load, + // then the singleton resolver won't have the proper items to work with to determine whether to resolve or create. + if(!this.initialDataLoaded) { + return; + } // The reason we also need to consider savedItems in consolidating singletons is in case of sync conflicts, // a new item can be created, but is never processed through "retrievedItems" since it is only created locally then saved. From 8a56db377feabe09c6812ae61d7630cda1d68868 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 20 Dec 2018 10:36:23 -0600 Subject: [PATCH 55/62] Component stack dock fixes --- .../javascripts/app/controllers/editor.js | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 247107ab0..b1b196bb6 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -27,6 +27,7 @@ angular.module('app') this.spellcheck = true; this.componentManager = componentManager; + this.componentStack = []; $rootScope.$on("sync:taking-too-long", function(){ this.syncTakingTooLong = true; @@ -88,11 +89,14 @@ angular.module('app') } }); - // Observe editor changes to see if the current note should update its editor modelManager.addItemSyncObserver("editor-component-observer", "SN|Component", (allItems, validItems, deletedItems, source) => { if(!this.note) { return; } + // Reload componentStack in case new ones were added or removed + this.reloadComponentStackArray(); + + // Observe editor changes to see if the current note should update its editor var editors = allItems.filter(function(item) { return item.isEditor(); }); @@ -683,15 +687,18 @@ angular.module('app') } }}); - - this.reloadComponentContext = function() { - // componentStack is used by the template to ng-repeat + this.reloadComponentStackArray = function() { this.componentStack = componentManager.componentsForArea("editor-stack").sort((a, b) => { // Careful here. For some reason (probably because re-assigning array everytime quickly destroys componentView elements, causing deallocs), // sorting by updated_at (or any other property that may always be changing) // causes weird problems with ext communication when changing notes or activating/deactivating in quick succession return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); + } + + this.reloadComponentContext = function() { + // componentStack is used by the template to ng-repeat + this.reloadComponentStackArray(); /* In the past, we were doing this looping code even if the note wasn't currently defined. The problem is if an editor stack item loaded first, requested to stream items, and the note was undefined, @@ -717,13 +724,15 @@ angular.module('app') } this.toggleStackComponentForCurrentItem = function(component) { - if(component.hidden) { + // If it's hidden, we want to show it + // If it's not active, then hidden won't be set, and we mean to activate and show it. + if(component.hidden || !component.active) { // Unhide, associate with current item component.hidden = false; + this.associateComponentWithCurrentNote(component); if(!component.active) { componentManager.activateComponent(component); } - this.associateComponentWithCurrentNote(component); componentManager.contextItemDidChangeInArea("editor-stack"); } else { // not hidden, hide From 2edeb553ccd2bca1f736e83614509b06fe59307d Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 20 Dec 2018 11:07:20 -0600 Subject: [PATCH 56/62] Window gained focus event --- app/assets/javascripts/app/services/desktopManager.js | 2 ++ app/assets/javascripts/app/services/passcodeManager.js | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/app/services/desktopManager.js b/app/assets/javascripts/app/services/desktopManager.js index 7478b432b..de16399d5 100644 --- a/app/assets/javascripts/app/services/desktopManager.js +++ b/app/assets/javascripts/app/services/desktopManager.js @@ -83,6 +83,8 @@ class DesktopManager { if(!this.passcodeManager.isLocked()) { this.syncManager.sync(); } + + this.$rootScope.$broadcast("window-gained-focus"); } desktop_windowLostFocus() { diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 765ac7345..390471e87 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -148,8 +148,10 @@ class PasscodeManager { if(isDesktopApplication()) { // desktop only this.$rootScope.$on("window-lost-focus", () => { - let visible = false; - this.documentVisibilityChanged(visible); + this.documentVisibilityChanged(false); + }) + this.$rootScope.$on("window-gained-focus", () => { + this.documentVisibilityChanged(true); }) } else { // tab visibility listender, web only From 9b08f1e124dcde7a99a3bfc8b57be2777977f386 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 20 Dec 2018 12:35:31 -0600 Subject: [PATCH 57/62] Reload theme dock logic --- app/assets/javascripts/app/controllers/footer.js | 12 +++++++----- package.json | 2 +- public/extensions/extensions-manager | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index f0c37e9a8..15fcd07f2 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -138,20 +138,22 @@ angular.module('app') this.componentManager = componentManager; this.rooms = []; - this.themes = []; + this.themesWithIcons = []; modelManager.addItemSyncObserver("room-bar", "SN|Component", (allItems, validItems, deletedItems, source) => { this.rooms = modelManager.components.filter((candidate) => {return candidate.area == "rooms" && !candidate.deleted}); }); modelManager.addItemSyncObserver("footer-bar-themes", "SN|Theme", (allItems, validItems, deletedItems, source) => { - let themes = modelManager.validItemsForContentType("SN|Theme").filter((candidate) => {return !candidate.deleted}).sort((a, b) => { + let themes = modelManager.validItemsForContentType("SN|Theme").filter((candidate) => { + return !candidate.deleted && candidate.content.package_info.dock_icon; + }).sort((a, b) => { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); - let differ = themes.length != this.themes.length; + let differ = themes.length != this.themesWithIcons.length; - this.themes = themes; + this.themesWithIcons = themes; if(differ) { this.reloadDockShortcuts(); @@ -160,7 +162,7 @@ angular.module('app') this.reloadDockShortcuts = function() { let shortcuts = []; - for(var theme of this.themes) { + for(var theme of this.themesWithIcons) { var icon = theme.content.package_info.dock_icon; if(!icon) { continue; diff --git a/package.json b/package.json index c75637f8b..b221e7500 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.0.0-beta1", + "version": "3.0.0-beta3", "license": "AGPL-3.0-or-later", "repository": { "type": "git", diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index 50a53c646..aa7682717 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit 50a53c6469db7a92ddfe2562da09c8cacd7c9901 +Subproject commit aa76827177f5067ff5b115cb964900de0380c026 From 091e484199440a8e105787487b4bb3dbefb83d00 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 20 Dec 2018 18:20:12 -0600 Subject: [PATCH 58/62] Full width login button --- app/assets/templates/directives/account-menu.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 6a6f21386..6b75744f9 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -42,8 +42,9 @@ %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} (Learn more) .sk-panel-section.form-submit{"ng-if" => "!formData.authenticating"} - .sk-button.info.featured{'ng-click' => 'submitAuthForm()', "ng-disabled" => "formData.authenticating"} - .sk-label {{formData.showLogin ? "Sign In" : "Register"}} + .sk-button-group.stretch + .sk-button.info.featured{'ng-click' => 'submitAuthForm()', "ng-disabled" => "formData.authenticating"} + .sk-label {{formData.showLogin ? "Sign In" : "Register"}} .sk-notification.neutral{"ng-if" => "formData.showRegister"} .sk-notification-title No Password Reset. From 28f5bbaf87eb69573d16e44a93f5e8efa6f6648a Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 21 Dec 2018 10:56:54 -0600 Subject: [PATCH 59/62] Use lockAfterDate for locking if timeout is put to sleep --- .../app/services/passcodeManager.js | 35 ++++++++++++++----- .../directives/account-menu.html.haml | 1 - 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 390471e87..357225fab 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,3 +1,5 @@ +const MillisecondsPerSecond = 1000; + class PasscodeManager { constructor($rootScope, authManager, storageManager) { @@ -161,7 +163,6 @@ class PasscodeManager { }); } - const MillisecondsPerSecond = 1000; PasscodeManager.AutoLockIntervalNone = 0; PasscodeManager.AutoLockIntervalImmediate = 1; PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; @@ -175,7 +176,7 @@ class PasscodeManager { return [ { value: PasscodeManager.AutoLockIntervalNone, - label: "None" + label: "Off" }, { value: PasscodeManager.AutoLockIntervalImmediate, @@ -183,24 +184,29 @@ class PasscodeManager { }, { value: PasscodeManager.AutoLockIntervalOneMinute, - label: "1 Min" + label: "1m" }, { value: PasscodeManager.AutoLockIntervalFiveMinutes, - label: "5 Min" + label: "5m" }, { value: PasscodeManager.AutoLockIntervalOneHour, - label: "1 Hr" + label: "1h" } ] } documentVisibilityChanged(visible) { - if(!visible) { - this.beginAutoLockTimer(); - } else { + if(visible) { + // check to see if lockAfterDate is not null, and if the application isn't locked. + // if that's the case, it needs to be locked immediately. + if(this.lockAfterDate && new Date() > this.lockAfterDate && !this.isLocked()) { + this.lockApplication(); + } this.cancelAutoLockTimer(); + } else { + this.beginAutoLockTimer(); } } @@ -210,13 +216,26 @@ class PasscodeManager { return; } + // Use a timeout if possible, but if the computer is put to sleep, timeouts won't work. + // Need to set a date as backup. this.lockAfterDate does not need to be persisted, as + // living in memory seems sufficient. If memory is cleared, then the application will lock anyway. + let addToNow = (seconds) => { + let date = new Date(); + date.setSeconds(date.getSeconds() + seconds); + return date; + } + + this.lockAfterDate = addToNow(interval / MillisecondsPerSecond); this.lockTimeout = setTimeout(() => { this.lockApplication(); + // We don't need to look at this anymore since we've succeeded with timeout lock + this.lockAfterDate = null; }, interval); } cancelAutoLockTimer() { clearTimeout(this.lockTimeout); + this.lockAfterDate = null; } } diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index 6b75744f9..60d0d357c 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -140,7 +140,6 @@ %div{"ng-if" => "hasPasscode() && !formData.showPasscodeForm"} .sk-p Passcode lock is enabled. - %span{"ng-if" => "isDesktopApplication()"} Your passcode will be required on new sessions after app quit. .sk-notification.contrast .sk-notification-title Options From 1de0c85e279cce9c9562efb603c0d2b12ced84f9 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 21 Dec 2018 11:05:02 -0600 Subject: [PATCH 60/62] Sync on window focus --- app/assets/javascripts/app/services/desktopManager.js | 4 ---- app/assets/javascripts/app/services/passcodeManager.js | 7 ++++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/app/services/desktopManager.js b/app/assets/javascripts/app/services/desktopManager.js index de16399d5..58ce492d9 100644 --- a/app/assets/javascripts/app/services/desktopManager.js +++ b/app/assets/javascripts/app/services/desktopManager.js @@ -80,10 +80,6 @@ class DesktopManager { } desktop_windowGainedFocus() { - if(!this.passcodeManager.isLocked()) { - this.syncManager.sync(); - } - this.$rootScope.$broadcast("window-gained-focus"); } diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 357225fab..79ed39f02 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -2,9 +2,10 @@ const MillisecondsPerSecond = 1000; class PasscodeManager { - constructor($rootScope, authManager, storageManager) { + constructor($rootScope, authManager, storageManager, syncManager) { this.authManager = authManager; this.storageManager = storageManager; + this.syncManager = syncManager; this.$rootScope = $rootScope; this._hasPasscode = this.storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; @@ -203,6 +204,10 @@ class PasscodeManager { // if that's the case, it needs to be locked immediately. if(this.lockAfterDate && new Date() > this.lockAfterDate && !this.isLocked()) { this.lockApplication(); + } else { + if(!this.isLocked()) { + this.syncManager.sync(); + } } this.cancelAutoLockTimer(); } else { From 7f7afd1a18c59a4c9316203ddda014f4aedcae1f Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 21 Dec 2018 11:27:55 -0600 Subject: [PATCH 61/62] Moz selection colors --- .../javascripts/app/directives/views/privilegesAuthModal.js | 5 ----- app/assets/javascripts/app/services/authManager.js | 1 - app/assets/javascripts/app/services/singletonManager.js | 2 +- app/assets/stylesheets/app/_main.scss | 4 ++-- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index c677da92b..8440fd849 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -1,8 +1,3 @@ -/* - The purpose of the conflict resoltion modal is to present two versions of a conflicted item, - and allow the user to choose which to keep (or to keep both.) -*/ - class PrivilegesAuthModal { constructor() { diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index d92e9d1e5..379617ca1 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -135,7 +135,6 @@ class AuthManager extends SFAuthManager { let contentTypePredicate = new SFPredicate("content_type", "=", prefsContentType); this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { - // console.log("Loaded existing user prefs", resolvedSingleton.uuid); this.userPreferences = resolvedSingleton; this.userPreferencesDidChange(); }, (valueCallback) => { diff --git a/app/assets/javascripts/app/services/singletonManager.js b/app/assets/javascripts/app/services/singletonManager.js index 6c4ce588b..4d7969eb7 100644 --- a/app/assets/javascripts/app/services/singletonManager.js +++ b/app/assets/javascripts/app/services/singletonManager.js @@ -29,7 +29,7 @@ class SingletonManager { /* If an item alternates its uuid on registration, singletonHandlers might need to update - their local refernece to the object, since the object reference will change on uuid alternation + their local reference to the object, since the object reference will change on uuid alternation */ modelManager.addModelUuidChangeObserver("singleton-manager", (oldModel, newModel) => { for(var handler of this.singletonHandlers) { diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index 514b8843a..a63f25de2 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -74,8 +74,8 @@ a { } ::-moz-selection { - background: var(--sn-stylekit-text-selection-color) !important; /* WebKit/Blink Browsers */ - color: white; + background: var(--sn-stylekit-info-color) !important; + color: var(--sn-stylekit-info-contrast-color); } p { From ad956646ed095fae7090f8082b30d167bdf39001 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 21 Dec 2018 11:31:46 -0600 Subject: [PATCH 62/62] 3.0.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee6414031..a97eed879 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.0.0-beta1", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b221e7500..0614f8400 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.0.0-beta3", + "version": "3.0.0", "license": "AGPL-3.0-or-later", "repository": { "type": "git",