From 9b125243eea2688f457afdd411eeb3d111255225 Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 9 May 2017 09:12:27 -0500 Subject: [PATCH 01/51] Revert the revert! This reverts commit ebe42f0d68e23f071de05267362fec45ab97489d. --- .editorconfig | 11 ++ README.md | 65 ------- my-app-seed-war/src/main/webapp/js/config.js | 3 - .../src/main/webapp/js/override.js | 24 --- .../src/main/webapp/json/sessionsample.json | 9 - .../src/main/webapp/my-app/my-app.css | 1 - .../main/webapp/my-app/view-home/README.md | 23 --- .../webapp/my-app/view-home/controllers.js | 8 - .../webapp/my-app/view-home/directives.js | 16 -- .../view-home/partials/subview-directive.html | 6 - .../webapp/my-app/view-home/view-home.html | 47 ----- pom.xml | 10 +- .../pom.xml | 8 +- .../src/main/webapp/WEB-INF/web.xml | 2 +- .../src/main/webapp/js/config.js | 3 + .../src/main/webapp/js/override.js | 20 ++ .../src/main/webapp/json/custom-template.json | 16 ++ .../webapp/json/list-of-links-template.json | 34 ++++ .../src/main/webapp/json/rss-template.json | 22 +++ .../json/search-with-links-template.json | 35 ++++ .../main/webapp/json/starter-templates.json | 111 +++++++++++ .../src/main/webapp/my-app/main.js | 4 +- .../src/main/webapp/my-app/my-app.css | 47 +++++ .../webapp/my-app/view-home/controllers.js | 174 ++++++++++++++++++ .../webapp/my-app/view-home/directives.js | 7 + .../main/webapp/my-app/view-home/routes.js | 0 .../main/webapp/my-app/view-home/services.js | 26 +++ .../webapp/my-app/view-home/view-home.html | 90 +++++++++ 28 files changed, 609 insertions(+), 213 deletions(-) create mode 100644 .editorconfig delete mode 100644 my-app-seed-war/src/main/webapp/js/config.js delete mode 100644 my-app-seed-war/src/main/webapp/js/override.js delete mode 100644 my-app-seed-war/src/main/webapp/json/sessionsample.json delete mode 100644 my-app-seed-war/src/main/webapp/my-app/my-app.css delete mode 100644 my-app-seed-war/src/main/webapp/my-app/view-home/README.md delete mode 100644 my-app-seed-war/src/main/webapp/my-app/view-home/controllers.js delete mode 100644 my-app-seed-war/src/main/webapp/my-app/view-home/directives.js delete mode 100644 my-app-seed-war/src/main/webapp/my-app/view-home/partials/subview-directive.html delete mode 100644 my-app-seed-war/src/main/webapp/my-app/view-home/view-home.html rename {my-app-seed-war => widget-creator-war}/pom.xml (78%) rename {my-app-seed-war => widget-creator-war}/src/main/webapp/WEB-INF/web.xml (94%) create mode 100644 widget-creator-war/src/main/webapp/js/config.js create mode 100644 widget-creator-war/src/main/webapp/js/override.js create mode 100644 widget-creator-war/src/main/webapp/json/custom-template.json create mode 100644 widget-creator-war/src/main/webapp/json/list-of-links-template.json create mode 100644 widget-creator-war/src/main/webapp/json/rss-template.json create mode 100644 widget-creator-war/src/main/webapp/json/search-with-links-template.json create mode 100644 widget-creator-war/src/main/webapp/json/starter-templates.json rename {my-app-seed-war => widget-creator-war}/src/main/webapp/my-app/main.js (94%) create mode 100644 widget-creator-war/src/main/webapp/my-app/my-app.css create mode 100644 widget-creator-war/src/main/webapp/my-app/view-home/controllers.js create mode 100644 widget-creator-war/src/main/webapp/my-app/view-home/directives.js rename {my-app-seed-war => widget-creator-war}/src/main/webapp/my-app/view-home/routes.js (100%) create mode 100644 widget-creator-war/src/main/webapp/my-app/view-home/services.js create mode 100644 widget-creator-war/src/main/webapp/my-app/view-home/view-home.html diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c5c70d2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +charset = utf-8 +continuation_indent_size = 2 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + diff --git a/README.md b/README.md index a458cf9..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,65 +0,0 @@ -## My UW App Seed - -[![Build Status](https://travis-ci.org/UW-Madison-DoIT/my-app-seed.svg)](https://travis-ci.org/UW-Madison-DoIT/my-app-seed) - -This is a seed project intended to be used as a template for creating applications in My UW in a new way. - -Rather than creating a Portlet, developers can clone this project and write a Servlet 3 web application -that can deployed with My UW Madison. - -### Requirements - -This application assumes you are familiar with Maven, have it installed, and have a settings.xml -appropriate for interacting with UW's [Maven Artifact Repository](https://wiki.doit.wisc.edu/confluence/pages/viewpage.action?spaceKey=ST&title=Maven+Repository+Manager). - -### Getting started - -1. `git clone git@github.com:UW-Madison-DoIT/my-app-seed.git your-app-name` -2. `cd your-app-name` -3. `mvn install jetty:run` - -Point your browser at http://localhost:8080 and you'll see the familiar My UW frame. - -### Adding your content - -The unique aspect about this project is that it overlays [angularjs-portal-frame](https://github.com/UW-Madison-DoIT/angularjs-portal). -That project provides us the frame that My UW uses: the header, the sidebar, and the footer. It provides -us an extension point in a file with a specific name: [main.js](my-app-seed-war/src/main/webapp/my-app/main.js). - -That file is expected to be a [require.js](http://requirejs.org/) module, i.e. enclosed within a `define()` function. RequireJS can be -used to include more javascript resources from within [my-app.js](my-app-seed-war/src/main/webapp/my-app.js). -For example: -```javascript -var myWidget = require(['my-widget.js'], function() { - alert('Require runs my-widget.js first, and then this function.'); -}); -``` -For detailed information, see the [require.js quickstart guide](http://requirejs.org/docs/start.html) and [API documentation](http://requirejs.org/docs/api.html). - -In main.js, you can see that we reference a variable named `app`. This variable is the result of [angular.module](https://docs.angularjs.org/api/ng/type/angular.Module) -that was provided by angularjs-portal-frame. - -With that reference we can use Angular to register app-specific controllers, services, directives, etc. - -The example in this project does a number of things: - -+ The `define` block includes all of the necessary routes, controllers, services, etc. that we need for our app to run. -Every time you add a new view/module, you will want to include its various components here. -+ The `var app` declaration includes the pieces that the angular application needs to know about. -+ The `app.config` block establishes routes that the application needs to know about. Whenever you add a new module/view, you -will need to add its route here and in the `/WEB-INF/web.xml` file in order for your application to find it. -+ The `app.config` block also instantiates and initializes the color palettes to be used by Angular Material elements -(i.e. anything with the "md-" prefix). See [Angular Material - Configuring a Theme](https://material.angularjs.org/latest/Theming/03_configuring_a_theme) -for more information. - -### Why is this a multi-module project? - -Generally, projects that use this seed are a little larger in nature and have other modules encapsulating parts -of the code base. You would see other modules that are siblings of the war module like: - -* api -* impl -* security -* integration - -For even better encapsulation and decoupling, you could consider factoring these modules into their own repositories, even independently semantically versioned. diff --git a/my-app-seed-war/src/main/webapp/js/config.js b/my-app-seed-war/src/main/webapp/js/config.js deleted file mode 100644 index 8eaa6f9..0000000 --- a/my-app-seed-war/src/main/webapp/js/config.js +++ /dev/null @@ -1,3 +0,0 @@ -var config = { - gaID : 'UA-123456789-12' -} diff --git a/my-app-seed-war/src/main/webapp/js/override.js b/my-app-seed-war/src/main/webapp/js/override.js deleted file mode 100644 index cc68d94..0000000 --- a/my-app-seed-war/src/main/webapp/js/override.js +++ /dev/null @@ -1,24 +0,0 @@ -define(['angular'], function(angular) { - - /*Keep in sync with docs/mardown/configuration.md*/ - - var config = angular.module('override', []); - config - //see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto - .constant('OVERRIDE', { - 'NAMES' : { - 'title' : 'My App Seed Name', - 'fname' : 'app-seed-fname' - }, - 'APP_BETA_FEATURES' : [ - { - "id" : "someAdditionalBetaFeature", - "title" : "App Seed Beta Feature", - "description" : "This is just an example of a toggle. Look at your localStorage after you switch this on for the first time." - } - ] - }) - - return config; - -}); diff --git a/my-app-seed-war/src/main/webapp/json/sessionsample.json b/my-app-seed-war/src/main/webapp/json/sessionsample.json deleted file mode 100644 index a84b59f..0000000 --- a/my-app-seed-war/src/main/webapp/json/sessionsample.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "person": { - "userName": "userx", - "sessionKey": "someRandomKey", - "serverName": "localhost", - "displayName": "Bucky Badger", - "version": "1.0.0" - } -} diff --git a/my-app-seed-war/src/main/webapp/my-app/my-app.css b/my-app-seed-war/src/main/webapp/my-app/my-app.css deleted file mode 100644 index 8b13789..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/my-app.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/README.md b/my-app-seed-war/src/main/webapp/my-app/view-home/README.md deleted file mode 100644 index f80fd91..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/view-home/README.md +++ /dev/null @@ -1,23 +0,0 @@ -This is just an example directory, but you can have many of these in your project - -### File Structure - -+ partials/\*.html (all your partials, including route partials and directives) -+ controllers.js (controllers for this module go here) -+ directives.js (directives for this module go here) -+ services.js (services go here) -+ routes.js (More about routes below) - -### Routes - -Routes is a simple json object. There can be one or many. You are encouraged to use one route per module or "view." -This file is used to tell your app where to look for this module/view in main.js. Look there for more information. - -### Paths - -To add an additional route to this module (ex. A single module may have a "summary" page and "detail" page that each use a separate route): - -+ Give the route a sensible name -+ Use the `require.toUrl('./partials/example.html')` with a relative path from the file you are writing it in -+ Add the route to the `.config` section in `main.js` - diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/controllers.js b/my-app-seed-war/src/main/webapp/my-app/view-home/controllers.js deleted file mode 100644 index beb35f0..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/view-home/controllers.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -define(['angular', 'jquery'], function(angular, $) { - - var app = angular.module('my-app.view-home.controllers', []); - - //put controllers here -}); diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/directives.js b/my-app-seed-war/src/main/webapp/my-app/view-home/directives.js deleted file mode 100644 index e2e0f84..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/view-home/directives.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -define(['angular', 'require'], function(angular, require) { - var app = angular.module('my-app.view-home.directives', []); - - /** - * Example directive to show relative path with require.toUrl - * - */ - app.directive('subviewDirective', function(){ - return { - restrict : 'E', - templateUrl : require.toUrl('./partials/subview-directive.html') - } - }); -}); diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/partials/subview-directive.html b/my-app-seed-war/src/main/webapp/my-app/view-home/partials/subview-directive.html deleted file mode 100644 index dccaff3..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/view-home/partials/subview-directive.html +++ /dev/null @@ -1,6 +0,0 @@ -

View Two

-

This view lives in the subview-directive directive.

- diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/view-home.html b/my-app-seed-war/src/main/webapp/my-app/view-home/view-home.html deleted file mode 100644 index 4a4c580..0000000 --- a/my-app-seed-war/src/main/webapp/my-app/view-home/view-home.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - -

Module Overview

-

The /view-home directory is just an example module directory, but you can have many of these - in your project. You should have one module directory for each distinct view or module in your application. - If the content and business logic of a feature/page are substantial enough to merit a separate URL, it should be considered - part of a new module.

- -

File Structure

-
    -
  • partials/*.html: All your partials, including route partials and directives
  • -
  • controllers.js: Controllers for this module go here
  • -
  • directives.js: Directives for this module go here
  • -
  • services.js: Services go here
  • -
  • routes.js: Module routes go here
  • -
- -

Routes

-

Routes is a simple json object. There can be one or many. You are encouraged to use one route per module or "view." - This file is used to tell your app where to look for this module/view in main.js. Look there for more information.

- -

Paths

-

To add an additional route to this module (ex. A "summary" page and "detail" page might be part of the same module, but may use separate paths):

-
    -
  • Give the route a sensible name
  • -
  • Use the require.toUrl('./partials/example.html') with a relative path from the file you are writing it in
  • -
  • Add the route to the .config section in /view-home/main.js
  • -
-
-
- - - - - - -
-
-
\ No newline at end of file diff --git a/pom.xml b/pom.xml index 3c18a45..401c11c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,11 @@ 4.0.0 edu.wisc.my.app - my-app-seed + widget-creator 0.0.1-SNAPSHOT pom - My App Seed Parent - Parent pom for seed project demonstrating how to write "apps" for My UW Madison. + Widget Creator Parent + Parent pom for widget creator project. scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git @@ -17,7 +17,7 @@ edu.wisc.my.apps uw-frame - 3.1.4 + 4.1.0 war @@ -57,6 +57,6 @@ - my-app-seed-war + widget-creator-war diff --git a/my-app-seed-war/pom.xml b/widget-creator-war/pom.xml similarity index 78% rename from my-app-seed-war/pom.xml rename to widget-creator-war/pom.xml index 7d1f5b1..9659af8 100644 --- a/my-app-seed-war/pom.xml +++ b/widget-creator-war/pom.xml @@ -2,12 +2,12 @@ 4.0.0 edu.wisc.my.app - my-app-seed + widget-creator 0.0.1-SNAPSHOT - my-app-seed-war - My App Seed War - Web application for My UW app seed project. + widget-creator-war + Widget Creator War + Web application for uportal-app-framework widget creator. war diff --git a/my-app-seed-war/src/main/webapp/WEB-INF/web.xml b/widget-creator-war/src/main/webapp/WEB-INF/web.xml similarity index 94% rename from my-app-seed-war/src/main/webapp/WEB-INF/web.xml rename to widget-creator-war/src/main/webapp/WEB-INF/web.xml index c1c285f..a31ee3f 100644 --- a/my-app-seed-war/src/main/webapp/WEB-INF/web.xml +++ b/widget-creator-war/src/main/webapp/WEB-INF/web.xml @@ -7,7 +7,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> - My Application Seed + Widget Creator index.jsp diff --git a/widget-creator-war/src/main/webapp/js/config.js b/widget-creator-war/src/main/webapp/js/config.js new file mode 100644 index 0000000..28a4db8 --- /dev/null +++ b/widget-creator-war/src/main/webapp/js/config.js @@ -0,0 +1,3 @@ +var config = { + gaID : '' +} diff --git a/widget-creator-war/src/main/webapp/js/override.js b/widget-creator-war/src/main/webapp/js/override.js new file mode 100644 index 0000000..585ebe9 --- /dev/null +++ b/widget-creator-war/src/main/webapp/js/override.js @@ -0,0 +1,20 @@ +define(['angular'], function(angular) { + + /*Keep in sync with docs/mardown/configuration.md*/ + + var config = angular.module('override', []); + config + //see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto + .constant('OVERRIDE', { + 'NAMES': { + 'title': 'Widget Creator', + 'fname': 'widget-creator' + }, + 'SERVICE_LOC': { + 'templates': '/json/starter-templates' + } + }); + + return config; + +}); diff --git a/widget-creator-war/src/main/webapp/json/custom-template.json b/widget-creator-war/src/main/webapp/json/custom-template.json new file mode 100644 index 0000000..f7723a1 --- /dev/null +++ b/widget-creator-war/src/main/webapp/json/custom-template.json @@ -0,0 +1,16 @@ +{ + "entry": { + "layoutObject": { + "id": 4, + "type": "widget-creator", + "widgetType": "custom", + "title": "Custom", + "hasWidgetURL": false, + "description": "This super cool portlet can change lives.", + "widgetConfig": {}, + "widgetTemplate": "

Hello

", + "jsonSample": {}, + "url": "www.example.com" + } + } +} diff --git a/widget-creator-war/src/main/webapp/json/list-of-links-template.json b/widget-creator-war/src/main/webapp/json/list-of-links-template.json new file mode 100644 index 0000000..26d98c3 --- /dev/null +++ b/widget-creator-war/src/main/webapp/json/list-of-links-template.json @@ -0,0 +1,34 @@ +{ + "entry": { + "layoutObject": { + "id": 3, + "url": "www.example.com", + "type": "list-of-links", + "widgetType": "list-of-links", + "title": "List of Links", + "jsonSample": false, + "hasWidgetURL": false, + "widgetConfig": { + "launchText": "Launch the Full App", + "additionalText": "Additional Text", + "links": [ + { + "title": "The Google", + "href": "http://www.google.com", + "icon": "fa-google", + "target": "_blank", + "rel": "noopener noreferrer" + }, + { + "title": "Bing", + "href": "http://www.bing.com", + "icon": "fa-bed", + "target": "_blank", + "rel": "noopener noreferrer" + } + ] + }, + "description": "A simple list of links" + } + } +} diff --git a/widget-creator-war/src/main/webapp/json/rss-template.json b/widget-creator-war/src/main/webapp/json/rss-template.json new file mode 100644 index 0000000..a538fd9 --- /dev/null +++ b/widget-creator-war/src/main/webapp/json/rss-template.json @@ -0,0 +1,22 @@ +{ + "entry": { + "layoutObject": { + "id": 2, + "url": "www.example.com", + "type": "rss", + "widgetType": "rss", + "title": "RSS Widget", + "jsonSample": false, + "widgetConfig": { + "lim": 6, + "target": "", + "showdate": true, + "titleLim": 40, + "dateFormat": "MM-dd-yyyy", + "showShowing": true + }, + "hasWidgetURL": true, + "widgetURL": "" + } + } +} diff --git a/widget-creator-war/src/main/webapp/json/search-with-links-template.json b/widget-creator-war/src/main/webapp/json/search-with-links-template.json new file mode 100644 index 0000000..3926b8a --- /dev/null +++ b/widget-creator-war/src/main/webapp/json/search-with-links-template.json @@ -0,0 +1,35 @@ +{ + "entry": { + "layoutObject": { + "id": 1, + "type": "search-with-links", + "widgetType": "search-with-links", + "title": "Search with Links", + "jsonSample": false, + "url": "www.example.com", + "widgetConfig": { + "actionURL": "https://rprg.wisc.edu/search/", + "actionTarget": "_blank", + "actionParameter": "q", + "launchText": "Go to resource guide", + "links": [ + { + "title": "Get started", + "href": "https://rprg.wisc.edu/phases/initiate/", + "icon": "fa-map-o", + "target": "_blank", + "rel": "noopener noreferrer" + }, + { + "title": "Resources", + "href": "https://rprg.wisc.edu/category/resource/", + "icon": "fa-th-list", + "target": "_blank", + "rel": "noopener noreferrer" + } + ] + }, + "hasWidgetURL": false + } + } +} diff --git a/widget-creator-war/src/main/webapp/json/starter-templates.json b/widget-creator-war/src/main/webapp/json/starter-templates.json new file mode 100644 index 0000000..8b98c76 --- /dev/null +++ b/widget-creator-war/src/main/webapp/json/starter-templates.json @@ -0,0 +1,111 @@ +{ + "templates": [ + { + "entry": { + "layoutObject": { + "id": 4, + "type": "widget-creator", + "widgetType": "custom", + "title": "Custom", + "hasWidgetURL": false, + "description": "This super cool portlet can change lives.", + "widgetConfig": {}, + "widgetTemplate": "

Hello

", + "jsonSample": {}, + "url": "www.example.com" + } + } + }, + { + "entry": { + "layoutObject": { + "id": 1, + "type": "search-with-links", + "widgetType": "search-with-links", + "title": "Search with Links", + "jsonSample": false, + "url": "www.example.com", + "widgetConfig": { + "actionURL": "https://rprg.wisc.edu/search/", + "actionTarget": "_blank", + "actionParameter": "q", + "launchText": "Go to resource guide", + "links": [ + { + "title": "Get started", + "href": "https://rprg.wisc.edu/phases/initiate/", + "icon": "fa-map-o", + "target": "_blank", + "rel": "noopener noreferrer" + }, + { + "title": "Resources", + "href": "https://rprg.wisc.edu/category/resource/", + "icon": "fa-th-list", + "target": "_blank", + "rel": "noopener noreferrer" + } + ] + }, + "hasWidgetURL": false + } + } + }, + { + "entry": { + "layoutObject": { + "id": 3, + "url": "www.example.com", + "type": "list-of-links", + "widgetType": "list-of-links", + "title": "List of Links", + "jsonSample": false, + "hasWidgetURL": false, + "widgetConfig": { + "launchText": "Launch the Full App", + "additionalText": "Additional Text", + "links": [ + { + "title": "The Google", + "href": "http://www.google.com", + "icon": "fa-google", + "target": "_blank", + "rel": "noopener noreferrer" + }, + { + "title": "Bing", + "href": "http://www.bing.com", + "icon": "fa-bed", + "target": "_blank", + "rel": "noopener noreferrer" + } + ] + }, + "description": "A simple list of links" + } + } + }, + { + "entry": { + "layoutObject": { + "id": 2, + "url": "www.example.com", + "type": "rss", + "widgetType": "rss", + "title": "RSS Widget", + "jsonSample": false, + "widgetConfig": { + "lim": 6, + "target": "", + "showdate": true, + "titleLim": 40, + "dateFormat": "MM-dd-yyyy", + "showShowing": true + }, + "hasWidgetURL": true, + "widgetURL": "" + } + } + } + ] +} diff --git a/my-app-seed-war/src/main/webapp/my-app/main.js b/widget-creator-war/src/main/webapp/my-app/main.js similarity index 94% rename from my-app-seed-war/src/main/webapp/my-app/main.js rename to widget-creator-war/src/main/webapp/my-app/main.js index 6a81f31..ec3f417 100644 --- a/my-app-seed-war/src/main/webapp/my-app/main.js +++ b/widget-creator-war/src/main/webapp/my-app/main.js @@ -11,13 +11,15 @@ define([ 'ngSanitize', 'ngStorage', './view-home/controllers', //add all your paths to your other js files here - './view-home/directives' + './view-home/directives', + './view-home/services' ], function(angular, require, homeRoutes, settingsRoutes, aboutRoute, mainRoutes) { //notice each route file is now an object var app = angular.module('my-app', [ 'app-config', 'my-app.view-home.controllers', // add in your modules here 'my-app.view-home.directives', + 'my-app.view-home.services', 'ngRoute', 'ngSanitize', 'ngStorage', diff --git a/widget-creator-war/src/main/webapp/my-app/my-app.css b/widget-creator-war/src/main/webapp/my-app/my-app.css new file mode 100644 index 0000000..0374db4 --- /dev/null +++ b/widget-creator-war/src/main/webapp/my-app/my-app.css @@ -0,0 +1,47 @@ +.widget-creator .portlet-body { + padding: 10px; +} + +.widget-creator .container__select-template { + padding-bottom: 20px; +} + +.widget-creator widget { + width: 300px; +} + +.widget-creator .help-notes p { + color: #999; + font-size: 12px; + margin-bottom: 0; +} + +.widget-creator textarea { + padding: 10px 14px; + overflow-y: scroll; +} + +.widget-creator ::-webkit-input-placeholder { + color: @grayscale6; + font-size: 12px; +} + +.widget-creator :-moz-placeholder { /* Firefox 18- */ + color: @grayscale6; + font-size: 12px; +} + +.widget-creator ::-moz-placeholder { /* Firefox 19+ */ + color: @grayscale6; + font-size: 12px; +} + +.widget-creator :-ms-input-placeholder { + color: @grayscale6; + font-size: 12px; +} + +.widget-middle { + width: 315px; + margin: auto; +} \ No newline at end of file diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js new file mode 100644 index 0000000..38004a6 --- /dev/null +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -0,0 +1,174 @@ +'use strict'; + +define(['angular', 'jquery'], function (angular, $) { + + var app = angular.module('my-app.view-home.controllers', []); + + // WIDGET CREATOR controller + app.controller('WidgetCreatorController', ['$scope', '$route', '$localStorage', '$log', 'widgetCreatorService', function ($scope, $route, $localStorage, $log, widgetCreatorService) { + + var starterTemplates = []; + /*------------------*/ + /* Bindable members */ + /*------------------*/ + $scope.templateOptions = [ + { "value": "search-with-links", "name": "Search with links" }, + { "value": "list-of-links", "name": "List of links" }, + { "value": "rss", "name": "RSS widget" }, + { "value": "widget-creator", "name": "Custom" } + ]; + $scope.selectedTemplate = {}; + $scope.content = {}; + $scope.storage = {}; + $scope.storage.isInitialized = false; + + /*-----------------*/ + /* Scope functions */ + /*-----------------*/ + + // Reload widget preview + $scope.reload = function () { + updateStorage(); + $route.reload(); + }; + + // Clear widget configuration + $scope.clear = function () { + if (confirm('Are you sure, all your config will be cleared')) { + $localStorage.$reset(); + init(); + $route.reload(); + } + }; + + // Change to newly-selected template type + $scope.changeTemplate = function() { + // Set widget equal to starter template that matches the selected type + angular.forEach(starterTemplates, function(value, key) { + if ($scope.selectedTemplate.value == value.entry.layoutObject.type) { + $scope.widget = value.entry.layoutObject; + } + }); + + updateStorage(); + + $scope.reload(); + }; + + /*-----------------*/ + /* Local functions */ + /*-----------------*/ + + /** + * Check if json is valid + * @param json + * @returns {boolean} + */ + var isValidJSON = function isValidJson(json) { + try { + JSON.parse(json); + return true; + } catch (e) { + return false; + } + }; + + /** + * Convert JSON objects to strings so they can be displayed in HTML + */ + var prepareWidgetDataForDisplay = function() { + // Cast widget objects as string for display + $scope.widget.widgetConfig = JSON.stringify($scope.widget.widgetConfig); + if ($scope.widget.jsonSample) { + $scope.content = JSON.stringify($scope.widget.jsonSample) + } + }; + + /** + * Update local storage with current scope content + */ + var updateStorage = function() { + $scope.storage.selectedTemplate = $scope.selectedTemplate; + $scope.storage.widget = $scope.widget; + $scope.storage.widgetConfig = $scope.widget.widgetConfig; + $scope.storage.content = $scope.content; + $scope.storage.isInitialized = true; + }; + + /** + * Get starter templates and setup scope variables + */ + var setupDefaults = function() { + widgetCreatorService.getStarterTemplates() + .then(function(templates) { + starterTemplates = templates; + $log.log('Got starter templates'); + if (templates[0].entry.layoutObject) { + + // Set default widget type + $scope.widget = templates[0].entry.layoutObject; + prepareWidgetDataForDisplay(); + + // Set selected template + angular.forEach($scope.templateOptions, function(value, key) { + if ($scope.widget.type === value.value) { + $scope.selectedTemplate = value; + } + }); + + } + }) + .catch(function(error) { + $log.warn('WidgetCreatorController couldn\'t get starter templates'); + $log.error(error); + }) + }; + + /** + * Setup scope variables based on content of local storage + */ + var setupDefaultsFromStorage = function() { + $scope.widget = $scope.storage.widget; + $scope.selectedTemplate = $scope.storage.selectedTemplate; + + // If a user has entered values into custom widget type fields, make sure it's valid and display correctly + if ($scope.storage.widgetConfig && isValidJSON($scope.storage.widgetConfig)) { + // Parse widgetConfig as JSON + $scope.widget.widgetConfig = JSON.parse($scope.storage.widgetConfig); + } else { + $scope.errorConfigJSON = $scope.storage.widgetConfig ? 'JSON NOT VALID' : ''; + } + + if ($scope.storage.content && isValidJSON($scope.storage.content)) { + $scope.content = $scope.storage.content; + } else { + console.log($scope.storage.content); + $scope.errorJSON = $scope.storage.content ? 'JSON NOT VALID' : ''; + } + + prepareWidgetDataForDisplay(); + $scope.storage.isInitialized = true; + }; + + /** + * Initialize widget creator + */ + var init = function() { + // Setup variable in local storage + $localStorage.widgetCreator = $localStorage.widgetCreator || {}; + + // Makes the widget creator stuff contained + $scope.storage = $localStorage.widgetCreator; + + if ($scope.storage.isInitialized) { + // Get defaults from storage + setupDefaultsFromStorage(); + } else { + setupDefaults(); + } + }; + + init(); + }]); + +}); diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/directives.js b/widget-creator-war/src/main/webapp/my-app/view-home/directives.js new file mode 100644 index 0000000..47d6f03 --- /dev/null +++ b/widget-creator-war/src/main/webapp/my-app/view-home/directives.js @@ -0,0 +1,7 @@ +'use strict'; + +define(['angular', 'require'], function(angular, require) { + var app = angular.module('my-app.view-home.directives', []); + + +}); diff --git a/my-app-seed-war/src/main/webapp/my-app/view-home/routes.js b/widget-creator-war/src/main/webapp/my-app/view-home/routes.js similarity index 100% rename from my-app-seed-war/src/main/webapp/my-app/view-home/routes.js rename to widget-creator-war/src/main/webapp/my-app/view-home/routes.js diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/services.js b/widget-creator-war/src/main/webapp/my-app/view-home/services.js new file mode 100644 index 0000000..d12330d --- /dev/null +++ b/widget-creator-war/src/main/webapp/my-app/view-home/services.js @@ -0,0 +1,26 @@ +'use strict'; + +define(['angular', 'jquery'], function(angular, $) { + + return angular.module('my-app.view-home.services', []) + + .factory('widgetCreatorService', ['$log', '$localStorage', '$http', 'SERVICE_LOC', function($log, $localStorage, $http, SERVICE_LOC) { + + var getStarterTemplates = function() { + return $http.get(SERVICE_LOC.templates + '.json') + .then(function (result) { + if (result.data.templates != undefined) { + return result.data.templates; + } + }) + .catch(function (error) { + $log.warn('Error getting starter templates'); + $log.error(error); + }); + }; + + return { + getStarterTemplates: getStarterTemplates + }; + }]); +}); diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html new file mode 100644 index 0000000..fa459d6 --- /dev/null +++ b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html @@ -0,0 +1,90 @@ +
+ +
+
+ + + + + + Smart Widget Configuration +

Read + the documentation on widgets + . +

+
+
+ +
+
+

Choose a starter template

+ or select 'Custom' to make your own. + + + + {{ option.name }} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Clear + Update +
+ +
+

* Changes to these fields requires you to click the refresh button to see the changes in the preview

+

** This is normally result from the widgetURL. This result is dumped into the "$scope.content" + variable.

+

*** Valid JSON that gets stored in '$scope.widget.widgetConfig'

+
+
+
+ +
+
+ +
+ {{ widget }} +
+
+
+ Clear + Update +
+
+
+
+
From 70582e6fa1bc4778e88d7e8c6371476a9853db15 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Tue, 9 May 2017 15:05:24 -0500 Subject: [PATCH 02/51] using DataURI for widget fname call --- pom.xml | 2 +- widget-creator-war/src/main/webapp/js/override.js | 10 ++++++++-- .../src/main/webapp/my-app/view-home/controllers.js | 9 +++++++++ .../src/main/webapp/my-app/view-home/view-home.html | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 401c11c..76b849e 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ edu.wisc.my.apps uw-frame - 4.1.0 + 4.1.1-SNAPSHOT war
diff --git a/widget-creator-war/src/main/webapp/js/override.js b/widget-creator-war/src/main/webapp/js/override.js index 585ebe9..ce23f22 100644 --- a/widget-creator-war/src/main/webapp/js/override.js +++ b/widget-creator-war/src/main/webapp/js/override.js @@ -8,10 +8,16 @@ define(['angular'], function(angular) { .constant('OVERRIDE', { 'NAMES': { 'title': 'Widget Creator', - 'fname': 'widget-creator' + 'fname': 'widget-creator', }, 'SERVICE_LOC': { - 'templates': '/json/starter-templates' + 'templates': '/json/starter-templates', + 'widgetApi': { + // For local testing, change to 'staticFeeds/' + 'entry': 'data:application/json;base64,', + 'entrySuffix': '', + 'entries': '/portal/api/marketplace/entries.json', + }, } }); diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js index 38004a6..3269c52 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -55,6 +55,15 @@ define(['angular', 'jquery'], function (angular, $) { $scope.reload(); }; + $scope.wrapAndEncode = function() { + var wrapped = { + 'entry': { + 'layoutObject': $scope.widget + } + }; + return btoa(JSON.stringify(wrapped)); + } + /*-----------------*/ /* Local functions */ /*-----------------*/ diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html index fa459d6..da8e293 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html +++ b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html @@ -75,7 +75,7 @@

Choose a starter template

- +
{{ widget }}
From ed3d16c6bbcc3ffbb92ac047b7bc5321541d76c1 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Wed, 10 May 2017 08:36:47 -0500 Subject: [PATCH 03/51] removing base 64 encoding --- widget-creator-war/src/main/webapp/js/override.js | 2 +- .../src/main/webapp/my-app/view-home/controllers.js | 4 ++-- .../src/main/webapp/my-app/view-home/view-home.html | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/widget-creator-war/src/main/webapp/js/override.js b/widget-creator-war/src/main/webapp/js/override.js index ce23f22..f444d27 100644 --- a/widget-creator-war/src/main/webapp/js/override.js +++ b/widget-creator-war/src/main/webapp/js/override.js @@ -14,7 +14,7 @@ define(['angular'], function(angular) { 'templates': '/json/starter-templates', 'widgetApi': { // For local testing, change to 'staticFeeds/' - 'entry': 'data:application/json;base64,', + 'entry': 'data:application/json,', 'entrySuffix': '', 'entries': '/portal/api/marketplace/entries.json', }, diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js index 3269c52..cdece1d 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -55,13 +55,13 @@ define(['angular', 'jquery'], function (angular, $) { $scope.reload(); }; - $scope.wrapAndEncode = function() { + $scope.wrapLayout = function() { var wrapped = { 'entry': { 'layoutObject': $scope.widget } }; - return btoa(JSON.stringify(wrapped)); + return JSON.stringify(wrapped); } /*-----------------*/ diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html index da8e293..5703e78 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html +++ b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html @@ -75,10 +75,7 @@

Choose a starter template

- -
- {{ widget }} -
+
Clear From fc6e1fe02c97007a4271e044533b24aa0e97c581 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Wed, 10 May 2017 15:58:16 -0500 Subject: [PATCH 04/51] wip removing localStorage --- .../webapp/my-app/view-home/controllers.js | 97 ++++--------------- .../webapp/my-app/view-home/directives.js | 21 +++- .../webapp/my-app/view-home/view-home.html | 2 +- 3 files changed, 39 insertions(+), 81 deletions(-) diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js index cdece1d..dc54081 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -5,7 +5,7 @@ define(['angular', 'jquery'], function (angular, $) { var app = angular.module('my-app.view-home.controllers', []); // WIDGET CREATOR controller - app.controller('WidgetCreatorController', ['$scope', '$route', '$localStorage', '$log', 'widgetCreatorService', function ($scope, $route, $localStorage, $log, widgetCreatorService) { + app.controller('WidgetCreatorController', ['$scope', '$route', '$log', 'widgetCreatorService', function ($scope, $route, $log, widgetCreatorService) { var starterTemplates = []; /*------------------*/ @@ -19,8 +19,7 @@ define(['angular', 'jquery'], function (angular, $) { ]; $scope.selectedTemplate = {}; $scope.content = {}; - $scope.storage = {}; - $scope.storage.isInitialized = false; + $scope.preview = undefined; /*-----------------*/ /* Scope functions */ @@ -28,16 +27,13 @@ define(['angular', 'jquery'], function (angular, $) { // Reload widget preview $scope.reload = function () { - updateStorage(); - $route.reload(); + prepareWidgetDataForDisplay(); }; // Clear widget configuration $scope.clear = function () { if (confirm('Are you sure, all your config will be cleared')) { - $localStorage.$reset(); init(); - $route.reload(); } }; @@ -50,15 +46,12 @@ define(['angular', 'jquery'], function (angular, $) { } }); - updateStorage(); - - $scope.reload(); }; - $scope.wrapLayout = function() { + var wrapLayout = function(preview) { var wrapped = { 'entry': { - 'layoutObject': $scope.widget + 'layoutObject': preview } }; return JSON.stringify(wrapped); @@ -86,29 +79,22 @@ define(['angular', 'jquery'], function (angular, $) { * Convert JSON objects to strings so they can be displayed in HTML */ var prepareWidgetDataForDisplay = function() { - // Cast widget objects as string for display - $scope.widget.widgetConfig = JSON.stringify($scope.widget.widgetConfig); - if ($scope.widget.jsonSample) { + var preview = angular.copy($scope.widget); + if (!angular.isString($scope.widget.widgetConfig)) { + $scope.widget.widgetConfig = JSON.stringify($scope.widget.widgetConfig); + } + preview.widgetConfig = JSON.parse($scope.widget.widgetConfig); + if (preview.jsonSample) { $scope.content = JSON.stringify($scope.widget.jsonSample) } + $scope.preview = wrapLayout(preview); }; /** - * Update local storage with current scope content - */ - var updateStorage = function() { - $scope.storage.selectedTemplate = $scope.selectedTemplate; - $scope.storage.widget = $scope.widget; - $scope.storage.widgetConfig = $scope.widget.widgetConfig; - $scope.storage.content = $scope.content; - $scope.storage.isInitialized = true; - }; - - /** - * Get starter templates and setup scope variables + * Initialize widget creator */ - var setupDefaults = function() { - widgetCreatorService.getStarterTemplates() + var init = function() { + return widgetCreatorService.getStarterTemplates() .then(function(templates) { starterTemplates = templates; $log.log('Got starter templates'); @@ -127,57 +113,12 @@ define(['angular', 'jquery'], function (angular, $) { } }) - .catch(function(error) { - $log.warn('WidgetCreatorController couldn\'t get starter templates'); - $log.error(error); - }) - }; - - /** - * Setup scope variables based on content of local storage - */ - var setupDefaultsFromStorage = function() { - $scope.widget = $scope.storage.widget; - $scope.selectedTemplate = $scope.storage.selectedTemplate; - - // If a user has entered values into custom widget type fields, make sure it's valid and display correctly - if ($scope.storage.widgetConfig && isValidJSON($scope.storage.widgetConfig)) { - // Parse widgetConfig as JSON - $scope.widget.widgetConfig = JSON.parse($scope.storage.widgetConfig); - } else { - $scope.errorConfigJSON = $scope.storage.widgetConfig ? 'JSON NOT VALID' : ''; - } - - if ($scope.storage.content && isValidJSON($scope.storage.content)) { - $scope.content = $scope.storage.content; - } else { - console.log($scope.storage.content); - $scope.errorJSON = $scope.storage.content ? 'JSON NOT VALID' : ''; - } - - prepareWidgetDataForDisplay(); - $scope.storage.isInitialized = true; - }; - - /** - * Initialize widget creator - */ - var init = function() { - // Setup variable in local storage - $localStorage.widgetCreator = $localStorage.widgetCreator || {}; - - // Makes the widget creator stuff contained - $scope.storage = $localStorage.widgetCreator; - - if ($scope.storage.isInitialized) { - // Get defaults from storage - setupDefaultsFromStorage(); - } else { - setupDefaults(); - } }; - init(); + init().catch(function(error) { + $log.warn('WidgetCreatorController couldn\'t get starter templates'); + $log.error(error); + }); }]); }); diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/directives.js b/widget-creator-war/src/main/webapp/my-app/view-home/directives.js index 47d6f03..c9d4f3e 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/directives.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/directives.js @@ -1,7 +1,24 @@ 'use strict'; define(['angular', 'require'], function(angular, require) { - var app = angular.module('my-app.view-home.directives', []); - + return angular.module('my-app.view-home.directives', []) + .directive('previewWidget', function() { + return { + restrict: 'E', + transclude: true, + scope: { + fname: '@', + }, + templateUrl: require.toUrl('../../portal/widgets/partials/widget-card.html'), + controller: 'WidgetCardController', + link: function(scope, element, attrs) { + scope.$watch('fname', function(newValue, oldValue) { + if (newValue) { + scope.initializeWidget(newValue); + } + }); + }, + }; + }); }); diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html index 5703e78..2aecc1b 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html +++ b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html @@ -75,7 +75,7 @@

Choose a starter template

- +
Clear From d03ddc591043e489da950e7726b026b06ffc3211 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 11 May 2017 09:14:23 -0500 Subject: [PATCH 05/51] back to base64, separate preview config and editable config --- .../src/main/webapp/js/override.js | 2 +- .../webapp/my-app/view-home/controllers.js | 50 ++++++++++++------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/widget-creator-war/src/main/webapp/js/override.js b/widget-creator-war/src/main/webapp/js/override.js index f444d27..ce23f22 100644 --- a/widget-creator-war/src/main/webapp/js/override.js +++ b/widget-creator-war/src/main/webapp/js/override.js @@ -14,7 +14,7 @@ define(['angular'], function(angular) { 'templates': '/json/starter-templates', 'widgetApi': { // For local testing, change to 'staticFeeds/' - 'entry': 'data:application/json,', + 'entry': 'data:application/json;base64,', 'entrySuffix': '', 'entries': '/portal/api/marketplace/entries.json', }, diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js index dc54081..facdf06 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -20,6 +20,8 @@ define(['angular', 'jquery'], function (angular, $) { $scope.selectedTemplate = {}; $scope.content = {}; $scope.preview = undefined; + $scope.errorJSON = undefined; + $scope.errorConfigJSON = undefined; /*-----------------*/ /* Scope functions */ @@ -27,7 +29,7 @@ define(['angular', 'jquery'], function (angular, $) { // Reload widget preview $scope.reload = function () { - prepareWidgetDataForDisplay(); + prepareWidgetDataForDisplay($scope.widget); }; // Clear widget configuration @@ -42,7 +44,7 @@ define(['angular', 'jquery'], function (angular, $) { // Set widget equal to starter template that matches the selected type angular.forEach(starterTemplates, function(value, key) { if ($scope.selectedTemplate.value == value.entry.layoutObject.type) { - $scope.widget = value.entry.layoutObject; + $scope.widget = widgetAsEditable(value.entry.layoutObject); } }); @@ -54,7 +56,7 @@ define(['angular', 'jquery'], function (angular, $) { 'layoutObject': preview } }; - return JSON.stringify(wrapped); + return btoa(JSON.stringify(wrapped)); } /*-----------------*/ @@ -66,30 +68,42 @@ define(['angular', 'jquery'], function (angular, $) { * @param json * @returns {boolean} */ - var isValidJSON = function isValidJson(json) { + var parseJSON = function parseJSON(json) { try { - JSON.parse(json); - return true; + return JSON.parse(json); } catch (e) { - return false; + return undefined; } }; /** * Convert JSON objects to strings so they can be displayed in HTML */ - var prepareWidgetDataForDisplay = function() { - var preview = angular.copy($scope.widget); - if (!angular.isString($scope.widget.widgetConfig)) { - $scope.widget.widgetConfig = JSON.stringify($scope.widget.widgetConfig); + var prepareWidgetDataForDisplay = function(editable) { + var preview = angular.copy(editable); + var widgetConfig = parseJSON(editable.widgetConfig); + var jsonSample = parseJSON($scope.content); + if (widgetConfig && jsonSample) { + preview.widgetConfig = widgetConfig; + preview.jsonSample = jsonSample + $scope.preview = wrapLayout(preview); + } else { + $scope.errorJSON = (!jsonSample) ? 'JSON NOT VALID' : undefined; + $scope.errorConfigJSON = (!widgetConfig) ? 'JSON NOT VALID' : undefined; } - preview.widgetConfig = JSON.parse($scope.widget.widgetConfig); - if (preview.jsonSample) { - $scope.content = JSON.stringify($scope.widget.jsonSample) - } - $scope.preview = wrapLayout(preview); }; + var widgetAsEditable = function(widget) { + var editable = angular.copy(widget); + if (!angular.isString(editable.widgetConfig)) { + editable.widgetConfig = JSON.stringify(editable.widgetConfig); + } + if (editable.jsonSample) { + $scope.content = JSON.stringify(editable.jsonSample) + } + return editable; + } + /** * Initialize widget creator */ @@ -101,8 +115,8 @@ define(['angular', 'jquery'], function (angular, $) { if (templates[0].entry.layoutObject) { // Set default widget type - $scope.widget = templates[0].entry.layoutObject; - prepareWidgetDataForDisplay(); + $scope.widget = widgetAsEditable(templates[0].entry.layoutObject); + prepareWidgetDataForDisplay($scope.widget); // Set selected template angular.forEach($scope.templateOptions, function(value, key) { From b35fa69c0793eb79ee457e37b2c7dccb99f871de Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 11 May 2017 09:42:14 -0500 Subject: [PATCH 06/51] fixing indentation --- pom.xml | 118 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/pom.xml b/pom.xml index 76b849e..71f790b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,62 +1,62 @@ - 4.0.0 - edu.wisc.my.app - widget-creator - 0.0.1-SNAPSHOT - pom - Widget Creator Parent - Parent pom for widget creator project. - - scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git - scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git - https://github.com/UW-Madison-DoIT/my-app-seed - HEAD - - - - - edu.wisc.my.apps - uw-frame - 4.1.1-SNAPSHOT - war - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.2 - - - org.eclipse.jetty - jetty-maven-plugin - 9.2.8.v20150217 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.eclipse.jetty - jetty-maven-plugin - - true - - - - + 4.0.0 + edu.wisc.my.app + widget-creator + 0.0.1-SNAPSHOT + pom + Widget Creator Parent + Parent pom for widget creator project. + + scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git + scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git + https://github.com/UW-Madison-DoIT/my-app-seed + HEAD + + + + + edu.wisc.my.apps + uw-frame + 4.1.1-SNAPSHOT + war + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + + org.eclipse.jetty + jetty-maven-plugin + 9.2.8.v20150217 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.eclipse.jetty + jetty-maven-plugin + + true + + + + - - widget-creator-war - + + widget-creator-war + From caf75dfab70aec2def7666e7b9132a5574edef6f Mon Sep 17 00:00:00 2001 From: Andrew Petro Date: Thu, 11 May 2017 10:49:54 -0500 Subject: [PATCH 07/51] Add Apache2 LICENSE file. --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 09097c02d3044052a7226ee62f428d73cb5cda82 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 11 May 2017 11:33:07 -0500 Subject: [PATCH 08/51] adding repos to pom --- pom.xml | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 71f790b..5911d9e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,11 +7,41 @@ Widget Creator Parent Parent pom for widget creator project. - scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git - scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git - https://github.com/UW-Madison-DoIT/my-app-seed + scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git + scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git + https://github.com/UW-Madison-DoIT/widget-creator HEAD + + + + myuw-public-releases + https://artifacts.doit.wisc.edu/artifactory/myuw-public-releases/ + + + myuw-public-snapshots + https://artifacts.doit.wisc.edu/artifactory/myuw-public-snapshots/ + + + + + + myuw-public-releases + https://artifacts.doit.wisc.edu/artifactory/myuw-public-releases/ + true + false + + + myuw-public-snapshots + https://artifacts.doit.wisc.edu/artifactory/myuw-public-snapshots/ + false + + true + always + + + + @@ -25,6 +55,16 @@ + + maven-war-plugin + + true + + + + maven-release-plugin + 2.4.2 + org.apache.maven.plugins maven-compiler-plugin From 1d95aa05930fef2ac68e2611d9a9c8823b94c1e7 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 11 May 2017 13:20:30 -0500 Subject: [PATCH 09/51] using relative path for templates --- widget-creator-war/src/main/webapp/js/override.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget-creator-war/src/main/webapp/js/override.js b/widget-creator-war/src/main/webapp/js/override.js index ce23f22..0cd9967 100644 --- a/widget-creator-war/src/main/webapp/js/override.js +++ b/widget-creator-war/src/main/webapp/js/override.js @@ -11,7 +11,7 @@ define(['angular'], function(angular) { 'fname': 'widget-creator', }, 'SERVICE_LOC': { - 'templates': '/json/starter-templates', + 'templates': 'json/starter-templates', 'widgetApi': { // For local testing, change to 'staticFeeds/' 'entry': 'data:application/json;base64,', From f73a23a9a9de55c664bcb4c5afe8c5e1fcb59316 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 11 May 2017 11:34:31 -0500 Subject: [PATCH 10/51] wip fixing custom widget (example wiscard) --- .../webapp/my-app/view-home/controllers.js | 18 +++++++++++------- .../webapp/my-app/view-home/view-home.html | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js index facdf06..dbc83c8 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js +++ b/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js @@ -82,24 +82,28 @@ define(['angular', 'jquery'], function (angular, $) { var prepareWidgetDataForDisplay = function(editable) { var preview = angular.copy(editable); var widgetConfig = parseJSON(editable.widgetConfig); - var jsonSample = parseJSON($scope.content); - if (widgetConfig && jsonSample) { + var sample = parseJSON(editable.sample); + + $scope.errorJSON = (!sample) ? 'JSON NOT VALID' : undefined; + $scope.errorConfigJSON = (!widgetConfig) ? 'JSON NOT VALID' : undefined; + + if (widgetConfig && (!editable.jsonSample || sample)) { preview.widgetConfig = widgetConfig; - preview.jsonSample = jsonSample + $scope.content = sample $scope.preview = wrapLayout(preview); - } else { - $scope.errorJSON = (!jsonSample) ? 'JSON NOT VALID' : undefined; - $scope.errorConfigJSON = (!widgetConfig) ? 'JSON NOT VALID' : undefined; } }; var widgetAsEditable = function(widget) { var editable = angular.copy(widget); + $scope.errorConfigJSON = undefined; if (!angular.isString(editable.widgetConfig)) { editable.widgetConfig = JSON.stringify(editable.widgetConfig); } + $scope.errorJSON = undefined; if (editable.jsonSample) { - $scope.content = JSON.stringify(editable.jsonSample) + editable.sample = JSON.stringify(editable.jsonSample); + $scope.content = editable.jsonSample; } return editable; } diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html index 2aecc1b..2952a50 100644 --- a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html +++ b/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html @@ -45,7 +45,7 @@

Choose a starter template

- + From e862475badc5d62df0d4f12046c5de4d8851f534 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Fri, 12 May 2017 10:37:26 -0500 Subject: [PATCH 11/51] condensing maven project --- .gitignore | 1 + package.json | 72 +++++++++++++++++++ pom.xml | 72 ++++++++----------- .../src => src}/main/webapp/WEB-INF/web.xml | 0 .../src => src}/main/webapp/js/config.js | 0 .../src => src}/main/webapp/js/override.js | 0 .../main/webapp/json/custom-template.json | 0 .../webapp/json/list-of-links-template.json | 0 .../main/webapp/json/rss-template.json | 0 .../json/search-with-links-template.json | 0 .../main/webapp/json/starter-templates.json | 0 .../src => src}/main/webapp/my-app/main.js | 0 .../src => src}/main/webapp/my-app/my-app.css | 0 .../webapp/my-app/view-home/controllers.js | 0 .../webapp/my-app/view-home/directives.js | 0 .../main/webapp/my-app/view-home/routes.js | 0 .../main/webapp/my-app/view-home/services.js | 0 .../webapp/my-app/view-home/view-home.html | 0 widget-creator-war/pom.xml | 32 --------- 19 files changed, 101 insertions(+), 76 deletions(-) create mode 100644 package.json rename {widget-creator-war/src => src}/main/webapp/WEB-INF/web.xml (100%) rename {widget-creator-war/src => src}/main/webapp/js/config.js (100%) rename {widget-creator-war/src => src}/main/webapp/js/override.js (100%) rename {widget-creator-war/src => src}/main/webapp/json/custom-template.json (100%) rename {widget-creator-war/src => src}/main/webapp/json/list-of-links-template.json (100%) rename {widget-creator-war/src => src}/main/webapp/json/rss-template.json (100%) rename {widget-creator-war/src => src}/main/webapp/json/search-with-links-template.json (100%) rename {widget-creator-war/src => src}/main/webapp/json/starter-templates.json (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/main.js (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/my-app.css (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/view-home/controllers.js (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/view-home/directives.js (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/view-home/routes.js (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/view-home/services.js (100%) rename {widget-creator-war/src => src}/main/webapp/my-app/view-home/view-home.html (100%) delete mode 100644 widget-creator-war/pom.xml diff --git a/.gitignore b/.gitignore index 927903c..3863302 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ overlays target *.iml +node_modules diff --git a/package.json b/package.json new file mode 100644 index 0000000..0204f25 --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "name": "widget-creator", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "karma start widget-creator/target/karma.conf.js --single-run", + "lint-js": "eslint --ext js --ext json --ext md . --ignore-path .gitignore --ignore-pattern angularjs-portal-mock-portal" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/UW-Madison-DoIT/widget-creator.git" + }, + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/UW-Madison-DoIT/widget-creator/issues" + }, + "homepage": "https://github.com/UW-Madison-DoIT/widget-creator#readme", + "devDependencies": { + "eslint": "^3.17.1", + "eslint-config-angular": "^0.5.0", + "eslint-config-google": "^0.7.1", + "eslint-git-changes": "^2.0.0", + "eslint-plugin-angular": "^1.6.2", + "eslint-plugin-compat": "^1.0.2", + "eslint-plugin-jasmine": "^2.2.0", + "eslint-plugin-json": "^1.2.0" + }, + "eslintConfig": { + "root": true, + "parserOptions": { + "ecmaVersion": 5 + }, + "env": { + "browser": true, + "jasmine": true, + "amd": true + }, + "plugins": [ + "angular", + "compat", + "jasmine", + "json" + ], + "extends": [ + "eslint:recommended", + "google", + "angular", + "plugin:jasmine/recommended" + ], + "rules": { + "angular/di": [ + "warn", + "array" + ], + "angular/controller-as": "off", + "compat/compat": "error", + "arrow-parens": "off", + "constructor-super": "off", + "generator-star-spacing": "off", + "no-new-symbol": "off", + "no-this-before-super": "off", + "no-invalid-this": "off", + "no-var": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "valid-jsdoc": "warn", + "rest-spread-spacing": "off", + "yield-star-spacing": "off" + } + } +} diff --git a/pom.xml b/pom.xml index 5911d9e..a22d8a7 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,11 @@ - + 4.0.0 edu.wisc.my.app widget-creator - 0.0.1-SNAPSHOT - pom - Widget Creator Parent - Parent pom for widget creator project. + 1.0.0-SNAPSHOT + Widget Creator War + Web application for uportal-app-framework widget creator. + war scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git @@ -42,45 +42,32 @@ - - - - edu.wisc.my.apps - uw-frame - 4.1.1-SNAPSHOT - war - - - + + + edu.wisc.my.apps + uw-frame + 4.1.1-SNAPSHOT + war + + + - - - - maven-war-plugin - - true - - - - maven-release-plugin - 2.4.2 - - - org.apache.maven.plugins - maven-compiler-plugin - 3.2 - - - org.eclipse.jetty - jetty-maven-plugin - 9.2.8.v20150217 - - - + widget-creator + + maven-war-plugin + + true + + + + maven-release-plugin + 2.4.2 + org.apache.maven.plugins maven-compiler-plugin + 3.2 1.8 1.8 @@ -89,14 +76,11 @@ org.eclipse.jetty jetty-maven-plugin + 9.2.8.v20150217 - true + false - - - widget-creator-war - diff --git a/widget-creator-war/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from widget-creator-war/src/main/webapp/WEB-INF/web.xml rename to src/main/webapp/WEB-INF/web.xml diff --git a/widget-creator-war/src/main/webapp/js/config.js b/src/main/webapp/js/config.js similarity index 100% rename from widget-creator-war/src/main/webapp/js/config.js rename to src/main/webapp/js/config.js diff --git a/widget-creator-war/src/main/webapp/js/override.js b/src/main/webapp/js/override.js similarity index 100% rename from widget-creator-war/src/main/webapp/js/override.js rename to src/main/webapp/js/override.js diff --git a/widget-creator-war/src/main/webapp/json/custom-template.json b/src/main/webapp/json/custom-template.json similarity index 100% rename from widget-creator-war/src/main/webapp/json/custom-template.json rename to src/main/webapp/json/custom-template.json diff --git a/widget-creator-war/src/main/webapp/json/list-of-links-template.json b/src/main/webapp/json/list-of-links-template.json similarity index 100% rename from widget-creator-war/src/main/webapp/json/list-of-links-template.json rename to src/main/webapp/json/list-of-links-template.json diff --git a/widget-creator-war/src/main/webapp/json/rss-template.json b/src/main/webapp/json/rss-template.json similarity index 100% rename from widget-creator-war/src/main/webapp/json/rss-template.json rename to src/main/webapp/json/rss-template.json diff --git a/widget-creator-war/src/main/webapp/json/search-with-links-template.json b/src/main/webapp/json/search-with-links-template.json similarity index 100% rename from widget-creator-war/src/main/webapp/json/search-with-links-template.json rename to src/main/webapp/json/search-with-links-template.json diff --git a/widget-creator-war/src/main/webapp/json/starter-templates.json b/src/main/webapp/json/starter-templates.json similarity index 100% rename from widget-creator-war/src/main/webapp/json/starter-templates.json rename to src/main/webapp/json/starter-templates.json diff --git a/widget-creator-war/src/main/webapp/my-app/main.js b/src/main/webapp/my-app/main.js similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/main.js rename to src/main/webapp/my-app/main.js diff --git a/widget-creator-war/src/main/webapp/my-app/my-app.css b/src/main/webapp/my-app/my-app.css similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/my-app.css rename to src/main/webapp/my-app/my-app.css diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/view-home/controllers.js rename to src/main/webapp/my-app/view-home/controllers.js diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/directives.js b/src/main/webapp/my-app/view-home/directives.js similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/view-home/directives.js rename to src/main/webapp/my-app/view-home/directives.js diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/routes.js b/src/main/webapp/my-app/view-home/routes.js similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/view-home/routes.js rename to src/main/webapp/my-app/view-home/routes.js diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/view-home/services.js rename to src/main/webapp/my-app/view-home/services.js diff --git a/widget-creator-war/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html similarity index 100% rename from widget-creator-war/src/main/webapp/my-app/view-home/view-home.html rename to src/main/webapp/my-app/view-home/view-home.html diff --git a/widget-creator-war/pom.xml b/widget-creator-war/pom.xml deleted file mode 100644 index 9659af8..0000000 --- a/widget-creator-war/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - 4.0.0 - - edu.wisc.my.app - widget-creator - 0.0.1-SNAPSHOT - - widget-creator-war - Widget Creator War - Web application for uportal-app-framework widget creator. - war - - - - edu.wisc.my.apps - uw-frame - war - - - - - - - org.eclipse.jetty - jetty-maven-plugin - - false - - - - - From 529db9375a96e9b38bd0008e5a054cc20497a459 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Fri, 12 May 2017 13:11:08 -0500 Subject: [PATCH 12/51] fixing eslint rules --- package.json | 32 +++++- src/main/webapp/js/config.js | 5 +- src/main/webapp/js/override.js | 42 +++---- src/main/webapp/my-app/main.js | 48 ++++---- .../webapp/my-app/view-home/controllers.js | 104 +++++++++--------- .../webapp/my-app/view-home/directives.js | 4 +- src/main/webapp/my-app/view-home/routes.js | 7 +- src/main/webapp/my-app/view-home/services.js | 37 +++---- 8 files changed, 148 insertions(+), 131 deletions(-) diff --git a/package.json b/package.json index 0204f25..cb358c2 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,14 @@ "description": "", "main": "index.js", "scripts": { - "test": "karma start widget-creator/target/karma.conf.js --single-run", - "lint-js": "eslint --ext js --ext json --ext md . --ignore-path .gitignore --ignore-pattern angularjs-portal-mock-portal" + "build:pre": "mvn clean package", + "build:test": "karma start target/widget-creator/karma.conf.js --single-run", + "build:lint-js": "eslint --ext js --ext json --ext md . --ignore-path .gitignore", + "build": "npm run build:pre && npm run build:test && npm run build:lint-js", + "test": "npm run build:pre && npm run build:test", + "lint-js": "npm run build:pre && npm run build:lint-js", + "dev": "npm run build:pre && mvn jetty:run", + "precommit": "eslint-git-changes" }, "repository": { "type": "git", @@ -24,7 +30,21 @@ "eslint-plugin-angular": "^1.6.2", "eslint-plugin-compat": "^1.0.2", "eslint-plugin-jasmine": "^2.2.0", - "eslint-plugin-json": "^1.2.0" + "eslint-plugin-json": "^1.2.0", + "eslint-plugin-promise": "^3.5.0", + "husky": "^0.13.3", + "jasmine-core": "^2.3.4", + "karma": "^1.5.0", + "karma-chrome-launcher": "^2.0.0", + "karma-html-reporter": "^0.2.4", + "karma-htmlfile-reporter": "^0.3.5", + "karma-jasmine": "^0.3.5", + "karma-jasmine-html-reporter": "^0.2.2", + "karma-phantomjs-launcher": "^1.0.4", + "karma-requirejs": "^1.1.0", + "karma-read-json": "^1.1.0", + "phantomjs": "^2.1.7", + "requirejs": "^2.1.18" }, "eslintConfig": { "root": true, @@ -40,13 +60,15 @@ "angular", "compat", "jasmine", - "json" + "json", + "promise" ], "extends": [ "eslint:recommended", "google", "angular", - "plugin:jasmine/recommended" + "plugin:jasmine/recommended", + "plugin:promise/recommended" ], "rules": { "angular/di": [ diff --git a/src/main/webapp/js/config.js b/src/main/webapp/js/config.js index 28a4db8..856eb71 100644 --- a/src/main/webapp/js/config.js +++ b/src/main/webapp/js/config.js @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ var config = { - gaID : '' -} + 'gaID': '', +}; diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 0cd9967..40a9056 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -1,26 +1,20 @@ define(['angular'], function(angular) { - - /*Keep in sync with docs/mardown/configuration.md*/ - - var config = angular.module('override', []); - config - //see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto - .constant('OVERRIDE', { - 'NAMES': { - 'title': 'Widget Creator', - 'fname': 'widget-creator', - }, - 'SERVICE_LOC': { - 'templates': 'json/starter-templates', - 'widgetApi': { - // For local testing, change to 'staticFeeds/' - 'entry': 'data:application/json;base64,', - 'entrySuffix': '', - 'entries': '/portal/api/marketplace/entries.json', - }, - } - }); - - return config; - + /* Keep in sync with docs/mardown/configuration.md */ + return angular.module('override', []) + // see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto + .constant('OVERRIDE', { + 'NAMES': { + 'title': 'Widget Creator', + 'fname': 'widget-creator', + }, + 'SERVICE_LOC': { + 'templates': 'json/starter-templates', + 'widgetApi': { + // For local testing, change to 'staticFeeds/' + 'entry': 'data:application/json;base64,', + 'entrySuffix': '', + 'entries': '/portal/api/marketplace/entries.json', + }, + }, + }); }); diff --git a/src/main/webapp/my-app/main.js b/src/main/webapp/my-app/main.js index ec3f417..60cf45b 100644 --- a/src/main/webapp/my-app/main.js +++ b/src/main/webapp/my-app/main.js @@ -1,7 +1,7 @@ define([ 'angular', 'require', - './view-home/routes', //add all the paths to your routes here + './view-home/routes', // add all the paths to your routes here 'portal/settings/routes', // example pulling in portal module routes 'portal/about/route', // Nice about page for your application 'portal/main/routes', @@ -10,12 +10,18 @@ define([ 'ngRoute', 'ngSanitize', 'ngStorage', - './view-home/controllers', //add all your paths to your other js files here + './view-home/controllers', // add all your paths to your other js files here './view-home/directives', - './view-home/services' -], function(angular, require, homeRoutes, settingsRoutes, aboutRoute, mainRoutes) { //notice each route file is now an object - - var app = angular.module('my-app', [ + './view-home/services', + ], function( + angular, + require, + homeRoutes, + settingsRoutes, + aboutRoute, + mainRoutes + ) { // notice each route file is now an object + return angular.module('my-app', [ 'app-config', 'my-app.view-home.controllers', // add in your modules here 'my-app.view-home.directives', @@ -23,24 +29,18 @@ define([ 'ngRoute', 'ngSanitize', 'ngStorage', - 'portal' - ]); - - // TODO: Think of a more extensible approach such that frame and app can each manage their own routing without conflict - app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { + 'portal', + ]) + .config(['$routeProvider', '$locationProvider', + function($routeProvider, $locationProvider) { $locationProvider.html5Mode(true); - // IMPORTANT: Keep theses paths in sync with web.xml for html5mode - $routeProvider. - when('/home', homeRoutes.home). //use your route object to get the templateurl - when('/settings', settingsRoutes.betaSettings). - when('/user-settings', settingsRoutes.userSettings). - when('/about', aboutRoute). - when('/access-denied', mainRoutes.accessDenied). - otherwise({ redirectTo : '/home'}); - - + // IMPORTANT: Keep theses paths in sync with web.xml for html5mode + $routeProvider + .when('/home', homeRoutes.home) + .when('/settings', settingsRoutes.betaSettings) + .when('/user-settings', settingsRoutes.userSettings) + .when('/about', aboutRoute) + .when('/access-denied', mainRoutes.accessDenied) + .otherwise({'redirectTo': '/home'}); }]); - - return app; - }); diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index dbc83c8..40063a5 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -1,21 +1,20 @@ 'use strict'; -define(['angular', 'jquery'], function (angular, $) { - - var app = angular.module('my-app.view-home.controllers', []); - +define(['angular', 'jquery'], function(angular, $) { + return angular.module('my-app.view-home.controllers', []) // WIDGET CREATOR controller - app.controller('WidgetCreatorController', ['$scope', '$route', '$log', 'widgetCreatorService', function ($scope, $route, $log, widgetCreatorService) { - + .controller('WidgetCreatorController', [ + '$scope', '$route', '$log', 'widgetCreatorService', + function($scope, $route, $log, widgetCreatorService) { var starterTemplates = []; - /*------------------*/ + /* ---------------- */ /* Bindable members */ - /*------------------*/ + /* ---------------- */ $scope.templateOptions = [ - { "value": "search-with-links", "name": "Search with links" }, - { "value": "list-of-links", "name": "List of links" }, - { "value": "rss", "name": "RSS widget" }, - { "value": "widget-creator", "name": "Custom" } + {'value': 'search-with-links', 'name': 'Search with links'}, + {'value': 'list-of-links', 'name': 'List of links'}, + {'value': 'rss', 'name': 'RSS widget'}, + {'value': 'widget-creator', 'name': 'Custom'}, ]; $scope.selectedTemplate = {}; $scope.content = {}; @@ -23,19 +22,19 @@ define(['angular', 'jquery'], function (angular, $) { $scope.errorJSON = undefined; $scope.errorConfigJSON = undefined; - /*-----------------*/ + /* --------------- */ /* Scope functions */ - /*-----------------*/ + /* --------------- */ // Reload widget preview - $scope.reload = function () { - prepareWidgetDataForDisplay($scope.widget); + $scope.reload = function() { + $scope.prepareWidgetDataForDisplay($scope.widget); }; // Clear widget configuration - $scope.clear = function () { + $scope.clear = function() { if (confirm('Are you sure, all your config will be cleared')) { - init(); + $scope.init(); } }; @@ -44,33 +43,32 @@ define(['angular', 'jquery'], function (angular, $) { // Set widget equal to starter template that matches the selected type angular.forEach(starterTemplates, function(value, key) { if ($scope.selectedTemplate.value == value.entry.layoutObject.type) { - $scope.widget = widgetAsEditable(value.entry.layoutObject); + $scope.widget = $scope.widgetAsEditable(value.entry.layoutObject); } }); - }; - var wrapLayout = function(preview) { + /* --------------- */ + /* Local functions */ + /* --------------- */ + + $scope.wrapLayout = function(preview) { var wrapped = { 'entry': { - 'layoutObject': preview - } + 'layoutObject': preview, + }, }; - return btoa(JSON.stringify(wrapped)); - } - - /*-----------------*/ - /* Local functions */ - /*-----------------*/ + return btoa(angular.toJson(wrapped)); + }; /** * Check if json is valid - * @param json - * @returns {boolean} + * @param {String} json the json to parse + * @return {Object|undefined} */ - var parseJSON = function parseJSON(json) { + $scope.parseJSON = function parseJSON(json) { try { - return JSON.parse(json); + return angular.fromJson(json); } catch (e) { return undefined; } @@ -78,49 +76,56 @@ define(['angular', 'jquery'], function (angular, $) { /** * Convert JSON objects to strings so they can be displayed in HTML + * @param {Object} editable The object used to store user edits */ - var prepareWidgetDataForDisplay = function(editable) { + $scope.prepareWidgetDataForDisplay = function(editable) { var preview = angular.copy(editable); - var widgetConfig = parseJSON(editable.widgetConfig); - var sample = parseJSON(editable.sample); + var widgetConfig = $scope.parseJSON(editable.widgetConfig); + var sample = $scope.parseJSON(editable.sample); $scope.errorJSON = (!sample) ? 'JSON NOT VALID' : undefined; $scope.errorConfigJSON = (!widgetConfig) ? 'JSON NOT VALID' : undefined; if (widgetConfig && (!editable.jsonSample || sample)) { preview.widgetConfig = widgetConfig; - $scope.content = sample - $scope.preview = wrapLayout(preview); + $scope.content = sample; + $scope.preview = $scope.wrapLayout(preview); } }; - var widgetAsEditable = function(widget) { + /** + * Takes a valid widget configuration and creates an user-editable version. + * @param {Object} widget widget configuration + * @return {Object} user-editable widget config + */ + $scope.widgetAsEditable = function(widget) { var editable = angular.copy(widget); $scope.errorConfigJSON = undefined; if (!angular.isString(editable.widgetConfig)) { - editable.widgetConfig = JSON.stringify(editable.widgetConfig); + editable.widgetConfig = angular.toJson(editable.widgetConfig); } $scope.errorJSON = undefined; if (editable.jsonSample) { - editable.sample = JSON.stringify(editable.jsonSample); + editable.sample = angular.toJson(editable.jsonSample); $scope.content = editable.jsonSample; } return editable; - } + }; /** * Initialize widget creator + * @return {Promise} starter templates */ - var init = function() { + $scope.init = function() { return widgetCreatorService.getStarterTemplates() .then(function(templates) { starterTemplates = templates; $log.log('Got starter templates'); if (templates[0].entry.layoutObject) { - // Set default widget type - $scope.widget = widgetAsEditable(templates[0].entry.layoutObject); - prepareWidgetDataForDisplay($scope.widget); + $scope.widget = $scope.widgetAsEditable( + templates[0].entry.layoutObject); + $scope.prepareWidgetDataForDisplay($scope.widget); // Set selected template angular.forEach($scope.templateOptions, function(value, key) { @@ -128,15 +133,14 @@ define(['angular', 'jquery'], function (angular, $) { $scope.selectedTemplate = value; } }); - } - }) + return templates; + }); }; - init().catch(function(error) { + $scope.init().catch(function(error) { $log.warn('WidgetCreatorController couldn\'t get starter templates'); $log.error(error); }); }]); - }); diff --git a/src/main/webapp/my-app/view-home/directives.js b/src/main/webapp/my-app/view-home/directives.js index c9d4f3e..b684968 100644 --- a/src/main/webapp/my-app/view-home/directives.js +++ b/src/main/webapp/my-app/view-home/directives.js @@ -9,7 +9,8 @@ define(['angular', 'require'], function(angular, require) { scope: { fname: '@', }, - templateUrl: require.toUrl('../../portal/widgets/partials/widget-card.html'), + templateUrl: require.toUrl( + '../../portal/widgets/partials/widget-card.html'), controller: 'WidgetCardController', link: function(scope, element, attrs) { scope.$watch('fname', function(newValue, oldValue) { @@ -20,5 +21,4 @@ define(['angular', 'require'], function(angular, require) { }, }; }); - }); diff --git a/src/main/webapp/my-app/view-home/routes.js b/src/main/webapp/my-app/view-home/routes.js index a9c1abb..0b3d4f1 100644 --- a/src/main/webapp/my-app/view-home/routes.js +++ b/src/main/webapp/my-app/view-home/routes.js @@ -1,6 +1,5 @@ -define(['require'], function(require){ - +define(['require'], function(require) { return { - home : {templateUrl: require.toUrl('./view-home.html')} - } + 'home': {templateUrl: require.toUrl('./view-home.html')}, + }; }); diff --git a/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js index d12330d..a8fd2e1 100644 --- a/src/main/webapp/my-app/view-home/services.js +++ b/src/main/webapp/my-app/view-home/services.js @@ -1,26 +1,23 @@ 'use strict'; define(['angular', 'jquery'], function(angular, $) { - return angular.module('my-app.view-home.services', []) + .factory('widgetCreatorService', [ + '$log', '$localStorage', '$http', 'SERVICE_LOC', + function($log, $localStorage, $http, SERVICE_LOC) { + var getStarterTemplates = function() { + return $http.get(SERVICE_LOC.templates + '.json') + .then(function(result) { + return result.data.templates; + }) + .catch(function(error) { + $log.warn('Error getting starter templates'); + $log.error(error); + }); + }; - .factory('widgetCreatorService', ['$log', '$localStorage', '$http', 'SERVICE_LOC', function($log, $localStorage, $http, SERVICE_LOC) { - - var getStarterTemplates = function() { - return $http.get(SERVICE_LOC.templates + '.json') - .then(function (result) { - if (result.data.templates != undefined) { - return result.data.templates; - } - }) - .catch(function (error) { - $log.warn('Error getting starter templates'); - $log.error(error); - }); - }; - - return { - getStarterTemplates: getStarterTemplates - }; - }]); + return { + 'getStarterTemplates': getStarterTemplates, + }; + }]); }); From b5b9c67a6fbb040ce012c7c7a8bde3f31ca03dd5 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Fri, 12 May 2017 13:12:30 -0500 Subject: [PATCH 13/51] ignore test_out --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3863302..951e6a6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ overlays target *.iml node_modules +test_out From 0984625baddd87e687a4c204646e807bfc00d118 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Fri, 12 May 2017 14:40:20 -0500 Subject: [PATCH 14/51] adding package description --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb358c2..a09f51d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "widget-creator", "version": "1.0.0", - "description": "", + "description": "Web application for uportal-app-framework widget creator.", "main": "index.js", "scripts": { "build:pre": "mvn clean package", From 1fd130ec26f46bfafe28c5f007ccf6e9e3a63402 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Mon, 15 May 2017 08:26:28 -0500 Subject: [PATCH 15/51] adding oss sonatype repo --- pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pom.xml b/pom.xml index a22d8a7..cbefafe 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,15 @@ always + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + false + + true + always + + From d6f479bb007df3151b7a0684fa7f8ac4d0780fec Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Tue, 16 May 2017 10:44:10 -0500 Subject: [PATCH 16/51] adding preliminary tests --- package.json | 4 +- src/main/webapp/karma.conf.js | 58 +++++++++++++++++++ .../webapp/my-app/view-home/controllers.js | 6 +- src/main/webapp/my-app/view-home/services.js | 6 +- .../my-app/view-home/spec/view-home-spec.js | 46 +++++++++++++++ 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 src/main/webapp/karma.conf.js create mode 100644 src/main/webapp/my-app/view-home/spec/view-home-spec.js diff --git a/package.json b/package.json index a09f51d..96f8b07 100644 --- a/package.json +++ b/package.json @@ -40,9 +40,11 @@ "karma-htmlfile-reporter": "^0.3.5", "karma-jasmine": "^0.3.5", "karma-jasmine-html-reporter": "^0.2.2", + "karma-ng-html2js-preprocessor": "^1.0.0", "karma-phantomjs-launcher": "^1.0.4", - "karma-requirejs": "^1.1.0", "karma-read-json": "^1.1.0", + "karma-requirejs": "^1.1.0", + "karma-requirejs-wrapper-preprocessor": "0.0.1", "phantomjs": "^2.1.7", "requirejs": "^2.1.18" }, diff --git a/src/main/webapp/karma.conf.js b/src/main/webapp/karma.conf.js new file mode 100644 index 0000000..a093c9a --- /dev/null +++ b/src/main/webapp/karma.conf.js @@ -0,0 +1,58 @@ +/* eslint-env node */ +module.exports = function(config) { + config.set({ + + basePath: './', + + files: [ + // main.js will handle finding and loading the tests, + // by way of RequireJS. + 'test/main.js', + '../../node_modules/karma-read-json/karma-read-json.js', + // all other files need to be listed in order to be hosted and + // available, but excluded so that they are not run automatically. + {pattern: './**', included: false}, + ], + + preprocessors: { + 'portal/**/*.js': 'coverage', + 'my-app/**/*.js': 'coverage', + }, + + autoWatch: true, + + frameworks: ['jasmine', 'requirejs'], + + browsers: ['PhantomJS'], // or 'Chrome' + + plugins: [ + 'karma-htmlfile-reporter', + 'karma-chrome-launcher', + 'karma-phantomjs-launcher', + 'karma-jasmine', + 'karma-requirejs', + 'karma-coverage', + 'karma-coveralls', + ], + + reporters: ['dots', 'html', 'coverage', 'coveralls'], + + htmlReporter: { + outputFile: 'test_out/units.html', + }, + + junitReporter: { + outputFile: 'test_out/unit.xml', + suite: 'unit', + }, + + coverageReporter: { + // lcov or lcovonly are required for generating lcov.info files + type: 'lcov', + dir: 'coverage/', + }, + + colors: true, + + }); +}; diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index 40063a5..3d791f3 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -1,11 +1,11 @@ 'use strict'; -define(['angular', 'jquery'], function(angular, $) { +define(['angular'], function(angular) { return angular.module('my-app.view-home.controllers', []) // WIDGET CREATOR controller .controller('WidgetCreatorController', [ - '$scope', '$route', '$log', 'widgetCreatorService', - function($scope, $route, $log, widgetCreatorService) { + '$scope', '$log', 'widgetCreatorService', + function($scope, $log, widgetCreatorService) { var starterTemplates = []; /* ---------------- */ /* Bindable members */ diff --git a/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js index a8fd2e1..fd8d7fd 100644 --- a/src/main/webapp/my-app/view-home/services.js +++ b/src/main/webapp/my-app/view-home/services.js @@ -1,10 +1,10 @@ 'use strict'; -define(['angular', 'jquery'], function(angular, $) { +define(['angular'], function(angular) { return angular.module('my-app.view-home.services', []) .factory('widgetCreatorService', [ - '$log', '$localStorage', '$http', 'SERVICE_LOC', - function($log, $localStorage, $http, SERVICE_LOC) { + '$log', '$http', 'SERVICE_LOC', + function($log, $http, SERVICE_LOC) { var getStarterTemplates = function() { return $http.get(SERVICE_LOC.templates + '.json') .then(function(result) { diff --git a/src/main/webapp/my-app/view-home/spec/view-home-spec.js b/src/main/webapp/my-app/view-home/spec/view-home-spec.js new file mode 100644 index 0000000..20048a9 --- /dev/null +++ b/src/main/webapp/my-app/view-home/spec/view-home-spec.js @@ -0,0 +1,46 @@ +'use strict'; +/* eslint-env node */ +/* global inject readJSON */ +define(['angular-mocks', 'my-app'], function() { + describe('WidgetCreatorController', function() { + var scope; + var deferred; + var service; + var templateURL; + var templates; + + beforeEach(function() { + module('my-app'); + }); + + beforeEach(inject(function( + _$controller_, _$q_, _$rootScope_, _$templateCache_, + _widgetCreatorService_, _SERVICE_LOC_) { + scope = _$rootScope_.$new(); + templateURL = _SERVICE_LOC_.templates + '.json'; + templates = readJSON(templateURL).templates; + spyOn(_$templateCache_, 'get').and.callFake(function(path) { + return '
'; + }); + service = _widgetCreatorService_; + deferred = _$q_.defer(); + spyOn(service, 'getStarterTemplates') + .and.returnValue(deferred.promise); + _$controller_('WidgetCreatorController', { + '$scope': scope, + 'widgetCreatorService': service, + }); + deferred.resolve(templates); + scope.$apply(); + })); + + it('should set selectedTemplate in scope', function() { + expect(scope.selectedTemplate).toBeTruthy(); + expect(scope.selectedTemplate).not.toEqual({}); + }); + + it('should set the preview widget configuration', function() { + expect(scope.preview).toBeTruthy(); + }); + }); +}); From 379826e3a4847fee58ffd365b1a038cecbd8da34 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Tue, 16 May 2017 10:50:46 -0500 Subject: [PATCH 17/51] fixing packages --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 96f8b07..cb73afe 100644 --- a/package.json +++ b/package.json @@ -36,15 +36,15 @@ "jasmine-core": "^2.3.4", "karma": "^1.5.0", "karma-chrome-launcher": "^2.0.0", + "karma-coverage": "^1.1.1", + "karma-coveralls": "^1.1.2", "karma-html-reporter": "^0.2.4", "karma-htmlfile-reporter": "^0.3.5", "karma-jasmine": "^0.3.5", "karma-jasmine-html-reporter": "^0.2.2", - "karma-ng-html2js-preprocessor": "^1.0.0", "karma-phantomjs-launcher": "^1.0.4", "karma-read-json": "^1.1.0", "karma-requirejs": "^1.1.0", - "karma-requirejs-wrapper-preprocessor": "0.0.1", "phantomjs": "^2.1.7", "requirejs": "^2.1.18" }, From 915564e2d8c67d2636642a011d4368b88857e0f6 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Mon, 22 May 2017 14:23:07 -0500 Subject: [PATCH 18/51] using a Data URI to populate widget content (#9) --- src/main/webapp/my-app/view-home/controllers.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index 3d791f3..5d63216 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -17,7 +17,6 @@ define(['angular'], function(angular) { {'value': 'widget-creator', 'name': 'Custom'}, ]; $scope.selectedTemplate = {}; - $scope.content = {}; $scope.preview = undefined; $scope.errorJSON = undefined; $scope.errorConfigJSON = undefined; @@ -88,7 +87,10 @@ define(['angular'], function(angular) { if (widgetConfig && (!editable.jsonSample || sample)) { preview.widgetConfig = widgetConfig; - $scope.content = sample; + if (sample) { + preview.widgetURL = 'data:application/json;base64,' + + btoa(angular.toJson(sample)); + } $scope.preview = $scope.wrapLayout(preview); } }; @@ -107,7 +109,6 @@ define(['angular'], function(angular) { $scope.errorJSON = undefined; if (editable.jsonSample) { editable.sample = angular.toJson(editable.jsonSample); - $scope.content = editable.jsonSample; } return editable; }; From 2344db656f9e189352bceaf37874ed43e8766b50 Mon Sep 17 00:00:00 2001 From: Timothy A Vertein Date: Tue, 23 May 2017 16:30:48 -0500 Subject: [PATCH 19/51] Fixes bug where you cant change launch url (#11) --- src/main/webapp/my-app/my-app.css | 2 +- src/main/webapp/my-app/view-home/view-home.html | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/my-app/my-app.css b/src/main/webapp/my-app/my-app.css index 0374db4..7320162 100644 --- a/src/main/webapp/my-app/my-app.css +++ b/src/main/webapp/my-app/my-app.css @@ -6,7 +6,7 @@ padding-bottom: 20px; } -.widget-creator widget { +.widget-creator preview-widget { width: 300px; } diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index 2952a50..6a6f7be 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -55,7 +55,12 @@

Choose a starter template

- + + + + + + From 678244621522684430a8d6e4d05f453ae21910ac Mon Sep 17 00:00:00 2001 From: Timothy A Vertein Date: Tue, 23 May 2017 16:31:19 -0500 Subject: [PATCH 20/51] Adds exercises to widget creator (#10) --- .gitignore | 2 + docs/Gemfile | 7 ++ docs/README.md | 22 +++++ docs/_config.yml | 9 ++ docs/_includes/footer-aside.html | 24 ++++++ docs/_includes/footer.html | 4 + docs/_layouts/default.html | 55 ++++++++++++ docs/assets/css/style.scss | 127 ++++++++++++++++++++++++++++ docs/customWidgetExercise.md | 58 +++++++++++++ docs/img/octocat-small.png | Bin 0 -> 357 bytes docs/img/selectorDropDown.png | Bin 0 -> 35074 bytes docs/listOfLinksWidgetExercise.md | 134 ++++++++++++++++++++++++++++++ docs/rssWidgetExercise.md | 32 +++++++ 13 files changed, 474 insertions(+) create mode 100644 docs/Gemfile create mode 100644 docs/README.md create mode 100644 docs/_config.yml create mode 100644 docs/_includes/footer-aside.html create mode 100644 docs/_includes/footer.html create mode 100644 docs/_layouts/default.html create mode 100644 docs/assets/css/style.scss create mode 100644 docs/customWidgetExercise.md create mode 100644 docs/img/octocat-small.png create mode 100644 docs/img/selectorDropDown.png create mode 100644 docs/listOfLinksWidgetExercise.md create mode 100644 docs/rssWidgetExercise.md diff --git a/.gitignore b/.gitignore index 951e6a6..9cf63e0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ target *.iml node_modules test_out +docs/Gemfile.lock +docs/_site/ diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..c868308 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'github-pages', group: :jekyll_plugins +gem 'jekyll-default-layout' +gem 'jekyll-optional-front-matter' +gem 'jekyll-readme-index' +gem 'jekyll-titles-from-headings' diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ecf6dc3 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,22 @@ +Widget Creator is a web application that allows you to quickly create and test +widgets. Widgets are used in +[uPortal-App-Frameworks applications](https://github.com/UW-Madison-DoIT/uw-frame) +and come complete with their own +[documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) on how +to configure and deploy. This application allows a sandbox for rapid +development. UW-Madison hosts a +[deployed instance](https://test.my.wisc.edu/widget-creator) for campus +developers to use. + +# How to run locally +```bash +mvn jetty:run +``` + + +# Exercises +Complete some exercises that will give you some experience with creating widgets + +* [List of Links Widget Exercise](listOfLinksWidgetExercise.md) +* [RSS Widget Exercise](rssWidgetExercise.md) +* [Custom Widget Exercise](customWidgetExercise.md) \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..a6efb81 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,9 @@ +gems: + - github-pages + - jekyll-default-layout + - jekyll-optional-front-matter + - jekyll-readme-index + - jekyll-titles-from-headings + +theme: jekyll-theme-minimal + diff --git a/docs/_includes/footer-aside.html b/docs/_includes/footer-aside.html new file mode 100644 index 0000000..3d9cbeb --- /dev/null +++ b/docs/_includes/footer-aside.html @@ -0,0 +1,24 @@ + diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html new file mode 100644 index 0000000..725fa17 --- /dev/null +++ b/docs/_includes/footer.html @@ -0,0 +1,4 @@ +{% if site.github.is_project_page %} +

This project is maintained by {{ site.github.owner_name }}

+{% endif %} +

Hosted on GitHub Pages — Base theme by orderedlist

diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 0000000..4059438 --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,55 @@ + + + + + + Docs: {{ site.title | default: site.github.repository_name }} by {{ site.github.owner_name }} + + + + + + +
+

+ {{ site.title | default: site.github.repository_name }} +

+

{{ site.description | default: site.github.project_tagline }}

+ + {% if site.github.is_project_page %} +

+ + + View on GitHub + +

+ {% endif %} + +
+
+ + {{ content }} + +
+
+ {% include footer-aside.html %} + {% include footer.html %} +
+ + + +{% if site.google_analytics %} + +{% endif %} + + diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss new file mode 100644 index 0000000..9ec81c9 --- /dev/null +++ b/docs/assets/css/style.scss @@ -0,0 +1,127 @@ +--- +--- + +@import "{{ site.theme }}"; + +.wrapper { + width: auto; +} + +header { + left: 0; + background: #444; + padding: 24px 24px 14px 70px; + h1 { + a { + color: #fff; + &:hover { + color: #fff; + } + } + } + p { + color: #e5e5e5; + margin-bottom: 10px; + &.view { + margin-bottom: 0; + } + } + a.button { + box-shadow: 0 2px 5px 0 rgba(0,0,0,.26); + background: #39c; + color: #fff; + display: inline-block; + position: relative; + cursor: pointer; + min-height: 36px; + min-width: 88px; + line-height: 36px; + text-align: center; + border-radius: 2px; + box-sizing: border-box; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + outline: none; + border: 0; + padding: 0 8px; + margin: 6px 8px 6px 0; + white-space: nowrap; + font-weight: 500; + text-decoration: none; + overflow: hidden; + -webkit-transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1); + transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1); + &:hover { + background: #069; + } + img { + vertical-align: middle; + margin: 0 4px 2px 0; + } + } +} + +section { + border-bottom: none; + width: auto; + h2 { + font-size: 24px; + font-weight: 300; + border-bottom: 1px solid #e5e5e5; + padding-bottom: 6px; + } + h4 { + margin-bottom: 8px; + font-weight: 300; + border-bottom: #e5e5e5 1px solid; + padding-bottom: 4px; + } +} + +aside { + margin-bottom: 36px; + h5 { + font-size: 14px; + font-weight: 300; + border-bottom: #e5e5e5 1px solid; + padding-bottom: 4px; + margin-top: 12px; + } + ul { + padding-left: 20px; + -webkit-padding-start: 20px; + } +} + +footer { + top: 270px; + bottom: auto; + overflow-y: scroll; + p.owner { + margin: 0; + } +} + +@media (min-width: 960px) { + section { + float: left; + margin-left: 360px; + border-bottom: #e5e5e5 1px solid; + } + footer { + left: 0; + padding-left: 70px; + } +} + +@media (max-width: 960px) { + body { + margin: 0; + padding: 40px 40px 40px 0; + header, section, footer { + padding-left: 40px; + } + } +} diff --git a/docs/customWidgetExercise.md b/docs/customWidgetExercise.md new file mode 100644 index 0000000..90dfdd5 --- /dev/null +++ b/docs/customWidgetExercise.md @@ -0,0 +1,58 @@ +The +[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) +has more information about configuration options and more technical details. + +Choose `Custom Widget` from the starter templates. + +![Image of the template dropdown](img/selectorDropDown.png) + +Let’s create a campus food account balance widget. + +Select `Custom` from the drop down starter template selector + +Type into title +``` +Food Account Balance +``` + +Type as a description +``` +Check your balance and get some money saving tips +``` + +Custom widgets are custom because you supply your own html markup. Angular is +available to use. Use this as an example. + +```html +
+
+ + + {{content.data.food.balance | currency:"$":2}} +
+
+ + +
+
+ + +
+
+Manage my food account + +``` + +In widget URL JSON sample type this + +```json +{"status":200,"data":{"food": {"balance":25.73}}} +``` + +Click update and see your widget in action. + +Change the styling and the JSON to try different things. diff --git a/docs/img/octocat-small.png b/docs/img/octocat-small.png new file mode 100644 index 0000000000000000000000000000000000000000..57c1e44f9b67d2dcbbdd1a7e0f2c24549c043799 GIT binary patch literal 357 zcmV-r0h<1aP)|_uU`DGt*!YlC@Am|DD>an&JK*_ z<>mi__UCKux;y>4Pqor7j|)IU*M9Gw z-IGbu2m_ZdUGO1GBT$h55cdP|c_4ld#Or}LA6*>)0_L))J+G2e00000NkvXXu0mjf DP-vTT literal 0 HcmV?d00001 diff --git a/docs/img/selectorDropDown.png b/docs/img/selectorDropDown.png new file mode 100644 index 0000000000000000000000000000000000000000..006e1f3a0745ad74ad3f01d7c5db76792da28ad6 GIT binary patch literal 35074 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
    ~Irj3SJFR0#S!84CoRX%kDiVD}%VkF?k9ycv9cq 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%0Aw16ylXlu94}F#i4SPEfS@aImSx-b!ui=Sz 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 CX^m+B literal 0 HcmV?d00001 diff --git a/docs/listOfLinksWidgetExercise.md b/docs/listOfLinksWidgetExercise.md new file mode 100644 index 0000000..e6091ae --- /dev/null +++ b/docs/listOfLinksWidgetExercise.md @@ -0,0 +1,134 @@ +The +[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) +has more information about configuration options and more technical details. + +In the starter template, select `List of Links` from the drop down. + +![Image of the template dropdown](img/selectorDropDown.png) + +![Image of selecting list of links](img/selectListOfLinks.png) + +A title and description have already been provided. + + + +Widget configuration - Notice that sample text has already been provided: +```json +{"launchText":"Launch the Full App","additionalText":"Additional Text","links":[{"title":"The Google","href":"http://www.google.com","icon":"fa-google","target":"_blank","rel":"noopener noreferrer"},{"title":"Bing","href":"http://www.bing.com","icon":"fa-bed","target":"_blank","rel":"noopener noreferrer"}]} +``` + +Let’s format that JSON so it’s easier to read +```json +{ +"launchText":"Launch the Full App", +"additionalText":"Additional Text" +,"links":[ + { + "title":"The Google", + "href":"http://www.google.com", + "icon":"fa-google", + "target":"_blank", + "rel":"noopener noreferrer" + }, + { + "title":"Bing", + "href":"http://www.bing.com", + "icon":"fa-bed", + "target":"_blank", + "rel":"noopener noreferrer" + } +]} +``` + + +Click the update button and notice that you have a fully functioning list of links widget already. + +Let’s create our own list of links widget. We’ll use Apereo projects in our example. + +For Title, type in “Apereo Projects”. + +Description, type “My very first list of links widget” + +For the widget config, copy and paste this: + +```json +{ +"launchText":"All Apereo Projects", +"links":[ + { + "title":"uPortal", + "href":"https://www.apereo.org/projects/uportal", + "icon":"fa-google", + "target":"_blank", + "rel":"noopener noreferrer" + } +]} +``` + +Finally, type ‘https://www.apereo.org/content/projects-communities’ for Launch URL + +Let’s break that widget configuration down into parts. +The first part is to notice that the launch text is configurable. Try updating the launch text to “See all Apereo projects” +``` +"launchText":"See all Apereo Projects", +``` + +Click update and see what happens. + +Try adding more links. If you need help, here’s some sample widget configuration you can copy and paste. + +```json +{ +"launchText":"See All Apereo Projects", +"links":[ + { + "title":"uPortal", + "href":"https://www.apereo.org/projects/uportal", + "icon":"fa-key", + "target":"_blank", + "rel":"noopener noreferrer" + }, + { + "title":"Sakai Project", + "href":"https://www.apereo.org/projects/sakai-project", + "icon":"fa-folder-open", + "target":"_blank", + "rel":"noopener noreferrer" + } +]} +``` + + +You can keep adding more links and see that the widget auto formats the correct spacing and layout. + +Try three links + +```javascript +{ +"launchText":"See All Apereo Projects", +"links":[ + { + "title":"uPortal", + "href":"https://www.apereo.org/projects/uportal", + "icon":"fa-key", + "target":"_blank", + "rel":"noopener noreferrer" + }, + { + "title":"Sakai Project", + "href":"https://www.apereo.org/projects/sakai-project", + "icon":"fa-folder-open", + "target":"_blank", + "rel":"noopener noreferrer" + }, +{ + "title":"Student Success Plan", + "href":"https://www.apereo.org/projects/student-success-plan", + "icon":"fa-graduation-cap", + "target":"_blank", + "rel":"noopener noreferrer" + } +]} +``` + +See what happens the more you add! diff --git a/docs/rssWidgetExercise.md b/docs/rssWidgetExercise.md new file mode 100644 index 0000000..f155051 --- /dev/null +++ b/docs/rssWidgetExercise.md @@ -0,0 +1,32 @@ +The +[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) +has more information about configuration options and more technical details. + +Choose `RSS widget` from the starter templates. + +![Image of the template dropdown](img/selectorDropDown.png) + +Give your RSS Widget the Title of +``` +Apereo News +``` + +Give your RSS Widget a description of +``` +The latest and greatest news from Apereo +``` + +You can leave the widget configuration as it is. + +For the widget url use +``` +https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.apereo.org%2Fnews%2Ffeed +``` +This is JSONified rss feed of Apereo News. + +Finally change the Launch URL to +``` +https://www.apereo.org/news +``` + +Click update and see your new RSS Widget! From 064848329f199ef1704ce2a585835a0d21e01055 Mon Sep 17 00:00:00 2001 From: Timothy Vertein Date: Tue, 23 May 2017 16:49:12 -0500 Subject: [PATCH 21/51] Removes extra image --- docs/listOfLinksWidgetExercise.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/listOfLinksWidgetExercise.md b/docs/listOfLinksWidgetExercise.md index e6091ae..b610cfe 100644 --- a/docs/listOfLinksWidgetExercise.md +++ b/docs/listOfLinksWidgetExercise.md @@ -6,8 +6,6 @@ In the starter template, select `List of Links` from the drop down. ![Image of the template dropdown](img/selectorDropDown.png) -![Image of selecting list of links](img/selectListOfLinks.png) - A title and description have already been provided. From aed47ff68503a9e2d8c4760a0467b36178a41b72 Mon Sep 17 00:00:00 2001 From: Timothy A Vertein Date: Tue, 23 May 2017 16:51:06 -0500 Subject: [PATCH 22/51] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e69de29..9c9c174 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,2 @@ +# widget-creator +Web-based tool supporting developing widgets for uPortal-home. Documentation available at https://uw-madison-doit.github.io/widget-creator/ From 36aed152ad4362073f31800d914bd7a5373e719d Mon Sep 17 00:00:00 2001 From: Timothy A Vertein Date: Sun, 4 Jun 2017 11:02:30 -0400 Subject: [PATCH 23/51] Updates to stop rendering as html to allow viewing of angular variable (#12) --- docs/customWidgetExercise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/customWidgetExercise.md b/docs/customWidgetExercise.md index 90dfdd5..2c5ea23 100644 --- a/docs/customWidgetExercise.md +++ b/docs/customWidgetExercise.md @@ -23,7 +23,7 @@ Check your balance and get some money saving tips Custom widgets are custom because you supply your own html markup. Angular is available to use. Use this as an example. -```html +```
    From 12dd175c307866bcc1a03c81e26a16bb57e2325b Mon Sep 17 00:00:00 2001 From: Lyle Hanson Date: Tue, 11 Jul 2017 14:55:46 -0500 Subject: [PATCH 24/51] Fix whitespace (#13) Trailing space before period --- src/main/webapp/my-app/view-home/view-home.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index 6a6f7be..d5d8d6c 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -11,8 +11,7 @@

    Read the documentation on widgets - . + rel="noopener noreferrer">the documentation on widgets.

    From 2630879b95ed1996657e1a74f4f86ec6cfdd4f73 Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Mon, 17 Jul 2017 12:01:20 -0500 Subject: [PATCH 25/51] Add basic widget type --- README.md | 9 +++++-- src/main/webapp/json/starter-templates.json | 21 +++++++++++++-- src/main/webapp/my-app/my-app.css | 21 ++++++++++++++- .../webapp/my-app/view-home/controllers.js | 2 ++ .../webapp/my-app/view-home/view-home.html | 27 +++++++++++-------- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 9c9c174..c466112 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# widget-creator -Web-based tool supporting developing widgets for uPortal-home. Documentation available at https://uw-madison-doit.github.io/widget-creator/ +# widget-creator +Web-based tool supporting developing widgets for uPortal-home. Documentation available at https://uw-madison-doit.github.io/widget-creator/ + +## How to run locally +```bash +mvn jetty:run +``` diff --git a/src/main/webapp/json/starter-templates.json b/src/main/webapp/json/starter-templates.json index 8b98c76..e80e252 100644 --- a/src/main/webapp/json/starter-templates.json +++ b/src/main/webapp/json/starter-templates.json @@ -1,5 +1,22 @@ { "templates": [ + { + "entry": { + "layoutObject": { + "id": 4, + "type": "basic", + "widgetType": "basic", + "title": "Basic Widget", + "hasWidgetURL": false, + "description": "This default widget is super easy to set up!", + "mdIcon": "widgets", + "widgetConfig": { + "launchText": "Launch app" + }, + "url": "www.example.com" + } + } + }, { "entry": { "layoutObject": { @@ -29,7 +46,7 @@ "actionURL": "https://rprg.wisc.edu/search/", "actionTarget": "_blank", "actionParameter": "q", - "launchText": "Go to resource guide", + "launchText": "Launch app", "links": [ { "title": "Get started", @@ -62,7 +79,7 @@ "jsonSample": false, "hasWidgetURL": false, "widgetConfig": { - "launchText": "Launch the Full App", + "launchText": "See all", "additionalText": "Additional Text", "links": [ { diff --git a/src/main/webapp/my-app/my-app.css b/src/main/webapp/my-app/my-app.css index 7320162..af51152 100644 --- a/src/main/webapp/my-app/my-app.css +++ b/src/main/webapp/my-app/my-app.css @@ -1,3 +1,7 @@ +.widget-creator .bold { + font-weight: 600; +} + .widget-creator .portlet-body { padding: 10px; } @@ -21,6 +25,21 @@ overflow-y: scroll; } +.widget-creator .hint { + position: absolute; + left: 2px; + right: auto; + bottom: 7px; + font-size: 12px; + line-height: 14px; + transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); + color: grey; +} + +.widget-creator md-input-container.has-hint { + margin-bottom: 32px; +} + .widget-creator ::-webkit-input-placeholder { color: @grayscale6; font-size: 12px; @@ -44,4 +63,4 @@ .widget-middle { width: 315px; margin: auto; -} \ No newline at end of file +} diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index 5d63216..4bad39b 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -15,6 +15,7 @@ define(['angular'], function(angular) { {'value': 'list-of-links', 'name': 'List of links'}, {'value': 'rss', 'name': 'RSS widget'}, {'value': 'widget-creator', 'name': 'Custom'}, + {'value': 'basic', 'name': 'Basic'} ]; $scope.selectedTemplate = {}; $scope.preview = undefined; @@ -45,6 +46,7 @@ define(['angular'], function(angular) { $scope.widget = $scope.widgetAsEditable(value.entry.layoutObject); } }); + $scope.reload(); }; /* --------------- */ diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index d5d8d6c..1a82b42 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -11,7 +11,7 @@

    Read the documentation on widgets. + rel="noopener noreferrer">widget documentation.

    @@ -36,24 +36,32 @@

    Choose a starter template

    + + + + +
    See available icons here.
    +
    - + - - + + +
    This is usually returned by the widgetURL. The results are stored in the $scope.content variable.
    - - + + +
    Valid JSON provided by the widget's widgetConfig.
    - + @@ -69,10 +77,7 @@

    Choose a starter template

    -

    * Changes to these fields requires you to click the refresh button to see the changes in the preview

    -

    ** This is normally result from the widgetURL. This result is dumped into the "$scope.content" - variable.

    -

    *** Valid JSON that gets stored in '$scope.widget.widgetConfig'

    +

    HINT: Most fields require you to click Update before changes appear.

    From 5590fd7dad7c3de942758d53f9f0ca899f991fd0 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Tue, 18 Jul 2017 11:56:07 -0500 Subject: [PATCH 26/51] removing unused json files, fixing accidentally relative urls, adding action items --- src/main/webapp/js/override.js | 3 ++ src/main/webapp/json/custom-template.json | 16 ------- .../webapp/json/list-of-links-template.json | 34 --------------- src/main/webapp/json/rss-template.json | 22 ---------- src/main/webapp/json/sample-action-item.json | 3 ++ src/main/webapp/json/sample-action-items.json | 3 ++ .../json/search-with-links-template.json | 35 ---------------- src/main/webapp/json/starter-templates.json | 42 ++++++++++++++++--- .../webapp/my-app/view-home/controllers.js | 9 ++-- 9 files changed, 50 insertions(+), 117 deletions(-) delete mode 100644 src/main/webapp/json/custom-template.json delete mode 100644 src/main/webapp/json/list-of-links-template.json delete mode 100644 src/main/webapp/json/rss-template.json create mode 100644 src/main/webapp/json/sample-action-item.json create mode 100644 src/main/webapp/json/sample-action-items.json delete mode 100644 src/main/webapp/json/search-with-links-template.json diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 40a9056..f923f48 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -3,6 +3,9 @@ define(['angular'], function(angular) { return angular.module('override', []) // see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto .constant('OVERRIDE', { + 'APP_FLAGS': { + 'defaultTheme': 'uw-madison', + }, 'NAMES': { 'title': 'Widget Creator', 'fname': 'widget-creator', diff --git a/src/main/webapp/json/custom-template.json b/src/main/webapp/json/custom-template.json deleted file mode 100644 index f7723a1..0000000 --- a/src/main/webapp/json/custom-template.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "entry": { - "layoutObject": { - "id": 4, - "type": "widget-creator", - "widgetType": "custom", - "title": "Custom", - "hasWidgetURL": false, - "description": "This super cool portlet can change lives.", - "widgetConfig": {}, - "widgetTemplate": "

    Hello

    ", - "jsonSample": {}, - "url": "www.example.com" - } - } -} diff --git a/src/main/webapp/json/list-of-links-template.json b/src/main/webapp/json/list-of-links-template.json deleted file mode 100644 index 26d98c3..0000000 --- a/src/main/webapp/json/list-of-links-template.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "entry": { - "layoutObject": { - "id": 3, - "url": "www.example.com", - "type": "list-of-links", - "widgetType": "list-of-links", - "title": "List of Links", - "jsonSample": false, - "hasWidgetURL": false, - "widgetConfig": { - "launchText": "Launch the Full App", - "additionalText": "Additional Text", - "links": [ - { - "title": "The Google", - "href": "http://www.google.com", - "icon": "fa-google", - "target": "_blank", - "rel": "noopener noreferrer" - }, - { - "title": "Bing", - "href": "http://www.bing.com", - "icon": "fa-bed", - "target": "_blank", - "rel": "noopener noreferrer" - } - ] - }, - "description": "A simple list of links" - } - } -} diff --git a/src/main/webapp/json/rss-template.json b/src/main/webapp/json/rss-template.json deleted file mode 100644 index a538fd9..0000000 --- a/src/main/webapp/json/rss-template.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "entry": { - "layoutObject": { - "id": 2, - "url": "www.example.com", - "type": "rss", - "widgetType": "rss", - "title": "RSS Widget", - "jsonSample": false, - "widgetConfig": { - "lim": 6, - "target": "", - "showdate": true, - "titleLim": 40, - "dateFormat": "MM-dd-yyyy", - "showShowing": true - }, - "hasWidgetURL": true, - "widgetURL": "" - } - } -} diff --git a/src/main/webapp/json/sample-action-item.json b/src/main/webapp/json/sample-action-item.json new file mode 100644 index 0000000..39dd041 --- /dev/null +++ b/src/main/webapp/json/sample-action-item.json @@ -0,0 +1,3 @@ +{ + "quantity": 1 +} diff --git a/src/main/webapp/json/sample-action-items.json b/src/main/webapp/json/sample-action-items.json new file mode 100644 index 0000000..12cb4d5 --- /dev/null +++ b/src/main/webapp/json/sample-action-items.json @@ -0,0 +1,3 @@ +{ + "quantity": 5 +} diff --git a/src/main/webapp/json/search-with-links-template.json b/src/main/webapp/json/search-with-links-template.json deleted file mode 100644 index 3926b8a..0000000 --- a/src/main/webapp/json/search-with-links-template.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "entry": { - "layoutObject": { - "id": 1, - "type": "search-with-links", - "widgetType": "search-with-links", - "title": "Search with Links", - "jsonSample": false, - "url": "www.example.com", - "widgetConfig": { - "actionURL": "https://rprg.wisc.edu/search/", - "actionTarget": "_blank", - "actionParameter": "q", - "launchText": "Go to resource guide", - "links": [ - { - "title": "Get started", - "href": "https://rprg.wisc.edu/phases/initiate/", - "icon": "fa-map-o", - "target": "_blank", - "rel": "noopener noreferrer" - }, - { - "title": "Resources", - "href": "https://rprg.wisc.edu/category/resource/", - "icon": "fa-th-list", - "target": "_blank", - "rel": "noopener noreferrer" - } - ] - }, - "hasWidgetURL": false - } - } -} diff --git a/src/main/webapp/json/starter-templates.json b/src/main/webapp/json/starter-templates.json index e80e252..621300e 100644 --- a/src/main/webapp/json/starter-templates.json +++ b/src/main/webapp/json/starter-templates.json @@ -3,7 +3,7 @@ { "entry": { "layoutObject": { - "id": 4, + "id": 5, "type": "basic", "widgetType": "basic", "title": "Basic Widget", @@ -13,7 +13,7 @@ "widgetConfig": { "launchText": "Launch app" }, - "url": "www.example.com" + "url": "//www.example.com" } } }, @@ -29,7 +29,7 @@ "widgetConfig": {}, "widgetTemplate": "

    Hello

    ", "jsonSample": {}, - "url": "www.example.com" + "url": "//www.example.com" } } }, @@ -41,7 +41,7 @@ "widgetType": "search-with-links", "title": "Search with Links", "jsonSample": false, - "url": "www.example.com", + "url": "//www.example.com", "widgetConfig": { "actionURL": "https://rprg.wisc.edu/search/", "actionTarget": "_blank", @@ -72,7 +72,7 @@ "entry": { "layoutObject": { "id": 3, - "url": "www.example.com", + "url": "//www.example.com", "type": "list-of-links", "widgetType": "list-of-links", "title": "List of Links", @@ -106,7 +106,7 @@ "entry": { "layoutObject": { "id": 2, - "url": "www.example.com", + "url": "//www.example.com", "type": "rss", "widgetType": "rss", "title": "RSS Widget", @@ -123,6 +123,36 @@ "widgetURL": "" } } + }, + { + "entry": { + "layoutObject": { + "id": 6, + "url": "//www.example.com", + "type": "action-items", + "widgetType": "action-items", + "title": "Action Items", + "description": "A list of items that need your attention", + "widgetConfig": { + "launchText": "See all items", + "actionItems": [ + { + "textSingular": "item needs your attention.", + "textPlural": "items need your attention.", + "feedUrl": "json/sample-action-items.json", + "actionUrl": "//www.example.com/#first-link" + }, + { + "textSingular": "item needs your approval.", + "textPlural": "items need your approval.", + "feedUrl": "json/sample-action-item.json", + "actionUrl": "//www.example.com/#second-link" + } + ] + }, + "hasWidgetURL": false + } + } } ] } diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index 4bad39b..81ca1e4 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -11,11 +11,12 @@ define(['angular'], function(angular) { /* Bindable members */ /* ---------------- */ $scope.templateOptions = [ - {'value': 'search-with-links', 'name': 'Search with links'}, - {'value': 'list-of-links', 'name': 'List of links'}, - {'value': 'rss', 'name': 'RSS widget'}, + {'value': 'basic', 'name': 'Basic'}, {'value': 'widget-creator', 'name': 'Custom'}, - {'value': 'basic', 'name': 'Basic'} + {'value': 'rss', 'name': 'RSS widget'}, + {'value': 'list-of-links', 'name': 'List of links'}, + {'value': 'search-with-links', 'name': 'Search with links'}, + {'value': 'action-items', 'name': 'Action Items'}, ]; $scope.selectedTemplate = {}; $scope.preview = undefined; From c1ee92bd027366318a0443d0cc563befa0922f60 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Tue, 18 Jul 2017 13:04:13 -0500 Subject: [PATCH 27/51] adding 0 quantity sample --- src/main/webapp/json/sample-action-none.json | 3 +++ src/main/webapp/json/starter-templates.json | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 src/main/webapp/json/sample-action-none.json diff --git a/src/main/webapp/json/sample-action-none.json b/src/main/webapp/json/sample-action-none.json new file mode 100644 index 0000000..a243fda --- /dev/null +++ b/src/main/webapp/json/sample-action-none.json @@ -0,0 +1,3 @@ +{ + "quantity": 0 +} diff --git a/src/main/webapp/json/starter-templates.json b/src/main/webapp/json/starter-templates.json index 621300e..d658127 100644 --- a/src/main/webapp/json/starter-templates.json +++ b/src/main/webapp/json/starter-templates.json @@ -136,6 +136,12 @@ "widgetConfig": { "launchText": "See all items", "actionItems": [ + { + "textSingular": "thing in empty feed.", + "textPlural": "things in empty feed.", + "feedUrl": "json/sample-action-none.json", + "actionUrl": "//www.example.com/#second-link" + }, { "textSingular": "item needs your attention.", "textPlural": "items need your attention.", From c3c48d8c257f507c69ce0a5fea983f638bfe47dc Mon Sep 17 00:00:00 2001 From: Andrew Petro Date: Wed, 26 Jul 2017 15:45:33 -0500 Subject: [PATCH 28/51] Update in-creator hyperlink to documentation. --- src/main/webapp/my-app/view-home/view-home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index 1a82b42..20280fa 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -9,7 +9,7 @@ Smart Widget Configuration

    Read - widget documentation.

    From 8c22965eba473ca1546c6db0ed928b8ee17e5bf2 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Wed, 23 Aug 2017 13:02:07 -0500 Subject: [PATCH 29/51] guestMode, and cleaning up config urls --- src/main/webapp/js/override.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index f923f48..0c5b329 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -1,23 +1,31 @@ define(['angular'], function(angular) { - /* Keep in sync with docs/mardown/configuration.md */ return angular.module('override', []) - // see http://uw-madison-doit.github.io/uw-frame/latest/#/md/configuration for howto .constant('OVERRIDE', { 'APP_FLAGS': { 'defaultTheme': 'uw-madison', + 'showSearch': false, + 'isWeb': false, + 'loginOnLoad': false, }, 'NAMES': { 'title': 'Widget Creator', 'fname': 'widget-creator', }, 'SERVICE_LOC': { + 'kvURL': null, + 'groupURL': 'staticFeeds/groups.json', + 'sessionInfo': 'staticFeeds/guest-session.json', + 'shibbolethSessionURL': '/Shibboleth.sso/Session.json', 'templates': 'json/starter-templates', 'widgetApi': { // For local testing, change to 'staticFeeds/' 'entry': 'data:application/json;base64,', 'entrySuffix': '', - 'entries': '/portal/api/marketplace/entries.json', + 'entries': null, }, }, + 'MISC_URLS': { + 'rootURL': 'https://my.wisc.edu', + }, }); }); From 361a5e0979186b1cfe81f0270c61d393f65f6965 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Wed, 23 Aug 2017 13:16:29 -0500 Subject: [PATCH 30/51] adding documentation link back in --- src/main/webapp/js/override.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 0c5b329..5af6a13 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -1,4 +1,5 @@ define(['angular'], function(angular) { + // see https://uw-madison-doit.github.io/uw-frame/configuration.html for howto return angular.module('override', []) .constant('OVERRIDE', { 'APP_FLAGS': { From 6d1b3a159faab372b19b6176b2053e9b0e3b5ef7 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Wed, 23 Aug 2017 14:08:24 -0500 Subject: [PATCH 31/51] Fix Session url to be staticFeed Somehow I forgot this in the pull request that was supposed to address this --- src/main/webapp/js/override.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 5af6a13..4811641 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -16,7 +16,7 @@ define(['angular'], function(angular) { 'kvURL': null, 'groupURL': 'staticFeeds/groups.json', 'sessionInfo': 'staticFeeds/guest-session.json', - 'shibbolethSessionURL': '/Shibboleth.sso/Session.json', + 'shibbolethSessionURL': 'staticFeeds/Shibboleth.sso/Session.json', 'templates': 'json/starter-templates', 'widgetApi': { // For local testing, change to 'staticFeeds/' From 0af79488531ea56cb46af658e161d1d298d25487 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 13:20:19 -0500 Subject: [PATCH 32/51] Update to uw-frame 5.0.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cbefafe..a5ab690 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ edu.wisc.my.apps uw-frame - 4.1.1-SNAPSHOT + 5.0.0 war From 9bc84b2c8ddb851aecf801abfb7f9631b312c1f0 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 13:53:45 -0500 Subject: [PATCH 33/51] Releasing 1.0.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a5ab690..2cfa2f8 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 edu.wisc.my.app widget-creator - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT Widget Creator War Web application for uportal-app-framework widget creator. war From 4981ac912be143ffafc963fb190a659bb6aacea7 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 14:03:47 -0500 Subject: [PATCH 34/51] Revert "Releasing 1.0.0" This reverts commit 9bc84b2c8ddb851aecf801abfb7f9631b312c1f0. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2cfa2f8..a5ab690 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 edu.wisc.my.app widget-creator - 1.0.1-SNAPSHOT + 1.0.0-SNAPSHOT Widget Creator War Web application for uportal-app-framework widget creator. war From f1118d48e4ec1ccf2d9af6868035dcc293a32001 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 14:28:35 -0500 Subject: [PATCH 35/51] removing troublesome tag tag in pom --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5ab690..0055be8 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,6 @@ scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git https://github.com/UW-Madison-DoIT/widget-creator - HEAD From bd342e0cce03cdb74d516af72b96747e05cc7fe8 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 14:48:53 -0500 Subject: [PATCH 36/51] upgrading release plugin due to a bug in 2.4.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0055be8..8022d22 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ maven-release-plugin - 2.4.2 + 2.5.3 org.apache.maven.plugins From 4da56150666c9eeab7d97c6f6b660c637c5108f7 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 14:50:58 -0500 Subject: [PATCH 37/51] [maven-release-plugin] prepare release widget-creator-1.0.0 --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8022d22..96c32b5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 edu.wisc.my.app widget-creator - 1.0.0-SNAPSHOT + 1.0.0 Widget Creator War Web application for uportal-app-framework widget creator. war @@ -10,6 +10,7 @@ scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git https://github.com/UW-Madison-DoIT/widget-creator + widget-creator-1.0.0 From 50d2de4c7c171601c6ac05790046bc8a88c864d1 Mon Sep 17 00:00:00 2001 From: David M Sibley Date: Thu, 24 Aug 2017 14:51:17 -0500 Subject: [PATCH 38/51] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 96c32b5..c582e2c 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 edu.wisc.my.app widget-creator - 1.0.0 + 1.0.1-SNAPSHOT Widget Creator War Web application for uportal-app-framework widget creator. war @@ -10,7 +10,7 @@ scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git https://github.com/UW-Madison-DoIT/widget-creator - widget-creator-1.0.0 + HEAD From 5a876c80e787705e4d4d0102ac17846393e559c8 Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Mon, 4 Sep 2017 10:32:50 -0700 Subject: [PATCH 39/51] chore(package): add package lock file --- package-lock.json | 4587 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4587 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9ef718a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4587 @@ +{ + "name": "widget-creator", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true, + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + } + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "dev": true + }, + "bl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", + "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", + "dev": true, + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "dev": true + }, + "body-parser": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", + "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", + "dev": true, + "requires": { + "bytes": "2.4.0", + "content-type": "1.0.2", + "debug": "2.6.7", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.15", + "on-finished": "2.3.0", + "qs": "6.4.0", + "raw-body": "2.2.0", + "type-is": "1.6.15" + }, + "dependencies": { + "debug": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browserslist": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.1.4.tgz", + "integrity": "sha1-zFJq9KExK30uBWU+VtDIq3DA4FM=", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000722", + "electron-to-chromium": "1.3.20" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caniuse-db": { + "version": "1.0.30000671", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000671.tgz", + "integrity": "sha1-nwcbvHuWmUY4zLr0eCnVihV3qO0=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000722", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000722.tgz", + "integrity": "sha1-jL/gdEBHjjoWqw07GC/u8ZAeq1U=", + "dev": true + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "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.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "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" + } + }, + "ci-info": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.1.tgz", + "integrity": "sha512-u+kVhyCfR37aSKEneBwRcsff8tCLIyBvngsqL/fgOoWJsBhSFVVRaXWUI3HuAQKu8cLawFFRxNxpDUktZUXScw==", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.2" + } + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "connect": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.3.tgz", + "integrity": "sha512-GLSZqgjVxPvGYVD/2vz//gS201MEXk4b7t3nHV6OVnTdDNWi/Gm7Rpxs/ybvljPWvULys/wrzIV3jB3YvEc3nQ==", + "dev": true, + "requires": { + "debug": "2.6.8", + "finalhandler": "1.0.4", + "parseurl": "1.3.1", + "utils-merge": "1.0.0" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "coveralls": { + "version": "2.11.16", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.11.16.tgz", + "integrity": "sha1-2pBhJlFC3e6VT2g3kSK+l76KtLE=", + "dev": true, + "requires": { + "js-yaml": "3.6.1", + "lcov-parse": "0.0.10", + "log-driver": "1.2.5", + "minimist": "1.2.0", + "request": "2.79.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.30" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.20", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.20.tgz", + "integrity": "sha1-Lu3VzLrn3cVX9orR/OnBcukV5OU=", + "dev": true + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true + }, + "engine.io": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", + "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", + "dev": true, + "requires": { + "accepts": "1.3.3", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "ws": "1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "engine.io-client": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", + "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parsejson": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "1.1.2", + "xmlhttprequest-ssl": "1.5.3", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "engine.io-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", + "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary": "0.1.7", + "wtf-8": "1.0.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.30", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "dev": true, + "requires": { + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30", + "es6-iterator": "2.0.1", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-promise": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", + "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=", + "dev": true + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "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 + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.8", + "doctrine": "2.0.0", + "escope": "3.6.0", + "espree": "3.5.0", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.5", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.1", + "is-resolvable": "1.0.0", + "js-yaml": "3.9.1", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + } + }, + "eslint-config-angular": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-angular/-/eslint-config-angular-0.5.0.tgz", + "integrity": "sha1-4KrgEy4550Z98/dUf+yBpE02hcQ=", + "dev": true + }, + "eslint-config-google": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.7.1.tgz", + "integrity": "sha1-VZj4SY6eB4Qg80uASVuNlZ9lH7I=", + "dev": true + }, + "eslint-git-changes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-git-changes/-/eslint-git-changes-2.0.0.tgz", + "integrity": "sha1-x5ZKRGm3A+WOo6rqHSDSbc1bpZ8=", + "dev": true, + "requires": { + "yargs": "4.8.1" + } + }, + "eslint-plugin-angular": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-angular/-/eslint-plugin-angular-1.6.4.tgz", + "integrity": "sha1-9JWzUeKkmQegIPHE+9+/gQEaMqI=", + "dev": true + }, + "eslint-plugin-compat": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-1.0.4.tgz", + "integrity": "sha512-16yjDdjrivRQT7/Kov+3O6DMvfg8WYC1JKPAsvf/UNtdLBeMXVYATohAM4nOak1ynGP69mKUlOjw7nroUqY9Sg==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "browserslist": "2.1.4", + "caniuse-db": "1.0.30000671", + "requireindex": "1.1.0" + } + }, + "eslint-plugin-jasmine": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.8.4.tgz", + "integrity": "sha1-Z6VVHj0dXguMa1Sq66uVNw9dN94=", + "dev": true + }, + "eslint-plugin-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz", + "integrity": "sha1-m6c7sL6Z1QCT6In1uWhGPSow764=", + "dev": true, + "requires": { + "jshint": "2.9.5" + } + }, + "eslint-plugin-promise": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", + "dev": true + }, + "espree": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", + "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", + "dev": true, + "requires": { + "acorn": "5.1.2", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.30" + } + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" + }, + "dependencies": { + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "0.1.1" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "0.1.1", + "repeat-string": "0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extract-zip": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", + "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.2.0", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "1.2.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.2.2", + "object-assign": "4.1.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "finalhandler": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz", + "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==", + "dev": true, + "requires": { + "debug": "2.6.8", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.1", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "1.0.0" + } + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": 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" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "handlebars": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.1", + "pinkie-promise": "2.0.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.1.1" + } + }, + "has-binary": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", + "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + } + }, + "http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "dev": true, + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "husky": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.13.4.tgz", + "integrity": "sha1-SHhcUCjeNFKlHEjBLE+UshJKFAc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "find-parent-dir": "0.3.0", + "is-ci": "1.0.10", + "normalize-path": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "dev": true + }, + "ignore": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + } + }, + "interpret": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.10.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "1.0.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.10", + "js-yaml": "3.9.1", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", + "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jshint": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", + "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "dev": true, + "requires": { + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.4", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" + }, + "dependencies": { + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "karma": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", + "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", + "dev": true, + "requires": { + "bluebird": "3.5.0", + "body-parser": "1.17.2", + "chokidar": "1.7.0", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.3", + "core-js": "2.5.1", + "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.16.2", + "isbinaryfile": "3.0.2", + "lodash": "3.10.1", + "log4js": "0.6.38", + "mime": "1.4.0", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.1.5", + "range-parser": "1.2.0", + "rimraf": "2.6.1", + "safe-buffer": "5.1.1", + "socket.io": "1.7.3", + "source-map": "0.5.7", + "tmp": "0.0.31", + "useragent": "2.2.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "1.0.1", + "which": "1.3.0" + } + }, + "karma-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.1.tgz", + "integrity": "sha1-Wv+LOc9plNwi3kyENix2ABtjfPY=", + "dev": true, + "requires": { + "dateformat": "1.0.12", + "istanbul": "0.4.5", + "lodash": "3.10.1", + "minimatch": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "karma-coveralls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/karma-coveralls/-/karma-coveralls-1.1.2.tgz", + "integrity": "sha1-b5YO5zh5Owh7qZKEqFTva+TTKuA=", + "dev": true, + "requires": { + "coveralls": "2.11.16", + "glob": "5.0.15" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "karma-html-reporter": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/karma-html-reporter/-/karma-html-reporter-0.2.7.tgz", + "integrity": "sha1-/XPanxrJn9W6+zCc8HCUIYjnumM=", + "dev": true, + "requires": { + "lodash": "2.2.1", + "mu2": "0.5.21" + }, + "dependencies": { + "lodash": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.2.1.tgz", + "integrity": "sha1-ypNf0UqzwMhyq6zxmLnNpQFECGc=", + "dev": true + } + } + }, + "karma-htmlfile-reporter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/karma-htmlfile-reporter/-/karma-htmlfile-reporter-0.3.5.tgz", + "integrity": "sha1-CavKmRCj6x27onqadmAmlIyWygQ=", + "dev": true, + "requires": { + "xmlbuilder": "3.1.0" + } + }, + "karma-jasmine": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-0.3.8.tgz", + "integrity": "sha1-W2RXeRrZuJqhc/B54+vhuMgFI2w=", + "dev": true + }, + "karma-jasmine-html-reporter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", + "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", + "dev": true, + "requires": { + "karma-jasmine": "1.1.0" + }, + "dependencies": { + "karma-jasmine": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.0.tgz", + "integrity": "sha1-IuTAa/mhguUpTR9wXjczgRuBCs8=", + "dev": true + } + } + }, + "karma-phantomjs-launcher": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", + "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", + "dev": true, + "requires": { + "lodash": "4.17.4", + "phantomjs-prebuilt": "2.1.15" + }, + "dependencies": { + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "phantomjs-prebuilt": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz", + "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=", + "dev": true, + "requires": { + "es6-promise": "4.0.5", + "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.14" + } + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.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.1.4", + "har-validator": "4.2.1", + "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.17", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + } + } + }, + "karma-read-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-read-json/-/karma-read-json-1.1.0.tgz", + "integrity": "sha1-4M40XFrmOKNqWgXcGmoELczaseQ=", + "dev": true + }, + "karma-requirejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-requirejs/-/karma-requirejs-1.1.0.tgz", + "integrity": "sha1-/driy4fX68FvsCIok1ZNf+5Xh5g=", + "dev": true + }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": 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" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "log-driver": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", + "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", + "dev": true + }, + "log4js": { + "version": "0.6.38", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", + "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "semver": "4.3.6" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz", + "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": 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", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + } + } + }, + "mime": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.0.tgz", + "integrity": "sha512-n9ChLv77+QQEapYz8lV+rIZAW3HhAPW2CXnzb1GN5uMkuczshwvkW7XPsbzU0ZQN3sP47Er2KVkp2p3KyqZKSQ==", + "dev": true + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mu2": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/mu2/-/mu2-0.5.21.tgz", + "integrity": "sha1-iIqPD9kOsc/anbgUdvbhmcyeWNM=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": 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" + } + }, + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "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" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parsejson": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", + "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "phantomjs": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/phantomjs/-/phantomjs-2.1.7.tgz", + "integrity": "sha1-xpEPZ5NcNyhbYRQyn8LyfV8+MTQ=", + "dev": true, + "requires": { + "extract-zip": "1.5.0", + "fs-extra": "0.26.7", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.67.0", + "request-progress": "2.0.1", + "which": "1.2.14" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "concat-stream": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", + "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + } + }, + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "dev": true + }, + "extract-zip": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", + "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=", + "dev": true, + "requires": { + "concat-stream": "1.5.0", + "debug": "0.7.4", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + } + }, + "form-data": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", + "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", + "dev": true, + "requires": { + "async": "2.5.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.1" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "dev": true + }, + "qs": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.1.tgz", + "integrity": "sha1-gB/uAw4LlFDWOFrcSKTMVbRK7fw=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.67.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.67.0.tgz", + "integrity": "sha1-ivdHgOK/EeoK6aqWXBHxGv0nJ0I=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "bl": "1.0.3", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "1.0.1", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "node-uuid": "1.4.8", + "oauth-sign": "0.8.2", + "qs": "5.2.1", + "stringstream": "0.0.5", + "tough-cookie": "2.2.2", + "tunnel-agent": "0.4.3" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "tough-cookie": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", + "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qjobs": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.1.5.tgz", + "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", + "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "dev": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.15", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": 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", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.4.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", + "dev": true + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "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.17", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.1.0" + }, + "dependencies": { + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + } + } + }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "dev": true, + "requires": { + "throttleit": "1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=", + "dev": true + }, + "requirejs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz", + "integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.0.3", + "rechoir": "0.6.2" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "socket.io": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", + "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", + "dev": true, + "requires": { + "debug": "2.3.3", + "engine.io": "1.8.3", + "has-binary": "0.1.7", + "object-assign": "4.1.0", + "socket.io-adapter": "0.5.0", + "socket.io-client": "1.7.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", + "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", + "dev": true, + "requires": { + "debug": "2.3.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-client": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", + "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.3.3", + "engine.io-client": "1.8.3", + "has-binary": "0.1.7", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.5", + "socket.io-parser": "2.3.1", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", + "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "dev": true, + "requires": { + "component-emitter": "1.1.2", + "debug": "2.2.0", + "isarray": "0.0.1", + "json3": "3.3.2" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "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.1.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "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 + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "useragent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz", + "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", + "dev": true, + "requires": { + "lru-cache": "2.2.4", + "tmp": "0.0.31" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "ws": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", + "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "dev": true, + "requires": { + "options": "0.0.6", + "ultron": "1.0.2" + } + }, + "wtf-8": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", + "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", + "dev": true + }, + "xmlbuilder": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz", + "integrity": "sha1-LIaIjy1OrehQ+jjKf3Ij9yCVFuE=", + "dev": true, + "requires": { + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "lodash.assign": "4.2.0" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "1.0.1" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} From f85131b508bea4650d3c9c0fbad81d41a9875c8c Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Mon, 4 Sep 2017 10:33:15 -0700 Subject: [PATCH 40/51] docs(readme): add david dm dependency status badge --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c466112..f604150 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # widget-creator + +[![devDependencies Status](https://david-dm.org/UW-Madison-DoIT/widget-creator/dev-status.svg)](https://david-dm.org/UW-Madison-DoIT/widget-creator?type=dev) + Web-based tool supporting developing widgets for uPortal-home. Documentation available at https://uw-madison-doit.github.io/widget-creator/ ## How to run locally From 0a53beb3e5b98558b3eebba5e039e3af9db44d8f Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Mon, 4 Sep 2017 10:42:46 -0700 Subject: [PATCH 41/51] style(md): use angle brackets around literal link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f604150..f4e6b38 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![devDependencies Status](https://david-dm.org/UW-Madison-DoIT/widget-creator/dev-status.svg)](https://david-dm.org/UW-Madison-DoIT/widget-creator?type=dev) -Web-based tool supporting developing widgets for uPortal-home. Documentation available at https://uw-madison-doit.github.io/widget-creator/ +Web-based tool supporting developing widgets for uPortal-home. Documentation available at ## How to run locally ```bash From e8d41e8754be1ec606ea20c8997e05628950f623 Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Mon, 4 Sep 2017 13:26:55 -0700 Subject: [PATCH 42/51] ci(travis): setup Travis CI for Linux and MacOS --- .travis.yml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e358d25..1358098 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,24 @@ language: java -jdk: - - oraclejdk7 +sudo: false + +matrix: + include: + - os: linux + dist: trusty + jdk: oraclejdk8 + - os: linux + dist: trusty + jdk: openjdk7 + - os: osx + osx_image: xcode8.3 + +before_install: + - nvm install node + - npm install + +script: npm test + +cache: + directories: + - $HOME/.m2 + - $HOME/.npm From 198f98f713464b2d64e045967904c3414e368ab9 Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Mon, 4 Sep 2017 13:28:52 -0700 Subject: [PATCH 43/51] docs(readme): add Travis CI badge to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f4e6b38..652d54b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # widget-creator +[![Build Status](https://travis-ci.org/UW-Madison-DoIT/widget-creator.svg?branch=master)](https://travis-ci.org/UW-Madison-DoIT/widget-creator) [![devDependencies Status](https://david-dm.org/UW-Madison-DoIT/widget-creator/dev-status.svg)](https://david-dm.org/UW-Madison-DoIT/widget-creator?type=dev) Web-based tool supporting developing widgets for uPortal-home. Documentation available at From c7324e350e16b56f748525dc32f0f8de2cceb6df Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Fri, 22 Sep 2017 14:48:08 -0500 Subject: [PATCH 44/51] Update to widget-creator standard, then rename --- README.md | 8 +- docs/README.md | 19 +- docs/customWidgetExercise.md | 58 ------- docs/listOfLinksWidgetExercise.md | 132 -------------- docs/rssWidgetExercise.md | 32 ---- package.json | 12 +- pom.xml | 14 +- src/main/webapp/js/override.js | 11 +- src/main/webapp/json/sample-action-item.json | 3 - src/main/webapp/json/sample-action-items.json | 3 - src/main/webapp/json/sample-action-none.json | 3 - src/main/webapp/json/starter-templates.json | 164 ------------------ .../webapp/my-app/view-home/controllers.js | 144 --------------- .../webapp/my-app/view-home/directives.js | 20 +-- src/main/webapp/my-app/view-home/services.js | 17 -- 15 files changed, 22 insertions(+), 618 deletions(-) delete mode 100644 docs/customWidgetExercise.md delete mode 100644 docs/listOfLinksWidgetExercise.md delete mode 100644 docs/rssWidgetExercise.md delete mode 100644 src/main/webapp/json/sample-action-item.json delete mode 100644 src/main/webapp/json/sample-action-items.json delete mode 100644 src/main/webapp/json/sample-action-none.json delete mode 100644 src/main/webapp/json/starter-templates.json diff --git a/README.md b/README.md index 652d54b..bd6eb5e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# widget-creator +# My App Seed -[![Build Status](https://travis-ci.org/UW-Madison-DoIT/widget-creator.svg?branch=master)](https://travis-ci.org/UW-Madison-DoIT/widget-creator) -[![devDependencies Status](https://david-dm.org/UW-Madison-DoIT/widget-creator/dev-status.svg)](https://david-dm.org/UW-Madison-DoIT/widget-creator?type=dev) +[![Build Status](https://travis-ci.org/UW-Madison-DoIT/my-app-seed.svg?branch=master)](https://travis-ci.org/UW-Madison-DoIT/my-app-seed) +[![devDependencies Status](https://david-dm.org/UW-Madison-DoIT/my-app-seed/dev-status.svg)](https://david-dm.org/UW-Madison-DoIT/my-app-seed?type=dev) -Web-based tool supporting developing widgets for uPortal-home. Documentation available at +Seed application for developing apps with the uPortal-app-framework. Documentation available at ## How to run locally ```bash diff --git a/docs/README.md b/docs/README.md index ecf6dc3..20e396b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,22 +1,7 @@ -Widget Creator is a web application that allows you to quickly create and test -widgets. Widgets are used in -[uPortal-App-Frameworks applications](https://github.com/UW-Madison-DoIT/uw-frame) -and come complete with their own -[documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) on how -to configure and deploy. This application allows a sandbox for rapid -development. UW-Madison hosts a -[deployed instance](https://test.my.wisc.edu/widget-creator) for campus -developers to use. +My App Seed is a demo app used to help developers learn to make +[uPortal-App-Framework applications](https://github.com/UW-Madison-DoIT/uw-frame). # How to run locally ```bash mvn jetty:run ``` - - -# Exercises -Complete some exercises that will give you some experience with creating widgets - -* [List of Links Widget Exercise](listOfLinksWidgetExercise.md) -* [RSS Widget Exercise](rssWidgetExercise.md) -* [Custom Widget Exercise](customWidgetExercise.md) \ No newline at end of file diff --git a/docs/customWidgetExercise.md b/docs/customWidgetExercise.md deleted file mode 100644 index 2c5ea23..0000000 --- a/docs/customWidgetExercise.md +++ /dev/null @@ -1,58 +0,0 @@ -The -[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) -has more information about configuration options and more technical details. - -Choose `Custom Widget` from the starter templates. - -![Image of the template dropdown](img/selectorDropDown.png) - -Let’s create a campus food account balance widget. - -Select `Custom` from the drop down starter template selector - -Type into title -``` -Food Account Balance -``` - -Type as a description -``` -Check your balance and get some money saving tips -``` - -Custom widgets are custom because you supply your own html markup. Angular is -available to use. Use this as an example. - -``` -
    -
    - - - {{content.data.food.balance | currency:"$":2}} -
    -
    - - -
    -
    - - -
    -
    -Manage my food account - -``` - -In widget URL JSON sample type this - -```json -{"status":200,"data":{"food": {"balance":25.73}}} -``` - -Click update and see your widget in action. - -Change the styling and the JSON to try different things. diff --git a/docs/listOfLinksWidgetExercise.md b/docs/listOfLinksWidgetExercise.md deleted file mode 100644 index b610cfe..0000000 --- a/docs/listOfLinksWidgetExercise.md +++ /dev/null @@ -1,132 +0,0 @@ -The -[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) -has more information about configuration options and more technical details. - -In the starter template, select `List of Links` from the drop down. - -![Image of the template dropdown](img/selectorDropDown.png) - -A title and description have already been provided. - - - -Widget configuration - Notice that sample text has already been provided: -```json -{"launchText":"Launch the Full App","additionalText":"Additional Text","links":[{"title":"The Google","href":"http://www.google.com","icon":"fa-google","target":"_blank","rel":"noopener noreferrer"},{"title":"Bing","href":"http://www.bing.com","icon":"fa-bed","target":"_blank","rel":"noopener noreferrer"}]} -``` - -Let’s format that JSON so it’s easier to read -```json -{ -"launchText":"Launch the Full App", -"additionalText":"Additional Text" -,"links":[ - { - "title":"The Google", - "href":"http://www.google.com", - "icon":"fa-google", - "target":"_blank", - "rel":"noopener noreferrer" - }, - { - "title":"Bing", - "href":"http://www.bing.com", - "icon":"fa-bed", - "target":"_blank", - "rel":"noopener noreferrer" - } -]} -``` - - -Click the update button and notice that you have a fully functioning list of links widget already. - -Let’s create our own list of links widget. We’ll use Apereo projects in our example. - -For Title, type in “Apereo Projects”. - -Description, type “My very first list of links widget” - -For the widget config, copy and paste this: - -```json -{ -"launchText":"All Apereo Projects", -"links":[ - { - "title":"uPortal", - "href":"https://www.apereo.org/projects/uportal", - "icon":"fa-google", - "target":"_blank", - "rel":"noopener noreferrer" - } -]} -``` - -Finally, type ‘https://www.apereo.org/content/projects-communities’ for Launch URL - -Let’s break that widget configuration down into parts. -The first part is to notice that the launch text is configurable. Try updating the launch text to “See all Apereo projects” -``` -"launchText":"See all Apereo Projects", -``` - -Click update and see what happens. - -Try adding more links. If you need help, here’s some sample widget configuration you can copy and paste. - -```json -{ -"launchText":"See All Apereo Projects", -"links":[ - { - "title":"uPortal", - "href":"https://www.apereo.org/projects/uportal", - "icon":"fa-key", - "target":"_blank", - "rel":"noopener noreferrer" - }, - { - "title":"Sakai Project", - "href":"https://www.apereo.org/projects/sakai-project", - "icon":"fa-folder-open", - "target":"_blank", - "rel":"noopener noreferrer" - } -]} -``` - - -You can keep adding more links and see that the widget auto formats the correct spacing and layout. - -Try three links - -```javascript -{ -"launchText":"See All Apereo Projects", -"links":[ - { - "title":"uPortal", - "href":"https://www.apereo.org/projects/uportal", - "icon":"fa-key", - "target":"_blank", - "rel":"noopener noreferrer" - }, - { - "title":"Sakai Project", - "href":"https://www.apereo.org/projects/sakai-project", - "icon":"fa-folder-open", - "target":"_blank", - "rel":"noopener noreferrer" - }, -{ - "title":"Student Success Plan", - "href":"https://www.apereo.org/projects/student-success-plan", - "icon":"fa-graduation-cap", - "target":"_blank", - "rel":"noopener noreferrer" - } -]} -``` - -See what happens the more you add! diff --git a/docs/rssWidgetExercise.md b/docs/rssWidgetExercise.md deleted file mode 100644 index f155051..0000000 --- a/docs/rssWidgetExercise.md +++ /dev/null @@ -1,32 +0,0 @@ -The -[Widget Documentation](http://uw-madison-doit.github.io/uw-frame/widgets.html) -has more information about configuration options and more technical details. - -Choose `RSS widget` from the starter templates. - -![Image of the template dropdown](img/selectorDropDown.png) - -Give your RSS Widget the Title of -``` -Apereo News -``` - -Give your RSS Widget a description of -``` -The latest and greatest news from Apereo -``` - -You can leave the widget configuration as it is. - -For the widget url use -``` -https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.apereo.org%2Fnews%2Ffeed -``` -This is JSONified rss feed of Apereo News. - -Finally change the Launch URL to -``` -https://www.apereo.org/news -``` - -Click update and see your new RSS Widget! diff --git a/package.json b/package.json index cb73afe..ec0b01f 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "widget-creator", + "name": "my-app-seed", "version": "1.0.0", - "description": "Web application for uportal-app-framework widget creator.", + "description": "Web application for developing uportal-app-framework apps.", "main": "index.js", "scripts": { "build:pre": "mvn clean package", - "build:test": "karma start target/widget-creator/karma.conf.js --single-run", + "build:test": "karma start target/my-app-seed/karma.conf.js --single-run", "build:lint-js": "eslint --ext js --ext json --ext md . --ignore-path .gitignore", "build": "npm run build:pre && npm run build:test && npm run build:lint-js", "test": "npm run build:pre && npm run build:test", @@ -15,13 +15,13 @@ }, "repository": { "type": "git", - "url": "git+ssh://git@github.com/UW-Madison-DoIT/widget-creator.git" + "url": "git+ssh://git@github.com/UW-Madison-DoIT/my-app-seed.git" }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/UW-Madison-DoIT/widget-creator/issues" + "url": "https://github.com/UW-Madison-DoIT/my-app-seed/issues" }, - "homepage": "https://github.com/UW-Madison-DoIT/widget-creator#readme", + "homepage": "https://github.com/UW-Madison-DoIT/my-app-seed#readme", "devDependencies": { "eslint": "^3.17.1", "eslint-config-angular": "^0.5.0", diff --git a/pom.xml b/pom.xml index c582e2c..accdd09 100644 --- a/pom.xml +++ b/pom.xml @@ -1,15 +1,15 @@ 4.0.0 edu.wisc.my.app - widget-creator + my-app-seed 1.0.1-SNAPSHOT - Widget Creator War - Web application for uportal-app-framework widget creator. + My Seed App War + Web application for developing applications with uportal-app-framework. war - scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git - scm:git:git@github.com:UW-Madison-DoIT/widget-creator.git - https://github.com/UW-Madison-DoIT/widget-creator + scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git + scm:git:git@github.com:UW-Madison-DoIT/my-app-seed.git + https://github.com/UW-Madison-DoIT/my-app-seed HEAD @@ -61,7 +61,7 @@ - widget-creator + my-app-seed maven-war-plugin diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 4811641..243dc6d 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -9,21 +9,14 @@ define(['angular'], function(angular) { 'loginOnLoad': false, }, 'NAMES': { - 'title': 'Widget Creator', - 'fname': 'widget-creator', + 'title': 'My App Seed', + 'fname': 'my-app-seed', }, 'SERVICE_LOC': { 'kvURL': null, 'groupURL': 'staticFeeds/groups.json', 'sessionInfo': 'staticFeeds/guest-session.json', 'shibbolethSessionURL': 'staticFeeds/Shibboleth.sso/Session.json', - 'templates': 'json/starter-templates', - 'widgetApi': { - // For local testing, change to 'staticFeeds/' - 'entry': 'data:application/json;base64,', - 'entrySuffix': '', - 'entries': null, - }, }, 'MISC_URLS': { 'rootURL': 'https://my.wisc.edu', diff --git a/src/main/webapp/json/sample-action-item.json b/src/main/webapp/json/sample-action-item.json deleted file mode 100644 index 39dd041..0000000 --- a/src/main/webapp/json/sample-action-item.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "quantity": 1 -} diff --git a/src/main/webapp/json/sample-action-items.json b/src/main/webapp/json/sample-action-items.json deleted file mode 100644 index 12cb4d5..0000000 --- a/src/main/webapp/json/sample-action-items.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "quantity": 5 -} diff --git a/src/main/webapp/json/sample-action-none.json b/src/main/webapp/json/sample-action-none.json deleted file mode 100644 index a243fda..0000000 --- a/src/main/webapp/json/sample-action-none.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "quantity": 0 -} diff --git a/src/main/webapp/json/starter-templates.json b/src/main/webapp/json/starter-templates.json deleted file mode 100644 index d658127..0000000 --- a/src/main/webapp/json/starter-templates.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "templates": [ - { - "entry": { - "layoutObject": { - "id": 5, - "type": "basic", - "widgetType": "basic", - "title": "Basic Widget", - "hasWidgetURL": false, - "description": "This default widget is super easy to set up!", - "mdIcon": "widgets", - "widgetConfig": { - "launchText": "Launch app" - }, - "url": "//www.example.com" - } - } - }, - { - "entry": { - "layoutObject": { - "id": 4, - "type": "widget-creator", - "widgetType": "custom", - "title": "Custom", - "hasWidgetURL": false, - "description": "This super cool portlet can change lives.", - "widgetConfig": {}, - "widgetTemplate": "

    Hello

    ", - "jsonSample": {}, - "url": "//www.example.com" - } - } - }, - { - "entry": { - "layoutObject": { - "id": 1, - "type": "search-with-links", - "widgetType": "search-with-links", - "title": "Search with Links", - "jsonSample": false, - "url": "//www.example.com", - "widgetConfig": { - "actionURL": "https://rprg.wisc.edu/search/", - "actionTarget": "_blank", - "actionParameter": "q", - "launchText": "Launch app", - "links": [ - { - "title": "Get started", - "href": "https://rprg.wisc.edu/phases/initiate/", - "icon": "fa-map-o", - "target": "_blank", - "rel": "noopener noreferrer" - }, - { - "title": "Resources", - "href": "https://rprg.wisc.edu/category/resource/", - "icon": "fa-th-list", - "target": "_blank", - "rel": "noopener noreferrer" - } - ] - }, - "hasWidgetURL": false - } - } - }, - { - "entry": { - "layoutObject": { - "id": 3, - "url": "//www.example.com", - "type": "list-of-links", - "widgetType": "list-of-links", - "title": "List of Links", - "jsonSample": false, - "hasWidgetURL": false, - "widgetConfig": { - "launchText": "See all", - "additionalText": "Additional Text", - "links": [ - { - "title": "The Google", - "href": "http://www.google.com", - "icon": "fa-google", - "target": "_blank", - "rel": "noopener noreferrer" - }, - { - "title": "Bing", - "href": "http://www.bing.com", - "icon": "fa-bed", - "target": "_blank", - "rel": "noopener noreferrer" - } - ] - }, - "description": "A simple list of links" - } - } - }, - { - "entry": { - "layoutObject": { - "id": 2, - "url": "//www.example.com", - "type": "rss", - "widgetType": "rss", - "title": "RSS Widget", - "jsonSample": false, - "widgetConfig": { - "lim": 6, - "target": "", - "showdate": true, - "titleLim": 40, - "dateFormat": "MM-dd-yyyy", - "showShowing": true - }, - "hasWidgetURL": true, - "widgetURL": "" - } - } - }, - { - "entry": { - "layoutObject": { - "id": 6, - "url": "//www.example.com", - "type": "action-items", - "widgetType": "action-items", - "title": "Action Items", - "description": "A list of items that need your attention", - "widgetConfig": { - "launchText": "See all items", - "actionItems": [ - { - "textSingular": "thing in empty feed.", - "textPlural": "things in empty feed.", - "feedUrl": "json/sample-action-none.json", - "actionUrl": "//www.example.com/#second-link" - }, - { - "textSingular": "item needs your attention.", - "textPlural": "items need your attention.", - "feedUrl": "json/sample-action-items.json", - "actionUrl": "//www.example.com/#first-link" - }, - { - "textSingular": "item needs your approval.", - "textPlural": "items need your approval.", - "feedUrl": "json/sample-action-item.json", - "actionUrl": "//www.example.com/#second-link" - } - ] - }, - "hasWidgetURL": false - } - } - } - ] -} diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index 81ca1e4..e5f23e3 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -2,149 +2,5 @@ define(['angular'], function(angular) { return angular.module('my-app.view-home.controllers', []) - // WIDGET CREATOR controller - .controller('WidgetCreatorController', [ - '$scope', '$log', 'widgetCreatorService', - function($scope, $log, widgetCreatorService) { - var starterTemplates = []; - /* ---------------- */ - /* Bindable members */ - /* ---------------- */ - $scope.templateOptions = [ - {'value': 'basic', 'name': 'Basic'}, - {'value': 'widget-creator', 'name': 'Custom'}, - {'value': 'rss', 'name': 'RSS widget'}, - {'value': 'list-of-links', 'name': 'List of links'}, - {'value': 'search-with-links', 'name': 'Search with links'}, - {'value': 'action-items', 'name': 'Action Items'}, - ]; - $scope.selectedTemplate = {}; - $scope.preview = undefined; - $scope.errorJSON = undefined; - $scope.errorConfigJSON = undefined; - /* --------------- */ - /* Scope functions */ - /* --------------- */ - - // Reload widget preview - $scope.reload = function() { - $scope.prepareWidgetDataForDisplay($scope.widget); - }; - - // Clear widget configuration - $scope.clear = function() { - if (confirm('Are you sure, all your config will be cleared')) { - $scope.init(); - } - }; - - // Change to newly-selected template type - $scope.changeTemplate = function() { - // Set widget equal to starter template that matches the selected type - angular.forEach(starterTemplates, function(value, key) { - if ($scope.selectedTemplate.value == value.entry.layoutObject.type) { - $scope.widget = $scope.widgetAsEditable(value.entry.layoutObject); - } - }); - $scope.reload(); - }; - - /* --------------- */ - /* Local functions */ - /* --------------- */ - - $scope.wrapLayout = function(preview) { - var wrapped = { - 'entry': { - 'layoutObject': preview, - }, - }; - return btoa(angular.toJson(wrapped)); - }; - - /** - * Check if json is valid - * @param {String} json the json to parse - * @return {Object|undefined} - */ - $scope.parseJSON = function parseJSON(json) { - try { - return angular.fromJson(json); - } catch (e) { - return undefined; - } - }; - - /** - * Convert JSON objects to strings so they can be displayed in HTML - * @param {Object} editable The object used to store user edits - */ - $scope.prepareWidgetDataForDisplay = function(editable) { - var preview = angular.copy(editable); - var widgetConfig = $scope.parseJSON(editable.widgetConfig); - var sample = $scope.parseJSON(editable.sample); - - $scope.errorJSON = (!sample) ? 'JSON NOT VALID' : undefined; - $scope.errorConfigJSON = (!widgetConfig) ? 'JSON NOT VALID' : undefined; - - if (widgetConfig && (!editable.jsonSample || sample)) { - preview.widgetConfig = widgetConfig; - if (sample) { - preview.widgetURL = 'data:application/json;base64,' - + btoa(angular.toJson(sample)); - } - $scope.preview = $scope.wrapLayout(preview); - } - }; - - /** - * Takes a valid widget configuration and creates an user-editable version. - * @param {Object} widget widget configuration - * @return {Object} user-editable widget config - */ - $scope.widgetAsEditable = function(widget) { - var editable = angular.copy(widget); - $scope.errorConfigJSON = undefined; - if (!angular.isString(editable.widgetConfig)) { - editable.widgetConfig = angular.toJson(editable.widgetConfig); - } - $scope.errorJSON = undefined; - if (editable.jsonSample) { - editable.sample = angular.toJson(editable.jsonSample); - } - return editable; - }; - - /** - * Initialize widget creator - * @return {Promise} starter templates - */ - $scope.init = function() { - return widgetCreatorService.getStarterTemplates() - .then(function(templates) { - starterTemplates = templates; - $log.log('Got starter templates'); - if (templates[0].entry.layoutObject) { - // Set default widget type - $scope.widget = $scope.widgetAsEditable( - templates[0].entry.layoutObject); - $scope.prepareWidgetDataForDisplay($scope.widget); - - // Set selected template - angular.forEach($scope.templateOptions, function(value, key) { - if ($scope.widget.type === value.value) { - $scope.selectedTemplate = value; - } - }); - } - return templates; - }); - }; - - $scope.init().catch(function(error) { - $log.warn('WidgetCreatorController couldn\'t get starter templates'); - $log.error(error); - }); - }]); }); diff --git a/src/main/webapp/my-app/view-home/directives.js b/src/main/webapp/my-app/view-home/directives.js index b684968..3830d5b 100644 --- a/src/main/webapp/my-app/view-home/directives.js +++ b/src/main/webapp/my-app/view-home/directives.js @@ -2,23 +2,5 @@ define(['angular', 'require'], function(angular, require) { return angular.module('my-app.view-home.directives', []) - .directive('previewWidget', function() { - return { - restrict: 'E', - transclude: true, - scope: { - fname: '@', - }, - templateUrl: require.toUrl( - '../../portal/widgets/partials/widget-card.html'), - controller: 'WidgetCardController', - link: function(scope, element, attrs) { - scope.$watch('fname', function(newValue, oldValue) { - if (newValue) { - scope.initializeWidget(newValue); - } - }); - }, - }; - }); + }); diff --git a/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js index fd8d7fd..b4ca3b4 100644 --- a/src/main/webapp/my-app/view-home/services.js +++ b/src/main/webapp/my-app/view-home/services.js @@ -2,22 +2,5 @@ define(['angular'], function(angular) { return angular.module('my-app.view-home.services', []) - .factory('widgetCreatorService', [ - '$log', '$http', 'SERVICE_LOC', - function($log, $http, SERVICE_LOC) { - var getStarterTemplates = function() { - return $http.get(SERVICE_LOC.templates + '.json') - .then(function(result) { - return result.data.templates; - }) - .catch(function(error) { - $log.warn('Error getting starter templates'); - $log.error(error); - }); - }; - return { - 'getStarterTemplates': getStarterTemplates, - }; - }]); }); From 15b882330e8bde6b8538aca8b94d95236091a8ad Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Fri, 22 Sep 2017 14:51:34 -0500 Subject: [PATCH 45/51] Remove widget-creator content --- .../webapp/my-app/view-home/view-home.html | 103 ++---------------- 1 file changed, 9 insertions(+), 94 deletions(-) diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index 20280fa..da1b79f 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -1,96 +1,11 @@ -
    - -
    -
    +FRAME PAGE - - - - - Smart Widget Configuration -

    Read - widget documentation. -

    -
    -
    - -
    -
    -

    Choose a starter template

    - or select 'Custom' to make your own. +TO DO + +- Add some content +- Add a controller +- Add a directive +- Add a service +- Update README +- Update docs - - - {{ option.name }} - -
    - - - - - - - - - - - - - - -
    See available icons here.
    -
    - - - - - - - - - -
    This is usually returned by the widgetURL. The results are stored in the $scope.content variable.
    -
    - - - - -
    Valid JSON provided by the widget's widgetConfig.
    -
    - - - - - - - - - - -
    - -
    - Clear - Update -
    - -
    -

    HINT: Most fields require you to click Update before changes appear.

    -
    -
    -
    - -
    -
    - -
    -
    - Clear - Update -
    -
    -
    -
    -
    From a0021ee02731d4d0906b3c9e70955aa9a98c1341 Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Mon, 25 Sep 2017 11:42:36 -0500 Subject: [PATCH 46/51] Add content, unit test, and example architecture --- docs/README.md | 5 +- package-lock.json | 2 +- src/main/webapp/js/override.js | 11 ++- src/main/webapp/json/helpful-links.json | 29 ++++++++ src/main/webapp/my-app/my-app.css | 67 +------------------ .../my-app/templates/example-options.html | 11 +++ .../webapp/my-app/view-home/controllers.js | 36 ++++++++++ .../webapp/my-app/view-home/directives.js | 9 ++- .../view-home/partials/example-subview.html | 10 +++ src/main/webapp/my-app/view-home/services.js | 26 +++++++ .../my-app/view-home/spec/view-home-spec.js | 44 ++++++------ .../webapp/my-app/view-home/view-home.html | 25 ++++--- 12 files changed, 169 insertions(+), 106 deletions(-) create mode 100644 src/main/webapp/json/helpful-links.json create mode 100644 src/main/webapp/my-app/templates/example-options.html create mode 100644 src/main/webapp/my-app/view-home/partials/example-subview.html diff --git a/docs/README.md b/docs/README.md index 20e396b..2a180c1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,8 @@ My App Seed is a demo app used to help developers learn to make -[uPortal-App-Framework applications](https://github.com/UW-Madison-DoIT/uw-frame). +[uPortal-app-framework applications](https://github.com/uPortal-Project/uportal-app-framework). # How to run locally ```bash -mvn jetty:run +npm install +mvn clean package install jetty:run-war ``` diff --git a/package-lock.json b/package-lock.json index 9ef718a..e4a91d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "widget-creator", + "name": "my-app-seed", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 243dc6d..9f11996 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -8,15 +8,20 @@ define(['angular'], function(angular) { 'isWeb': false, 'loginOnLoad': false, }, - 'NAMES': { - 'title': 'My App Seed', - 'fname': 'my-app-seed', + 'APP_OPTIONS': { + 'optionsTemplateURL': 'my-app/templates/example-options.html', }, 'SERVICE_LOC': { + 'messagesURL': '', // Delete to get portal-wide notifications 'kvURL': null, 'groupURL': 'staticFeeds/groups.json', 'sessionInfo': 'staticFeeds/guest-session.json', 'shibbolethSessionURL': 'staticFeeds/Shibboleth.sso/Session.json', + 'helpfulLinks': 'json/helpful-links.json', + }, + 'NAMES': { + 'title': 'My App Seed', + 'fname': 'my-app-seed', }, 'MISC_URLS': { 'rootURL': 'https://my.wisc.edu', diff --git a/src/main/webapp/json/helpful-links.json b/src/main/webapp/json/helpful-links.json new file mode 100644 index 0000000..2ebc0a1 --- /dev/null +++ b/src/main/webapp/json/helpful-links.json @@ -0,0 +1,29 @@ +{ + "links": [ + { + "label": "uPortal-app-framework documentation", + "description": "MyUW apps are built upon the uPortal-app-framework. Its documentation includes best practices and implementation info about project configuration, access control, in-app messaging, and more.", + "url": "http://uportal-project.github.io/uportal-app-framework/" + }, + { + "label": "AngularJS Material documentation", + "description": "All of the CSS classes and directives in AngularJS Material are available for you to use.", + "url": "https://material.angularjs.org/latest/layout/introduction" + }, + { + "label": "AngularJS Material layout directives", + "description": "Using these directives can help you prototype faster by eliminating dependence on additional third-party libraries and custom CSS.", + "url": "https://material.angularjs.org/latest/layout/introduction" + }, + { + "label": "Material icons", + "description": "See all the Material Design icons at your disposal.", + "url": "https://material.io/icons" + }, + { + "label": "John Papa angularJS style guide", + "description": "Though we do not strictly conform to John Papa's code standards, the uPortal-app-framework team strives to do so whenever possible." + "url": "https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md" + } + ] +} diff --git a/src/main/webapp/my-app/my-app.css b/src/main/webapp/my-app/my-app.css index af51152..7d67610 100644 --- a/src/main/webapp/my-app/my-app.css +++ b/src/main/webapp/my-app/my-app.css @@ -1,66 +1,3 @@ -.widget-creator .bold { - font-weight: 600; -} - -.widget-creator .portlet-body { - padding: 10px; -} - -.widget-creator .container__select-template { - padding-bottom: 20px; -} - -.widget-creator preview-widget { - width: 300px; -} - -.widget-creator .help-notes p { - color: #999; - font-size: 12px; - margin-bottom: 0; -} - -.widget-creator textarea { - padding: 10px 14px; - overflow-y: scroll; -} - -.widget-creator .hint { - position: absolute; - left: 2px; - right: auto; - bottom: 7px; - font-size: 12px; - line-height: 14px; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - color: grey; -} - -.widget-creator md-input-container.has-hint { - margin-bottom: 32px; -} - -.widget-creator ::-webkit-input-placeholder { - color: @grayscale6; - font-size: 12px; -} - -.widget-creator :-moz-placeholder { /* Firefox 18- */ - color: @grayscale6; - font-size: 12px; -} - -.widget-creator ::-moz-placeholder { /* Firefox 19+ */ - color: @grayscale6; - font-size: 12px; -} - -.widget-creator :-ms-input-placeholder { - color: @grayscale6; - font-size: 12px; -} - -.widget-middle { - width: 315px; - margin: auto; +.view-home { + padding: 8px 18px; } diff --git a/src/main/webapp/my-app/templates/example-options.html b/src/main/webapp/my-app/templates/example-options.html new file mode 100644 index 0000000..4ed7fa7 --- /dev/null +++ b/src/main/webapp/my-app/templates/example-options.html @@ -0,0 +1,11 @@ + + + settings + Settings + + + + Checkout Repo + + + diff --git a/src/main/webapp/my-app/view-home/controllers.js b/src/main/webapp/my-app/view-home/controllers.js index e5f23e3..a629586 100644 --- a/src/main/webapp/my-app/view-home/controllers.js +++ b/src/main/webapp/my-app/view-home/controllers.js @@ -2,5 +2,41 @@ define(['angular'], function(angular) { return angular.module('my-app.view-home.controllers', []) + .controller('HomeViewController', ['resourcesService', '$window', '$log', + function(resourcesService, $window, $log) { + var vm = this; + // Bindable members + vm.links = []; + + // Scope functions + /** + * Go to the provided URL + * @param url String + */ + vm.goToUrl = function(url) { + $window.location.href = url; + }; + + // Local functions + /** + * When the controller is initialized, get the list of resources from + * the resources service. + */ + var init = function() { + // Get links from service + resourcesService.getHelpfulLinks() + .then(function(data) { + if (data.links.length > 0) { + vm.links = data.links; + } + return data; + }) + .catch(function(error) { + $log.log('Problem getting links from resources service.'); + }); + }; + + init(); + }]); }); diff --git a/src/main/webapp/my-app/view-home/directives.js b/src/main/webapp/my-app/view-home/directives.js index 3830d5b..080cc48 100644 --- a/src/main/webapp/my-app/view-home/directives.js +++ b/src/main/webapp/my-app/view-home/directives.js @@ -2,5 +2,12 @@ define(['angular', 'require'], function(angular, require) { return angular.module('my-app.view-home.directives', []) - + .directive('subview', function() { + return { + restrict: 'E', + templateUrl: require.toUrl('./partials/example-subview.html'), + controller: 'HomeViewController', + controllerAs: 'vm', + }; + }); }); diff --git a/src/main/webapp/my-app/view-home/partials/example-subview.html b/src/main/webapp/my-app/view-home/partials/example-subview.html new file mode 100644 index 0000000..669c92f --- /dev/null +++ b/src/main/webapp/my-app/view-home/partials/example-subview.html @@ -0,0 +1,10 @@ + + Other helpful resources + + +
    +

    {{ link.label }}

    +

    {{ link.description }}

    +
    +
    +
    diff --git a/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js index b4ca3b4..9715849 100644 --- a/src/main/webapp/my-app/view-home/services.js +++ b/src/main/webapp/my-app/view-home/services.js @@ -2,5 +2,31 @@ define(['angular'], function(angular) { return angular.module('my-app.view-home.services', []) + .factory('resourcesService', ['$log', '$http', 'SERVICE_LOC', + function($log, $http, SERVICE_LOC) { + var getHelpfulLinks = function() { + return $http.get(SERVICE_LOC.helpfulLinks) + .then(function(result) { + return result.data; + }) + .catch(function(error) { + $log.log('Could not get links from ' + SERVICE_LOC.helpfulLinks); + }); + }; + var getSessionInfo = function() { + return $http.get(SERVICE_LOC.sessionInfo) + .then(function(result) { + return result.data; + }) + .catch(function(error) { + $log.error(error); + }); + }; + + return { + 'getHelpfulLinks': getHelpfulLinks, + 'getSessionInfo': getSessionInfo, + }; + }]); }); diff --git a/src/main/webapp/my-app/view-home/spec/view-home-spec.js b/src/main/webapp/my-app/view-home/spec/view-home-spec.js index 20048a9..f0fdfa2 100644 --- a/src/main/webapp/my-app/view-home/spec/view-home-spec.js +++ b/src/main/webapp/my-app/view-home/spec/view-home-spec.js @@ -2,45 +2,43 @@ /* eslint-env node */ /* global inject readJSON */ define(['angular-mocks', 'my-app'], function() { - describe('WidgetCreatorController', function() { + describe('HomeViewController', function() { var scope; var deferred; var service; - var templateURL; - var templates; + var linksURL; + var links; + beforeEach(function() { module('my-app'); }); beforeEach(inject(function( - _$controller_, _$q_, _$rootScope_, _$templateCache_, - _widgetCreatorService_, _SERVICE_LOC_) { + _$controller_, _$q_, _$rootScope_, + _resourcesService_, _SERVICE_LOC_) { scope = _$rootScope_.$new(); - templateURL = _SERVICE_LOC_.templates + '.json'; - templates = readJSON(templateURL).templates; - spyOn(_$templateCache_, 'get').and.callFake(function(path) { - return '
    '; - }); - service = _widgetCreatorService_; + linksURL = _SERVICE_LOC_.helpfulLinks + '.json'; + links = readJSON(linksURL).links; + + service = _resourcesService_; deferred = _$q_.defer(); - spyOn(service, 'getStarterTemplates') - .and.returnValue(deferred.promise); - _$controller_('WidgetCreatorController', { + spyOn(service, 'getHelpfulLinks') + .and.returnValue(deferred.promise); + + _$controller_('HomeViewController', { '$scope': scope, - 'widgetCreatorService': service, + 'resourcesService': service, }); - deferred.resolve(templates); + + deferred.resolve(links); scope.$apply(); })); - it('should set selectedTemplate in scope', function() { - expect(scope.selectedTemplate).toBeTruthy(); - expect(scope.selectedTemplate).not.toEqual({}); - }); - - it('should set the preview widget configuration', function() { - expect(scope.preview).toBeTruthy(); + it('should set links in scope', function() { + // Test vm.links + // expect(vm.links).toBeTruthy(); + // expect(vm.links).not.toEqual([]); }); }); }); diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index da1b79f..6024964 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -1,11 +1,14 @@ -FRAME PAGE - -TO DO - -- Add some content -- Add a controller -- Add a directive -- Add a service -- Update README -- Update docs - + + + +

    Example view

    +

    This view uses the frame-page directive, which automatically includes the dark gray app header, in-app options (if provided in override.js), and other styles/content that make it look like a MyUW app. See the directives documentation for more information.

    + +
    +
    From afe8ca547c4ece28088560600c0c0787a99fcee9 Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 26 Sep 2017 12:07:54 -0500 Subject: [PATCH 47/51] Add unit test --- src/main/webapp/js/override.js | 2 +- src/main/webapp/json/helpful-links.json | 2 +- src/main/webapp/my-app/view-home/services.js | 2 +- .../my-app/view-home/spec/view-home-spec.js | 67 ++++++++++--------- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/main/webapp/js/override.js b/src/main/webapp/js/override.js index 9f11996..c8aa6e4 100644 --- a/src/main/webapp/js/override.js +++ b/src/main/webapp/js/override.js @@ -17,7 +17,7 @@ define(['angular'], function(angular) { 'groupURL': 'staticFeeds/groups.json', 'sessionInfo': 'staticFeeds/guest-session.json', 'shibbolethSessionURL': 'staticFeeds/Shibboleth.sso/Session.json', - 'helpfulLinks': 'json/helpful-links.json', + 'helpfulLinks': 'json/helpful-links', }, 'NAMES': { 'title': 'My App Seed', diff --git a/src/main/webapp/json/helpful-links.json b/src/main/webapp/json/helpful-links.json index 2ebc0a1..cf67068 100644 --- a/src/main/webapp/json/helpful-links.json +++ b/src/main/webapp/json/helpful-links.json @@ -22,7 +22,7 @@ }, { "label": "John Papa angularJS style guide", - "description": "Though we do not strictly conform to John Papa's code standards, the uPortal-app-framework team strives to do so whenever possible." + "description": "Though we do not strictly conform to John Papa's code standards, the uPortal-app-framework team strives to do so whenever possible.", "url": "https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md" } ] diff --git a/src/main/webapp/my-app/view-home/services.js b/src/main/webapp/my-app/view-home/services.js index 9715849..16aeef5 100644 --- a/src/main/webapp/my-app/view-home/services.js +++ b/src/main/webapp/my-app/view-home/services.js @@ -5,7 +5,7 @@ define(['angular'], function(angular) { .factory('resourcesService', ['$log', '$http', 'SERVICE_LOC', function($log, $http, SERVICE_LOC) { var getHelpfulLinks = function() { - return $http.get(SERVICE_LOC.helpfulLinks) + return $http.get(SERVICE_LOC.helpfulLinks + '.json') .then(function(result) { return result.data; }) diff --git a/src/main/webapp/my-app/view-home/spec/view-home-spec.js b/src/main/webapp/my-app/view-home/spec/view-home-spec.js index f0fdfa2..c67235e 100644 --- a/src/main/webapp/my-app/view-home/spec/view-home-spec.js +++ b/src/main/webapp/my-app/view-home/spec/view-home-spec.js @@ -3,42 +3,49 @@ /* global inject readJSON */ define(['angular-mocks', 'my-app'], function() { describe('HomeViewController', function() { - var scope; - var deferred; - var service; - var linksURL; - var links; + // Test variables + var $controller; + var vm; + var scope; + var service; + var linksURL; + var linksJSON; + var deferred; + // Inject the application module + beforeEach(function() { + module('my-app'); + }); - beforeEach(function() { - module('my-app'); - }); - - beforeEach(inject(function( - _$controller_, _$q_, _$rootScope_, - _resourcesService_, _SERVICE_LOC_) { - scope = _$rootScope_.$new(); - linksURL = _SERVICE_LOC_.helpfulLinks + '.json'; - links = readJSON(linksURL).links; + beforeEach(inject(function(_$controller_, _$rootScope_, _$q_, + _resourcesService_, _SERVICE_LOC_) { + $controller = _$controller_; + scope = _$rootScope_.$new(); + service = _resourcesService_; + linksURL = _SERVICE_LOC_.helpfulLinks + '.json'; + linksJSON = readJSON(linksURL); + deferred = _$q_.defer(); - service = _resourcesService_; - deferred = _$q_.defer(); - spyOn(service, 'getHelpfulLinks') - .and.returnValue(deferred.promise); + // Intercept service request and pass deferred promise + spyOn(service, 'getHelpfulLinks') + .and.returnValue(deferred.promise); - _$controller_('HomeViewController', { - '$scope': scope, - 'resourcesService': service, - }); + vm = $controller('HomeViewController', { + '$scope': scope, + 'resourcesService': service, + }); - deferred.resolve(links); - scope.$apply(); - })); + // When promise resolution is triggered, pass back the + // helpful links + deferred.resolve(linksJSON); + scope.$apply(); + })); - it('should set links in scope', function() { - // Test vm.links - // expect(vm.links).toBeTruthy(); - // expect(vm.links).not.toEqual([]); + describe('initialize controller', function() { + it('should set resource links in scope', function() { + expect(vm.links).toBeTruthy(); + expect(vm.links).not.toEqual([]); }); + }); }); }); From 856b3472d80787d526949f1797c567a30dcdcfec Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 26 Sep 2017 12:13:24 -0500 Subject: [PATCH 48/51] Add responsive options template --- src/main/webapp/my-app/templates/example-options.html | 7 ++++++- src/main/webapp/my-app/view-home/view-home.html | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/my-app/templates/example-options.html b/src/main/webapp/my-app/templates/example-options.html index 4ed7fa7..a7c7dbe 100644 --- a/src/main/webapp/my-app/templates/example-options.html +++ b/src/main/webapp/my-app/templates/example-options.html @@ -1,4 +1,9 @@ - +
    + + Checkout Repo + +
    + settings Settings diff --git a/src/main/webapp/my-app/view-home/view-home.html b/src/main/webapp/my-app/view-home/view-home.html index 6024964..9e37427 100644 --- a/src/main/webapp/my-app/view-home/view-home.html +++ b/src/main/webapp/my-app/view-home/view-home.html @@ -8,7 +8,8 @@ white-background="true">

    Example view

    -

    This view uses the frame-page directive, which automatically includes the dark gray app header, in-app options (if provided in override.js), and other styles/content that make it look like a MyUW app. See the directives documentation for more information.

    +

    This view uses the frame-page directive, which automatically includes the dark gray app header, in-app options (if provided in override.js), + and other styles/content that make it look like a MyUW app. See the links below for more information.

    From f10f3e388ab5e492495e6f86694107984da135ce Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 26 Sep 2017 12:15:17 -0500 Subject: [PATCH 49/51] Add docs directories to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9cf63e0..4c1cd40 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ node_modules test_out docs/Gemfile.lock docs/_site/ +docs/_layouts/ +docs/_includes/ From 3047a15ba08f404b903bead9190736a68eeaf6fd Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 26 Sep 2017 12:16:39 -0500 Subject: [PATCH 50/51] Remove unused image --- .gitignore | 2 -- docs/img/selectorDropDown.png | Bin 35074 -> 0 bytes 2 files changed, 2 deletions(-) delete mode 100644 docs/img/selectorDropDown.png diff --git a/.gitignore b/.gitignore index 4c1cd40..9cf63e0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,3 @@ node_modules test_out docs/Gemfile.lock docs/_site/ -docs/_layouts/ -docs/_includes/ diff --git a/docs/img/selectorDropDown.png b/docs/img/selectorDropDown.png deleted file mode 100644 index 006e1f3a0745ad74ad3f01d7c5db76792da28ad6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35074 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
      ~Irj3SJFR0#S!84CoRX%kDiVD}%VkF?k9ycv9cq zgj)h^deY)O3ZseESz6j#04;h>lQTK zK=qk^SoyexckQGj^|9O06@=xL!x43G9&Jg)*Ho;BLr8IqUhB7o0<HFDR121Dm7{G(@~e2Mpj0et5Gg~#2x!)4A=01#mw$4 zisZQs=1z-W&7zJqt}cV-g}l=S;T+M4U3k^a_qgNCezL~>`abcXamQo z1i#|n{HVScy7;^g>&^ATE&amvj(63|fiz|ATU$7UTn&J?nlt{r>fV%nMyz?1HQq=+QO+)`?(2|9tlo{>HI-fnZw z;r%|55d4D7D~E|;=KELJa<{Elc4c1D%&12rjbX^WIgP|V3%=ZFmSZ!Cdq3Q`>G0C5 z5i~R3Rr)2YhLE;FrTS8TQLOd@3Vj+R^t_Jfk>ioLVrku#Zv6L>_5)(#kjhh=)1A4=eK{ht9t@(zVKS{w z62|jheWEiv?7a3(ZzKdx>9ac8>(89FH8# zl-i$lA3{D4x>D7@zB*~4GtMgz$-FraXVrY~+F!`e;ZMzeDztNqb*A!Xky5-- zn58c}s_d;&8q2Q*X2Ee@-*(Mg=QtHw_TD7)d&~;ix3z80MORP9249SZsl zGU^HTmHsSg<#QB3=HLBQT*vGP(+|1VO=a5U5_m`_eewH)?VJZ|ToZrh>GvIe^d%za zb_E=IU0ByQck;FCP-*5rDhuF6aUw)0h)}U7K_rwzkFD+K$0MKBRGYm$1d-)vfky9c z6V>jkm)vo)Ed)4ioG+;chc?d~Zh*Tt?ccz^5+IXdV7Yv0f;;K>qCRYrL8X!vj^1Z# z<_2~YOSc9GTZ8GP>pWsbB@7zQa4dhX6s`b;PhVTG>PaaPV^qKY>7+pgSbu(N%Z@T8B1A=cp8 zIw!g==x6=X>X#FIA}0P6vBnk16!DX-XQK6tf%k!zZ!4C%$h5iydq80bpp;|jDYQbf zSNv~QyZH{Vq$azvAjo(?nsWi`k87y6fHtl-rMD(G1G#A$J!)X5Cv zt$T9lTiGM#i~tlxbEjds(rbHK2o(LSKj3eNhA1HU?B~Vd2Dwik)&=8R_Ek{yyu!$% zv#pF^Z6@YLmUkDKtdUeeDUve&hkKlAW9U80*Zu2X>wFRBZ-1~b?-gr?7hz}6U?tz0Z*5{=^oC+7kY_X zDHH|Y+fb2Bn##RYKrl%)xRztGyFaEFvB3>ZYV#klf*VDjmuW~h$X)` zW7arZPQk1`iM;6JzUd~BtY0rP+#s=&x4^0cX^!Qbe!&?bj>Dbk*rF@6zRU2k9wIU0 zSo9&#;kO912#fZ1eSW7oTR|RVdP^pYL~ySuoEaU zS~kPL)Oh5Uc=juQAbD*Am!d^*ge3??A;Yxm&Ac{J)NwSuFU{n$UhLU%dpanDLfUiP z$=k<>tpT+6g6O-b2DZIv9xo1(IyamU95V+Nw1e0QMe@P)3_6ogxK8h~k5T86PJz-+ zAa3yr_`PCpnL6Okl(RWTelqkPX`N6i?c2mK>3>iQEzo9X!4nL7qbPKlFIrJBee^=@ z{-=fd>vS{c5}_SlFz!W(QuO#&G)%K(4<4`GmvS$Nq}{l`wa9mSzXmG!N&j_EIsy}j zyES>yrc0KmWik(z@7TIlgx(R{XksAqx9*A^IzpSwY^m4z{TO!^RG=bJ6qh)-2i#@a-6nlO(<8<@m{6pF>3?jhsR{Zojw_{AD9i> zvbH>!r|p@Dr{|f7Re=PhZn-r-C5z{5(1PgA$M&fQOaA#fb6-p*!#&nn>gX#*yD?#v z%n?I2Be8POpL8!}(mOClo8CIrcCU2vIsX#H|4nXq7A11)CTFLmW>@_2pwrCA+sx#o~SM3M{8+hTjTpX z2m^ib!{jp-UBpN+iHz@reqGHTvxU&QfGpM7WxjW9@1S&K2y1^9Y#lf&aLH8Mw|m*k zj6{_t?%7&A_t^>oSVWd}6>iOLlf|p+!%TwXCv4W>2 zm~t@Sv*&d9Gdg7^{Flbr6VsiOon{A=%cgkUI{RgX&h!o_*|l&}up94Jd@_q<-}J|B z2oH3?d|jy^e^4QhXGsD#aHz*W3-H-z6;L*sAwOn*JNYT6D!9U+47saZo61s=nKdvz zE~i*|+H^;2xhyqeaQN$^xx|N3A?5DJD9MUD?jNOHW#4FeI(mMh;DZ`%T^!~R!jB1( z)%CwRc9l}}*zoOz4|s2vd>d-tt=CWbc({~SgCM@2?4mKdvGK*jc&1ux)3-s!y?g(R z!o9$Rf~jS3&>%uL!tD}$`N@|;PRSjD0Vq!pG!ITq#6`s7HmI4`!fjI0rQ0Cbw>efy zs3Ell|Mh7hL$L93(c~R3-NOz+FM3g?9qV!nH3y++0h@1gju~q=s&l>Kf&AzmRs`s} zU%ZvUD>PvY?@2ik6E)hilk(ZD*L5fQ@F>5Yh+7*yO_PswIdm3j)M$x^%jI6~5-P@% zAr9H*x_F%&PEEaV#&x;ty_EaLKwWFCX@yF@=(|CpGu9_P{nzAz^BWS5cc z*Z=KZIbP{bm*WH|D~4sB@6J>aO*kB}uKR3^N$hkQ!-Wm&3TtW8n0T0lV~5&SqMRgc z6A7Bj9>!@?WWMDoib>_(Tw}(Gtq!AxRDyJakj3-D{!Bn431a&WF~a$k$zhC%CMk4& zZfjm+!$N%N`T`?1KjY5t&)lNyl9J1v&fFm! z;5CzsgtizkuyIjlg+KBZOHa0wHf5lk_#v9?wMcI}(_nOR?M!g<9eUYSruC=P-+QjJu(c_|B`pgFQ3-9hEJp- zg>q4MUM1Qqyrr(gnjNk(zq`WJGVKK)fDu0pSubEyq0zjOD|L3fa}=^TSpCw_SGcH> z>;HUA;0#xSlK$8t9En;iHJbAcjW;~OKZ#fl?$rgLuP4oWA z68pL$PY|+{)=bF{K2^H?)s;^>N5!z_-c=*rw-Ea5@cZAO;v$q;DXttbEx9qxW&{<3 zmb@E6eK(dO=6+8==xh`SHxw@-9gMAUO6~6Kj0y%sD0$|Nhf^YuwCE?wox?Zjcd6Vb zYR#bXX?T){Dzq^_{e6ubLZQ5fhwQ3|*FG{7dJ&wFA3Xl5!vUPKYr_UekB&VFG1Wbey2e^s zbcNm?hpG-k_E7V5O#6y4{E=9;C0n9PCFb`M=jm4lu85VLy2M|~XwkjOtT0xS{Z@LFgtS$BGNxAK|CvL z0nB7vwk@s<0igkvxxL<`Q99#byO9$jpNcz@OW*_x<%hr>!fB zkJq;jpEKu=u{Xtkr`eqhW?E5CBxZ7GWLv*TI9k7J#y`O~p~8Bsu*Weu3TDai8MtZe zOx(XJW#~i2avXzU{+%$&27Lw>QO6nks>#-e%0Bnl1UuC->Yw3ag6~#`1l)V2y3bJ; z03)dFrx#Xl^pugYRGC}oey<=J9}7d3B&pVvt8Vhn zm8pP}`WYL~9O} z>5aHOXbjJH+}|dasU#3!jX^K>+jzL z7xcv7((4BeFFH<-l-B)Lb0u!x87ZYjqo#Ut2Nby;Zatul{R!qis2Vs6u4EbXsaDdm z^TAyT@IIVKWd_0q(Ubg+? zfNDyB)eA9@^7b>5q)b;`^zcLPSjjlD?)5kc%2&s|R{kXG_c(?GUiw3kXQ=6CzQ?F8 zPMQ|gfUNk98_lv+sUE}{=V;1#?KLhnay94{UB!f*)XtZi2PqVOls-!b)$J6_#Y}7e z2>^dS(@YmkxAHL#b|;zWytkmSNST!;WMnp3yGypuA;sg|5chj}w#$N)k4)0*hVf&4 z5r9c@v-qsvu$``>*C;x?8nHYu%3bS2HC^wFqtRDFo5s)b2FkNT;FAwu+2^{f@;tg| zIPZK%Qs`Hx0w%WoH3tFgm39;1 z)0KW>R8;{Bc*BKpO>>u$KrF9Jj(_H2O&qq8PQ9Vn$@r%kLI}9nnvFc0Y4BUUbmJh7 z^&&Ascm$K1o!k;DVBokvy#!dXRv8bcCuYBuRc=nX$Qq|KoJj?NLA#&e`B^>sBj>K&Bxo78W1wUS_tGKEUa?JL7 zzR3x%y3C2IRYDeULdbld*M+{8ofzDGy;jvvLq1H4Y@jPmi>?S@wy>eMDuZCW^KkxQ zMO=@%e$Q)f?CI9QTx34}HAYceDB6%0Aw16ylXlu94}F#i4SPEfS@aImSx-b!ui=Sz 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 CX^m+B From 7405ee19caaedf036b9f1285d20cb70cce2fa542 Mon Sep 17 00:00:00 2001 From: zeke-witter Date: Tue, 26 Sep 2017 12:22:34 -0500 Subject: [PATCH 51/51] Avoid crashingt he unit test due to template GET --- src/main/webapp/my-app/view-home/spec/view-home-spec.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/my-app/view-home/spec/view-home-spec.js b/src/main/webapp/my-app/view-home/spec/view-home-spec.js index c67235e..e5dd64d 100644 --- a/src/main/webapp/my-app/view-home/spec/view-home-spec.js +++ b/src/main/webapp/my-app/view-home/spec/view-home-spec.js @@ -17,8 +17,8 @@ define(['angular-mocks', 'my-app'], function() { module('my-app'); }); - beforeEach(inject(function(_$controller_, _$rootScope_, _$q_, - _resourcesService_, _SERVICE_LOC_) { + beforeEach(inject(function(_$controller_, _$rootScope_, _$templateCache_, + _$q_, _resourcesService_, _SERVICE_LOC_) { $controller = _$controller_; scope = _$rootScope_.$new(); service = _resourcesService_; @@ -26,6 +26,11 @@ define(['angular-mocks', 'my-app'], function() { linksJSON = readJSON(linksURL); deferred = _$q_.defer(); + // Avoid 'unexpected GET' failures when getting HTML templates + spyOn(_$templateCache_, 'get').and.callFake(function(path) { + return '
      '; + }); + // Intercept service request and pass deferred promise spyOn(service, 'getHelpfulLinks') .and.returnValue(deferred.promise);