<commit_before>// framework/entities/behavior/Router.js
// ------------------

function DefaultAction() {
  delete this.__currentRouteDescription;
  this.$outlet.reset();
}

function RoutedAction(routeDescription) {
  if( !isUndefined(routeDescription.title) ) {
    document.title = isFunction(routeDescription.title) ? routeDescription.title.call(this, routeDescription.namedParams, this.urlParts()) : routeDescription.title;
  }

  if( isUndefined(this.__currentRouteDescription) || !sameRouteDescription(this.__currentRouteDescription, routeDescription) ) {
    (routeDescription.controller || noop).apply( this, values(routeDescription.namedParams) );
    this.__currentRouteDescription = routeDescription;
  }
}

function startupRouter($router, $context, $parentRouter ) {
  $parentRouter = $parentRouter || $nullRouter;

  if( !isNullRouter($parentRouter) ) {
    $router.parentRouter( $parentRouter );
  } else if( isObject($context) ) {
    $parentRouter = nearestParentRouter($context);
    if( $parentRouter !== $router ) {
      $router.parentRouter( $parentRouter );
    }
  }

  if( !$router.historyIsEnabled() ) {
    if( historyIsReady() && !$router.disableHistory() ) {
      History.Adapter.bind( windowObject, 'popstate', $router.stateChangeHandler = function(event) {
        var url = '';
        if(!fw.routers.html5History() && windowObject.location.hash.length > 1) {
          url = windowObject.location.hash;
        } else {
          url = windowObject.location.pathname + windowObject.location.hash;
        }

        $router.currentState( normalizeURL($router, url) );
      });
      $router.historyIsEnabled(true);
    } else {
      $router.historyIsEnabled(false);
    }
  }

  return $router;
};

function normalizeURL($router, url) {
  var urlParts = parseUri(url);
  $router.urlParts(urlParts);

  if(!fw.routers.html5History()) {
    if(url.indexOf('#') !== -1) {
      url = '/' + urlParts.anchor.replace(startingSlashRegex, '');
    } else if($router.currentState() !== url) {
      url = '/';
    }
  } else {
    url = urlParts.path;
  }

  return trimBaseRoute($router, url);
};

function getRouteForURL($router, url) {
  var route = null;
  var parentRoutePath = $router.parentRouter().path() || '';
  var unknownRoute = getUnknownRoute($router);

  // If this is a relative router we need to remove the leading parentRoutePath section of the URL
  if($router.isRelative() && parentRoutePath.length > 0 && (routeIndex = url.indexOf(parentRoutePath + '/')) === 0) {
    url = url.substr( parentRoutePath.length );
  }

  // find all routes with a matching routeString
  var matchedRoutes = reduce($router.routeDescriptions, function(matches, routeDescription) {
    var routeString = routeDescription.route;
    var routeParams = [];

    if( isString(routeString) ) {
      routeParams = url.match(routeStringToRegExp(routeString));
      if( !isNull(routeParams) && routeDescription.filter.call($router, routeParams, $router.urlParts.peek()) ) {
        matches.push({
          routeString: routeString,
          specificity: routeString.replace(namedParamRegex, "*").length,
          routeDescription: routeDescription,
          routeParams: routeParams
        });
      }
    }
    return matches;
  }, []);

  // If there are matchedRoutes, find the one with the highest 'specificity' (longest normalized matching routeString)
  // and convert it into the actual route
  if(matchedRoutes.length) {
    var matchedRoute = reduce(matchedRoutes, function(matchedRoute, foundRoute) {
      if( isNull(matchedRoute) || foundRoute.specificity > matchedRoute.specificity ) {
        matchedRoute = foundRoute;
      }
      return matchedRoute;
    }, null);
    var routeDescription = matchedRoute.routeDescription;
    var routeString = matchedRoute.routeString;
    var routeParams = clone(matchedRoute.routeParams);
    var splatSegment = routeParams.pop() || '';
    var routeParamNames = map(routeString.match(namedParamRegex), function(param) {
      return param.replace(':', '');
    });
    var namedParams = reduce(routeParamNames, function(parameterNames, parameterName, index) {
      parameterNames[parameterName] = routeParams[index + 1];
      return parameterNames;
    }, {});

    route = extend({}, baseRoute, {
      id: routeDescription.id,
      controller: routeDescription.controller,
      title: routeDescription.title,
      url: url,
      segment: url.substr(0, url.length - splatSegment.length),
      indexedParams: routeParams,
      namedParams: namedParams
    });
  }

  return route || unknownRoute;
};

function getActionForRoute($router, routeDescription) {
  var Action;

  if( isRoute(routeDescription) ) {
    Action = RoutedAction.bind($router, routeDescription);
  }

  return Action || DefaultAction.bind($router);
};

function getUnknownRoute($router) {
  var unknownRoute = findWhere(($router.routeDescriptions || []).reverse(), { unknown: true }) || null;

  if( !isNull(unknownRoute) ) {
    unknownRoute = extend({}, baseRoute, {
      id: unknownRoute.id,
      controller: unknownRoute.controller,
      title: unknownRoute.title,
      segment: ''
    });
  }

  return unknownRoute;
};

var routeEntityDesc;
runPostInit.push(function() {
  routeEntityDesc = entityDescriptors.getDescriptor('router');
});

var Router = function(descriptor, configParams) {
  return {
    _preInit: function( params ) {
      var subscriptions = this.__subscriptions = fw.observableArray();

      this.$namespace.command.handler('setState', this.setState, this);
      this.$namespace.request.handler('currentRoute', function() { return this.currentRoute(); }, this);
      this.$namespace.request.handler('urlParts', function() { return this.urlParts(); }, this);

      this.urlParts = fw.observable();
      this.childRouters = fw.observableArray();
      this.parentRouter = fw.observable($nullRouter);
      this.context = fw.observable();
      this.historyIsEnabled = fw.observable(false);
      this.disableHistory = fw.observable().receiveFrom(this.$globalNamespace, 'disableHistory');
      this.currentState = fw.observable('').broadcastAs('currentState');
      configParams.baseRoute = fw.routers.baseRoute() + (result(configParams, 'baseRoute') || '');

      this.isRelative = fw.computed(function() {
        return configParams.isRelative && !isNullRouter( this.parentRouter() );
      }, this);

      this.currentRoute = fw.computed(function() {
        return getRouteForURL(this, normalizeURL(this, this.currentState()) );
      }, this);

      this.path = fw.computed(function() {
        var currentRoute = this.currentRoute();
        var routeSegment = '/';

        if( isRoute(currentRoute) ) {
          routeSegment = (currentRoute.segment === '' ? '/' : currentRoute.segment);
        }

        return (this.isRelative() ? this.parentRouter().path() : '') + routeSegment;
      }, this);

      var parentPathSubscription;
      var $router = this;
      var $previousParent = $nullRouter;
      subscriptions.push(this.parentRouter.subscribe(function( $parentRouter ) {
        if( !isNullRouter($previousParent) && $previousParent !== $parentRouter ) {
          $previousParent.childRouters.remove(this);

          if(parentPathSubscription) {
            subscriptions.remove(parentPathSubscription);
            parentPathSubscription.dispose();
          }
          subscriptions.push(parentPathSubscription = $parentRouter.path.subscribe(function triggerRouteRecompute() {
            $router.currentState.notifySubscribers();
          }));
        }
        $parentRouter.childRouters.push(this);
        $previousParent = $parentRouter;
      }, this));

      // Automatically trigger the new Action() whenever the currentRoute() updates
      subscriptions.push( this.currentRoute.subscribe(function getActionForRouteAndTrigger( newRoute ) {
        if(this.currentState().length) {
          getActionForRoute(this, newRoute )( /* get and call the action for the newRoute */ );
        }
      }, this) );

      this.outlets = {};
      this.$outlet = $routerOutlet.bind(this);
      this.$outlet.reset = function() {
        each( this.outlets, function(outlet) {
          outlet({ name: noComponentSelected, params: {} });
        });
      }.bind(this);

      if( !isUndefined(configParams.unknownRoute) ) {
        if( isFunction(configParams.unknownRoute) ) {
          configParams.unknownRoute = { controller: configParams.unknownRoute };
        }
        configParams.routes.push( extend( configParams.unknownRoute, { unknown: true } ) );
      }
      this.setRoutes( configParams.routes );

      if( configParams.activate === true ) {
        subscriptions.push(this.context.subscribe(function activateRouterAfterNewContext( $context ) {
          if( isObject($context) ) {
            this.activate($context);
          }
        }, this));
      }

      this.$namespace.exit();
    },
    mixin: {
      setRoutes: function(routeDesc) {
        this.routeDescriptions = [];
        this.addRoutes(routeDesc);
        return this;
      },
      addRoutes: function(routeConfig) {
        this.routeDescriptions = this.routeDescriptions.concat( map(isArray(routeConfig) ? routeConfig : [routeConfig], transformRouteConfigToDesc) );
        return this;
      },
      activate: function($context, $parentRouter) {
        $context = $context || this.context();
        startupRouter(this, $context, $parentRouter || nearestParentRouter($context) );
        if( this.currentState() === '' ) {
          this.setState();
        }
        return this;
      },
      setState: function(url) {
        if( this.historyIsEnabled() && !this.disableHistory() ) {
          if(isString(url)) {
            var historyAPIWorked = true;
            try {
              historyAPIWorked = History.pushState(null, '', this.__getConfigParams().baseRoute + this.parentRouter().path() + url.replace(startingHashRegex, '/'));
            } catch(historyException) {
              console.error(historyException);
              historyAPIWorked = false;
            } finally {
              if(historyAPIWorked) {
                return;
              }
            }
          } else if(isFunction(History.getState)) {
            this.currentState( normalizeURL(this, History.getState().url ) );
          }
        } else if(isString(url)) {
          this.currentState( normalizeURL(this, url ) );
        } else {
          this.currentState('/');
        }

        if(!historyIsReady()) {
          var routePath = this.path();
          each(this.childRouters(), function(childRouter) {
            childRouter.currentState(routePath);
          });
        }

        return this;
      },
      dispose: function() {
        var $parentRouter = this.parentRouter();
        if( !isNullRouter($parentRouter) ) {
          $parentRouter.childRouters.remove(this);
        }

        if( this.historyIsEnabled() && historyIsReady() ) {
          History.Adapter.unbind( this.stateChangeHandler );
        }

        this.$namespace.dispose();
        this.$globalNamespace.dispose();

        invoke(this.__subscriptions(), 'dispose');
        each(omit(this, function(property) {
          return isEntity(property);
        }), propertyDisposal);
      }
    }
  };
};
<commit_msg>more router cleanup<commit_after>// framework/entities/behavior/Router.js
// ------------------

function DefaultAction() {
  delete this.__currentRouteDescription;
  this.$outlet.reset();
}

function RoutedAction(routeDescription) {
  if( !isUndefined(routeDescription.title) ) {
    document.title = isFunction(routeDescription.title) ? routeDescription.title.call(this, routeDescription.namedParams, this.urlParts()) : routeDescription.title;
  }

  if( isUndefined(this.__currentRouteDescription) || !sameRouteDescription(this.__currentRouteDescription, routeDescription) ) {
    (routeDescription.controller || noop).apply( this, values(routeDescription.namedParams) );
    this.__currentRouteDescription = routeDescription;
  }
}

function activateRouter($router, $context, $parentRouter ) {
  $parentRouter = $parentRouter || $nullRouter;

  if( !isNullRouter($parentRouter) ) {
    $router.parentRouter( $parentRouter );
  } else if( isObject($context) ) {
    $parentRouter = nearestParentRouter($context);
    if( $parentRouter !== $router ) {
      $router.parentRouter( $parentRouter );
    }
  }

  if( !$router.historyIsEnabled() ) {
    if( historyIsReady() && !$router.disableHistory() ) {
      History.Adapter.bind( windowObject, 'popstate', $router.stateChangeHandler = function(event) {
        var url = '';
        if(!fw.routers.html5History() && windowObject.location.hash.length > 1) {
          url = windowObject.location.hash;
        } else {
          url = windowObject.location.pathname + windowObject.location.hash;
        }

        $router.currentState( normalizeURL($router, url) );
      });
      $router.historyIsEnabled(true);
    } else {
      $router.historyIsEnabled(false);
    }
  }

  return $router;
};

function normalizeURL($router, url) {
  var urlParts = parseUri(url);
  $router.urlParts(urlParts);

  if(!fw.routers.html5History()) {
    if(url.indexOf('#') !== -1) {
      url = '/' + urlParts.anchor.replace(startingSlashRegex, '');
    } else if($router.currentState() !== url) {
      url = '/';
    }
  } else {
    url = urlParts.path;
  }

  return trimBaseRoute($router, url);
};

function getRouteForURL($router, url) {
  var route = null;
  var parentRoutePath = $router.parentRouter().path() || '';
  var unknownRoute = getUnknownRoute($router);

  // If this is a relative router we need to remove the leading parentRoutePath section of the URL
  if($router.isRelative() && parentRoutePath.length > 0 && (routeIndex = url.indexOf(parentRoutePath + '/')) === 0) {
    url = url.substr( parentRoutePath.length );
  }

  // find all routes with a matching routeString
  var matchedRoutes = reduce($router.routeDescriptions, function(matches, routeDescription) {
    var routeString = routeDescription.route;
    var routeParams = [];

    if( isString(routeString) ) {
      routeParams = url.match(routeStringToRegExp(routeString));
      if( !isNull(routeParams) && routeDescription.filter.call($router, routeParams, $router.urlParts.peek()) ) {
        matches.push({
          routeString: routeString,
          specificity: routeString.replace(namedParamRegex, "*").length,
          routeDescription: routeDescription,
          routeParams: routeParams
        });
      }
    }
    return matches;
  }, []);

  // If there are matchedRoutes, find the one with the highest 'specificity' (longest normalized matching routeString)
  // and convert it into the actual route
  if(matchedRoutes.length) {
    var matchedRoute = reduce(matchedRoutes, function(matchedRoute, foundRoute) {
      if( isNull(matchedRoute) || foundRoute.specificity > matchedRoute.specificity ) {
        matchedRoute = foundRoute;
      }
      return matchedRoute;
    }, null);
    var routeDescription = matchedRoute.routeDescription;
    var routeString = matchedRoute.routeString;
    var routeParams = clone(matchedRoute.routeParams);
    var splatSegment = routeParams.pop() || '';
    var routeParamNames = map(routeString.match(namedParamRegex), function(param) {
      return param.replace(':', '');
    });
    var namedParams = reduce(routeParamNames, function(parameterNames, parameterName, index) {
      parameterNames[parameterName] = routeParams[index + 1];
      return parameterNames;
    }, {});

    route = extend({}, baseRoute, {
      id: routeDescription.id,
      controller: routeDescription.controller,
      title: routeDescription.title,
      url: url,
      segment: url.substr(0, url.length - splatSegment.length),
      indexedParams: routeParams,
      namedParams: namedParams
    });
  }

  return route || unknownRoute;
};

function getUnknownRoute($router) {
  var unknownRoute = findWhere(($router.routeDescriptions || []).reverse(), { unknown: true }) || null;

  if( !isNull(unknownRoute) ) {
    unknownRoute = extend({}, baseRoute, {
      id: unknownRoute.id,
      controller: unknownRoute.controller,
      title: unknownRoute.title,
      segment: ''
    });
  }

  return unknownRoute;
};

function getActionForRoute($router, routeDescription) {
  var Action;

  if( isRoute(routeDescription) ) {
    Action = RoutedAction.bind($router, routeDescription);
  }

  return Action || DefaultAction.bind($router);
};

var Router = function(descriptor, configParams) {
  return {
    _preInit: function( params ) {
      var subscriptions = this.__subscriptions = fw.observableArray();

      this.$namespace.command.handler('setState', this.setState, this);
      this.$namespace.request.handler('currentRoute', function() { return this.currentRoute(); }, this);
      this.$namespace.request.handler('urlParts', function() { return this.urlParts(); }, this);

      this.urlParts = fw.observable();
      this.childRouters = fw.observableArray();
      this.parentRouter = fw.observable($nullRouter);
      this.context = fw.observable();
      this.historyIsEnabled = fw.observable(false);
      this.disableHistory = fw.observable().receiveFrom(this.$globalNamespace, 'disableHistory');
      this.currentState = fw.observable('').broadcastAs('currentState');
      configParams.baseRoute = fw.routers.baseRoute() + (result(configParams, 'baseRoute') || '');

      this.isRelative = fw.computed(function() {
        return configParams.isRelative && !isNullRouter( this.parentRouter() );
      }, this);

      this.currentRoute = fw.computed(function() {
        return getRouteForURL(this, normalizeURL(this, this.currentState()) );
      }, this);

      this.path = fw.computed(function() {
        var currentRoute = this.currentRoute();
        var routeSegment = '/';

        if( isRoute(currentRoute) ) {
          routeSegment = (currentRoute.segment === '' ? '/' : currentRoute.segment);
        }

        return (this.isRelative() ? this.parentRouter().path() : '') + routeSegment;
      }, this);

      var parentPathSubscription;
      var $router = this;
      var $previousParent = $nullRouter;
      subscriptions.push(this.parentRouter.subscribe(function( $parentRouter ) {
        if( !isNullRouter($previousParent) && $previousParent !== $parentRouter ) {
          $previousParent.childRouters.remove(this);

          if(parentPathSubscription) {
            subscriptions.remove(parentPathSubscription);
            parentPathSubscription.dispose();
          }
          subscriptions.push(parentPathSubscription = $parentRouter.path.subscribe(function triggerRouteRecompute() {
            $router.currentState.notifySubscribers();
          }));
        }
        $parentRouter.childRouters.push(this);
        $previousParent = $parentRouter;
      }, this));

      // Automatically trigger the new Action() whenever the currentRoute() updates
      subscriptions.push( this.currentRoute.subscribe(function getActionForRouteAndTrigger( newRoute ) {
        if(this.currentState().length) {
          getActionForRoute(this, newRoute )( /* get and call the action for the newRoute */ );
        }
      }, this) );

      this.outlets = {};
      this.$outlet = $routerOutlet.bind(this);
      this.$outlet.reset = function() {
        each( this.outlets, function(outlet) {
          outlet({ name: noComponentSelected, params: {} });
        });
      }.bind(this);

      if( !isUndefined(configParams.unknownRoute) ) {
        if( isFunction(configParams.unknownRoute) ) {
          configParams.unknownRoute = { controller: configParams.unknownRoute };
        }
        configParams.routes.push( extend( configParams.unknownRoute, { unknown: true } ) );
      }
      this.setRoutes( configParams.routes );

      if( configParams.activate === true ) {
        subscriptions.push(this.context.subscribe(function activateRouterAfterNewContext( $context ) {
          if( isObject($context) ) {
            this.activate($context);
          }
        }, this));
      }

      this.$namespace.exit();
    },
    mixin: {
      setRoutes: function(routeDesc) {
        this.routeDescriptions = [];
        this.addRoutes(routeDesc);
        return this;
      },
      addRoutes: function(routeConfig) {
        this.routeDescriptions = this.routeDescriptions.concat( map(isArray(routeConfig) ? routeConfig : [routeConfig], transformRouteConfigToDesc) );
        return this;
      },
      activate: function($context, $parentRouter) {
        $context = $context || this.context();
        activateRouter(this, $context, $parentRouter || nearestParentRouter($context) );
        if( this.currentState() === '' ) {
          this.setState();
        }
        return this;
      },
      setState: function(url) {
        if( this.historyIsEnabled() && !this.disableHistory() ) {
          if(isString(url)) {
            var historyAPIWorked = true;
            try {
              historyAPIWorked = History.pushState(null, '', this.__getConfigParams().baseRoute + this.parentRouter().path() + url.replace(startingHashRegex, '/'));
            } catch(historyException) {
              historyAPIWorked = false;
            } finally {
              if(historyAPIWorked) {
                return;
              }
            }
          } else if(isFunction(History.getState)) {
            this.currentState( normalizeURL(this, History.getState().url ) );
          }
        } else if(isString(url)) {
          this.currentState( normalizeURL(this, url ) );
        } else {
          this.currentState('/');
        }

        if(!historyIsReady()) {
          var routePath = this.path();
          each(this.childRouters(), function(childRouter) {
            childRouter.currentState(routePath);
          });
        }

        return this;
      },
      dispose: function() {
        var $parentRouter = this.parentRouter();
        if( !isNullRouter($parentRouter) ) {
          $parentRouter.childRouters.remove(this);
        }

        if( this.historyIsEnabled() && historyIsReady() ) {
          History.Adapter.unbind( this.stateChangeHandler );
        }

        this.$namespace.dispose();
        this.$globalNamespace.dispose();

        invoke(this.__subscriptions(), 'dispose');
        each(omit(this, function(property) {
          return isEntity(property);
        }), propertyDisposal);
      }
    }
  };
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var _ = require('lodash'),
	defaultAssets = require('./config/assets/default'),
	testAssets = require('./config/assets/test'),
	gulp = require('gulp'),
	gulpLoadPlugins = require('gulp-load-plugins'),
	runSequence = require('run-sequence'),
	plugins = gulpLoadPlugins();

// Set NODE_ENV to 'test'
gulp.task('env:test', function () {
	process.env.NODE_ENV = 'test';
});

// Set NODE_ENV to 'development'
gulp.task('env:dev', function () {
	process.env.NODE_ENV = 'development';
});

// Set NODE_ENV to 'production'
gulp.task('env:prod', function () {
	process.env.NODE_ENV = 'production';
});

// Nodemon task
gulp.task('nodemon', function () {
	return plugins.nodemon({
		script: 'server.js',
		nodeArgs: ['--debug'],
		ext: 'js,html',
		watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config)
	});
});

// Watch Files For Changes
gulp.task('watch', function() {
	// Start livereload
	plugins.livereload.listen();

	// Add watch rules
	gulp.watch(defaultAssets.server.views).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.server.allJS, ['jshint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.views).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.js, ['jshint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.css, ['csslint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.sass, ['sass', 'csslint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.less, ['less', 'csslint']).on('change', plugins.livereload.changed);
});

// CSS linting task
gulp.task('csslint', function (done) {
	return gulp.src(defaultAssets.client.css)
		.pipe(plugins.csslint('.csslintrc'))
		.pipe(plugins.csslint.reporter())
		.pipe(plugins.csslint.reporter(function (file) {
			if (!file.csslint.errorCount) {
				done();
			}
		}));
});

// JS linting task
gulp.task('jshint', function () {
	return gulp.src(_.union(defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e))
		.pipe(plugins.jshint())
		.pipe(plugins.jshint.reporter('default'))
		.pipe(plugins.jshint.reporter('fail'));
});

// JS minifying task
gulp.task('uglify', function () {
	return gulp.src(defaultAssets.client.js)
		.pipe(plugins.ngAnnotate())
		.pipe(plugins.uglify({
			mangle: false
		}))
		.pipe(plugins.concat('application.min.js'))
		.pipe(gulp.dest('public/dist'));
});

// CSS minifying task
gulp.task('cssmin', function () {
	return gulp.src(defaultAssets.client.css)
		.pipe(plugins.cssmin())
		.pipe(plugins.concat('application.min.css'))
		.pipe(gulp.dest('public/dist'));
});

// Sass task
gulp.task('sass', function () {
	return gulp.src(defaultAssets.client.sass)
		.pipe(plugins.sass())
		.pipe(plugins.rename(function (path) {
			path.dirname = path.dirname.replace('/scss', '/css');
		}))
		.pipe(gulp.dest('./modules/'));
});

// Less task
gulp.task('less', function () {
	return gulp.src(defaultAssets.client.less)
		.pipe(plugins.less())
		.pipe(plugins.rename(function (path) {
			path.dirname = path.dirname.replace('/less', '/css');
		}))
		.pipe(gulp.dest('./modules/'));
});

// Mocha tests task
gulp.task('mocha', function (done) {
	// Open mongoose connections
	var mongoose = require('./config/lib/mongoose.js');
	var error;

	// Connect mongoose
	mongoose.connect(function() {
		// Run the tests
		gulp.src(testAssets.tests.server)
			.pipe(plugins.mocha({
				reporter: 'spec'
			}))
			.on('error', function (err) {
				// If an error occurs, save it
				error = err;
			})
			.on('end', function() {
				// When the tests are done, disconnect mongoose and pass the error state back to gulp
				mongoose.disconnect(function() {
					done(error);
				});
			});
	});

});

// Karma test runner task
gulp.task('karma', function (done) {
	return gulp.src([])
		.pipe(plugins.karma({
			configFile: 'karma.conf.js',
			action: 'run',
			singleRun: true
		}));
});

// Selenium standalone WebDriver update task
gulp.task('webdriver-update', plugins.protractor.webdriver_update);

// Protractor test runner task
gulp.task('protractor', function () {
	gulp.src([])
		.pipe(plugins.protractor.protractor({
			configFile: 'protractor.conf.js'
		}))
		.on('error', function (e) {
			throw e;
		});
});

// Lint CSS and JavaScript files.
gulp.task('lint', function(done) {
	runSequence('less', 'sass', ['csslint', 'jshint'], done);
});

// Lint project files and minify them into two production files.
gulp.task('build', function(done) {
	runSequence('env:dev' ,'lint', ['uglify', 'cssmin'], done);
});

// Run the project tests
gulp.task('test', function(done) {
	runSequence('env:test', ['karma', 'mocha'], done);
});

// Run the project in development mode
gulp.task('default', function(done) {
	runSequence('env:dev', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in debug mode
gulp.task('debug', function(done) {
	runSequence('env:dev', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in production mode
gulp.task('prod', function(done) {
	runSequence('build', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in production mode
gulp.task('heroku:prod', function(done) {
	runSequence('build', 'lint', ['nodemon', 'watch'], done);
});
<commit_msg>Fix environment task name<commit_after>'use strict';

/**
 * Module dependencies.
 */
var _ = require('lodash'),
	defaultAssets = require('./config/assets/default'),
	testAssets = require('./config/assets/test'),
	gulp = require('gulp'),
	gulpLoadPlugins = require('gulp-load-plugins'),
	runSequence = require('run-sequence'),
	plugins = gulpLoadPlugins();

// Set NODE_ENV to 'test'
gulp.task('env:test', function () {
	process.env.NODE_ENV = 'test';
});

// Set NODE_ENV to 'development'
gulp.task('env:dev', function () {
	process.env.NODE_ENV = 'development';
});

// Set NODE_ENV to 'production'
gulp.task('env:prod', function () {
	process.env.NODE_ENV = 'production';
});

// Nodemon task
gulp.task('nodemon', function () {
	return plugins.nodemon({
		script: 'server.js',
		nodeArgs: ['--debug'],
		ext: 'js,html',
		watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config)
	});
});

// Watch Files For Changes
gulp.task('watch', function() {
	// Start livereload
	plugins.livereload.listen();

	// Add watch rules
	gulp.watch(defaultAssets.server.views).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.server.allJS, ['jshint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.views).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.js, ['jshint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.css, ['csslint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.sass, ['sass', 'csslint']).on('change', plugins.livereload.changed);
	gulp.watch(defaultAssets.client.less, ['less', 'csslint']).on('change', plugins.livereload.changed);
});

// CSS linting task
gulp.task('csslint', function (done) {
	return gulp.src(defaultAssets.client.css)
		.pipe(plugins.csslint('.csslintrc'))
		.pipe(plugins.csslint.reporter())
		.pipe(plugins.csslint.reporter(function (file) {
			if (!file.csslint.errorCount) {
				done();
			}
		}));
});

// JS linting task
gulp.task('jshint', function () {
	return gulp.src(_.union(defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e))
		.pipe(plugins.jshint())
		.pipe(plugins.jshint.reporter('default'))
		.pipe(plugins.jshint.reporter('fail'));
});

// JS minifying task
gulp.task('uglify', function () {
	return gulp.src(defaultAssets.client.js)
		.pipe(plugins.ngAnnotate())
		.pipe(plugins.uglify({
			mangle: false
		}))
		.pipe(plugins.concat('application.min.js'))
		.pipe(gulp.dest('public/dist'));
});

// CSS minifying task
gulp.task('cssmin', function () {
	return gulp.src(defaultAssets.client.css)
		.pipe(plugins.cssmin())
		.pipe(plugins.concat('application.min.css'))
		.pipe(gulp.dest('public/dist'));
});

// Sass task
gulp.task('sass', function () {
	return gulp.src(defaultAssets.client.sass)
		.pipe(plugins.sass())
		.pipe(plugins.rename(function (path) {
			path.dirname = path.dirname.replace('/scss', '/css');
		}))
		.pipe(gulp.dest('./modules/'));
});

// Less task
gulp.task('less', function () {
	return gulp.src(defaultAssets.client.less)
		.pipe(plugins.less())
		.pipe(plugins.rename(function (path) {
			path.dirname = path.dirname.replace('/less', '/css');
		}))
		.pipe(gulp.dest('./modules/'));
});

// Mocha tests task
gulp.task('mocha', function (done) {
	// Open mongoose connections
	var mongoose = require('./config/lib/mongoose.js');
	var error;

	// Connect mongoose
	mongoose.connect(function() {
		// Run the tests
		gulp.src(testAssets.tests.server)
			.pipe(plugins.mocha({
				reporter: 'spec'
			}))
			.on('error', function (err) {
				// If an error occurs, save it
				error = err;
			})
			.on('end', function() {
				// When the tests are done, disconnect mongoose and pass the error state back to gulp
				mongoose.disconnect(function() {
					done(error);
				});
			});
	});

});

// Karma test runner task
gulp.task('karma', function (done) {
	return gulp.src([])
		.pipe(plugins.karma({
			configFile: 'karma.conf.js',
			action: 'run',
			singleRun: true
		}));
});

// Selenium standalone WebDriver update task
gulp.task('webdriver-update', plugins.protractor.webdriver_update);

// Protractor test runner task
gulp.task('protractor', function () {
	gulp.src([])
		.pipe(plugins.protractor.protractor({
			configFile: 'protractor.conf.js'
		}))
		.on('error', function (e) {
			throw e;
		});
});

// Lint CSS and JavaScript files.
gulp.task('lint', function(done) {
	runSequence('less', 'sass', ['csslint', 'jshint'], done);
});

// Lint project files and minify them into two production files.
gulp.task('build', function(done) {
	runSequence('env:dev' ,'lint', ['uglify', 'cssmin'], done);
});

// Run the project tests
gulp.task('test', function(done) {
	runSequence('env:test', ['karma', 'mocha'], done);
});

// Run the project in development mode
gulp.task('default', function(done) {
	runSequence('env:dev', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in debug mode
gulp.task('debug', function(done) {
	runSequence('env:dev', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in production mode
gulp.task('prod', function(done) {
	runSequence('build', 'lint', ['nodemon', 'watch'], done);
});

// Run the project in production mode
gulp.task('heroku:production', function(done) {
	runSequence('build', 'lint', ['nodemon', 'watch'], done);
});
<|endoftext|>


<commit_before>// ## Globals
var argv         = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
var browserSync  = require('browser-sync');
var changed      = require('gulp-changed');
var concat       = require('gulp-concat');
var flatten      = require('gulp-flatten');
var gulp         = require('gulp');
var gulpif       = require('gulp-if');
var imagemin     = require('gulp-imagemin');
var jshint       = require('gulp-jshint');
var lazypipe     = require('lazypipe');
var less         = require('gulp-less');
var merge        = require('merge-stream');
var minifyCss    = require('gulp-minify-css');
var plumber      = require('gulp-plumber');
var rev          = require('gulp-rev');
var runSequence  = require('run-sequence');
var sass         = require('gulp-sass');
var sourcemaps   = require('gulp-sourcemaps');
var uglify       = require('gulp-uglify');

// See https://github.com/austinpray/asset-builder
var manifest = require('asset-builder')('./assets/manifest.json');

// `path` - Paths to base asset directories. With trailing slashes.
// - `path.source` - Path to the source files. Default: `assets/`
// - `path.dist` - Path to the build directory. Default: `dist/`
var path = manifest.paths;

// `config` - Store arbitrary configuration values here.
var config = manifest.config || {};

// `globs` - These ultimately end up in their respective `gulp.src`.
// - `globs.js` - Array of asset-builder JS dependency objects. Example:
//   ```
//   {type: 'js', name: 'main.js', globs: []}
//   ```
// - `globs.css` - Array of asset-builder CSS dependency objects. Example:
//   ```
//   {type: 'css', name: 'main.css', globs: []}
//   ```
// - `globs.fonts` - Array of font path globs.
// - `globs.images` - Array of image path globs.
// - `globs.bower` - Array of all the main Bower files.
var globs = manifest.globs;

// `project` - paths to first-party assets.
// - `project.js` - Array of first-party JS assets.
// - `project.css` - Array of first-party CSS assets.
var project = manifest.getProjectGlobs();

// CLI options
var enabled = {
  // Enable static asset revisioning when `--production`
  rev: argv.production,
  // Disable source maps when `--production`
  maps: !argv.production,
  // Fail styles task on error when `--production`
  failStyleTask: argv.production
};

// Path to the compiled assets manifest in the dist directory
var revManifest = path.dist + 'assets.json';

// ## Reusable Pipelines
// See https://github.com/OverZealous/lazypipe

// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
//   .pipe(cssTasks('main.css')
//   .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
  return lazypipe()
    .pipe(function() {
      return gulpif(!enabled.failStyleTask, plumber());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.init());
    })
    .pipe(function() {
      return gulpif('*.less', less());
    })
    .pipe(function() {
      return gulpif('*.scss', sass({
        outputStyle: 'nested', // libsass doesn't support expanded yet
        precision: 10,
        includePaths: ['.'],
        errLogToConsole: !enabled.failStyleTask
      }));
    })
    .pipe(concat, filename)
    .pipe(autoprefixer, {
      browsers: [
        'last 2 versions',
        'ie 8',
        'ie 9',
        'android 2.3',
        'android 4',
        'opera 12'
      ]
    })
  .pipe(minifyCss)
    .pipe(function() {
      return gulpif(enabled.rev, rev());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.write('.'));
    })();
};

// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
//   .pipe(jsTasks('main.js')
//   .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
  return lazypipe()
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.init());
    })
    .pipe(concat, filename)
    .pipe(uglify)
    .pipe(function() {
      return gulpif(enabled.rev, rev());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.write('.'));
    })();
};

// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
  return lazypipe()
    .pipe(gulp.dest, path.dist + directory)
    .pipe(function() {
      return gulpif('**/*.{js,css}', browserSync.reload({stream:true}));
    })
    .pipe(rev.manifest, revManifest, {
      base: path.dist,
      merge: true
    })
    .pipe(gulp.dest, path.dist)();
};

// ## Gulp tasks
// Run `gulp -T` for a task summary

// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
  var merged = merge();
  manifest.forEachDependency('css', function(dep) {
    var cssTasksInstance = cssTasks(dep.name);
    if (!enabled.failStyleTask) {
      cssTasksInstance.on('error', function(err) {
        console.error(err.message);
        this.emit('end');
      });
    }
    merged.add(gulp.src(dep.globs, {base: 'styles'})
      .pipe(cssTasksInstance));
  });
  return merged
    .pipe(writeToManifest('styles'));
});

// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', ['jshint'], function() {
  var merged = merge();
  manifest.forEachDependency('js', function(dep) {
    merged.add(
      gulp.src(dep.globs, {base: 'scripts'})
        .pipe(jsTasks(dep.name))
    );
  });
  return merged
    .pipe(writeToManifest('scripts'));
});

// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
  return gulp.src(globs.fonts)
    .pipe(flatten())
    .pipe(gulp.dest(path.dist + 'fonts'));
});

// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
  return gulp.src(globs.images)
    .pipe(imagemin({
      progressive: true,
      interlaced: true,
      svgoPlugins: [{removeUnknownsAndDefaults: false}]
    }))
    .pipe(gulp.dest(path.dist + 'images'));
});

// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
  return gulp.src([
    'bower.json', 'gulpfile.js'
  ].concat(project.js))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));

// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
  browserSync({
    files: [path.dist, '{lib,templates}/**/*.php', '*.php'],
    proxy: config.devUrl,
    snippetOptions: {
      whitelist: ['/wp-admin/admin-ajax.php'],
      blacklist: ['/wp-admin/**']
    }
  });
  gulp.watch([path.source + 'styles/**/*'], ['styles']);
  gulp.watch([path.source + 'scripts/**/*'], ['jshint', 'scripts']);
  gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
  gulp.watch([path.source + 'images/**/*'], ['images']);
  gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});

// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
  runSequence('styles',
              'scripts',
              ['fonts', 'images'],
              callback);
});

// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
  var wiredep = require('wiredep').stream;
  return gulp.src(project.css)
    .pipe(wiredep())
    .pipe(changed(path.source + 'styles', {
      hasChanged: changed.compareSha1Digest
    }))
    .pipe(gulp.dest(path.source + 'styles'));
});

// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean'], function() {
  gulp.start('build');
});
<commit_msg>Turn off advanced CSS optimizations<commit_after>// ## Globals
var argv         = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
var browserSync  = require('browser-sync');
var changed      = require('gulp-changed');
var concat       = require('gulp-concat');
var flatten      = require('gulp-flatten');
var gulp         = require('gulp');
var gulpif       = require('gulp-if');
var imagemin     = require('gulp-imagemin');
var jshint       = require('gulp-jshint');
var lazypipe     = require('lazypipe');
var less         = require('gulp-less');
var merge        = require('merge-stream');
var minifyCss    = require('gulp-minify-css');
var plumber      = require('gulp-plumber');
var rev          = require('gulp-rev');
var runSequence  = require('run-sequence');
var sass         = require('gulp-sass');
var sourcemaps   = require('gulp-sourcemaps');
var uglify       = require('gulp-uglify');

// See https://github.com/austinpray/asset-builder
var manifest = require('asset-builder')('./assets/manifest.json');

// `path` - Paths to base asset directories. With trailing slashes.
// - `path.source` - Path to the source files. Default: `assets/`
// - `path.dist` - Path to the build directory. Default: `dist/`
var path = manifest.paths;

// `config` - Store arbitrary configuration values here.
var config = manifest.config || {};

// `globs` - These ultimately end up in their respective `gulp.src`.
// - `globs.js` - Array of asset-builder JS dependency objects. Example:
//   ```
//   {type: 'js', name: 'main.js', globs: []}
//   ```
// - `globs.css` - Array of asset-builder CSS dependency objects. Example:
//   ```
//   {type: 'css', name: 'main.css', globs: []}
//   ```
// - `globs.fonts` - Array of font path globs.
// - `globs.images` - Array of image path globs.
// - `globs.bower` - Array of all the main Bower files.
var globs = manifest.globs;

// `project` - paths to first-party assets.
// - `project.js` - Array of first-party JS assets.
// - `project.css` - Array of first-party CSS assets.
var project = manifest.getProjectGlobs();

// CLI options
var enabled = {
  // Enable static asset revisioning when `--production`
  rev: argv.production,
  // Disable source maps when `--production`
  maps: !argv.production,
  // Fail styles task on error when `--production`
  failStyleTask: argv.production
};

// Path to the compiled assets manifest in the dist directory
var revManifest = path.dist + 'assets.json';

// ## Reusable Pipelines
// See https://github.com/OverZealous/lazypipe

// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
//   .pipe(cssTasks('main.css')
//   .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
  return lazypipe()
    .pipe(function() {
      return gulpif(!enabled.failStyleTask, plumber());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.init());
    })
    .pipe(function() {
      return gulpif('*.less', less());
    })
    .pipe(function() {
      return gulpif('*.scss', sass({
        outputStyle: 'nested', // libsass doesn't support expanded yet
        precision: 10,
        includePaths: ['.'],
        errLogToConsole: !enabled.failStyleTask
      }));
    })
    .pipe(concat, filename)
    .pipe(autoprefixer, {
      browsers: [
        'last 2 versions',
        'ie 8',
        'ie 9',
        'android 2.3',
        'android 4',
        'opera 12'
      ]
    })
    .pipe(minifyCss, {
      advanced: false,
      rebase: false
    })
    .pipe(function() {
      return gulpif(enabled.rev, rev());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.write('.'));
    })();
};

// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
//   .pipe(jsTasks('main.js')
//   .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
  return lazypipe()
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.init());
    })
    .pipe(concat, filename)
    .pipe(uglify)
    .pipe(function() {
      return gulpif(enabled.rev, rev());
    })
    .pipe(function() {
      return gulpif(enabled.maps, sourcemaps.write('.'));
    })();
};

// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
  return lazypipe()
    .pipe(gulp.dest, path.dist + directory)
    .pipe(function() {
      return gulpif('**/*.{js,css}', browserSync.reload({stream:true}));
    })
    .pipe(rev.manifest, revManifest, {
      base: path.dist,
      merge: true
    })
    .pipe(gulp.dest, path.dist)();
};

// ## Gulp tasks
// Run `gulp -T` for a task summary

// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
  var merged = merge();
  manifest.forEachDependency('css', function(dep) {
    var cssTasksInstance = cssTasks(dep.name);
    if (!enabled.failStyleTask) {
      cssTasksInstance.on('error', function(err) {
        console.error(err.message);
        this.emit('end');
      });
    }
    merged.add(gulp.src(dep.globs, {base: 'styles'})
      .pipe(cssTasksInstance));
  });
  return merged
    .pipe(writeToManifest('styles'));
});

// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', ['jshint'], function() {
  var merged = merge();
  manifest.forEachDependency('js', function(dep) {
    merged.add(
      gulp.src(dep.globs, {base: 'scripts'})
        .pipe(jsTasks(dep.name))
    );
  });
  return merged
    .pipe(writeToManifest('scripts'));
});

// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
  return gulp.src(globs.fonts)
    .pipe(flatten())
    .pipe(gulp.dest(path.dist + 'fonts'));
});

// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
  return gulp.src(globs.images)
    .pipe(imagemin({
      progressive: true,
      interlaced: true,
      svgoPlugins: [{removeUnknownsAndDefaults: false}]
    }))
    .pipe(gulp.dest(path.dist + 'images'));
});

// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
  return gulp.src([
    'bower.json', 'gulpfile.js'
  ].concat(project.js))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));

// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
  browserSync({
    files: [path.dist, '{lib,templates}/**/*.php', '*.php'],
    proxy: config.devUrl,
    snippetOptions: {
      whitelist: ['/wp-admin/admin-ajax.php'],
      blacklist: ['/wp-admin/**']
    }
  });
  gulp.watch([path.source + 'styles/**/*'], ['styles']);
  gulp.watch([path.source + 'scripts/**/*'], ['jshint', 'scripts']);
  gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
  gulp.watch([path.source + 'images/**/*'], ['images']);
  gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});

// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
  runSequence('styles',
              'scripts',
              ['fonts', 'images'],
              callback);
});

// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
  var wiredep = require('wiredep').stream;
  return gulp.src(project.css)
    .pipe(wiredep())
    .pipe(changed(path.source + 'styles', {
      hasChanged: changed.compareSha1Digest
    }))
    .pipe(gulp.dest(path.source + 'styles'));
});

// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean'], function() {
  gulp.start('build');
});
<|endoftext|>


<commit_before>/*jshint node: true*/
'use strict';
var gulp = require('gulp');
var less = require('gulp-less');
var autoprefix = require('gulp-autoprefixer');
var minifyCss = require('gulp-minify-css');
var size = require('gulp-size');
var jade = require('gulp-jade');
var rename = require('gulp-rename');
var connect = require('gulp-connect');

var result = './dist';
var messagesSrc = './src/messages.js';
var indexSrc = './src/templates/**/*.jade';
var assetsSrc = './src/assets/**/*';
var lessSrc = './src/styles/**/*';
require('colors');

function wrap(stream) {
  function log(error) {
    console.log([
        '',
        "----------ERROR MESSAGE START----------".bold.red.underline,
        ("[" + error.name + " in " + error.plugin + "]").red.bold.inverse,
        error.message,
        "----------ERROR MESSAGE END----------".bold.red.underline,
        ''
    ].join('\n'));

    stream.emit('end'); //ohh, this one restarts watch
    stream.end();
  }

  return stream.on('error', log);
}

/**
 * Copy assets
 */
gulp.task('assets', function() {
  return gulp.src(assetsSrc)
    .pipe(gulp.dest(result));
});

/**
 * Build less files
 */
gulp.task('less', function() {
  return gulp.src('./src/styles/foodzzilla.less')
    .pipe(wrap(less()))
    .pipe(autoprefix('last 2 versions'))
    .pipe(size({title: 'Unminified css'}))
    .pipe(minifyCss())
    .pipe(size({title: 'Minified css'}))
    .pipe(gulp.dest(result));
});

/**
 * Generate index file
 */
gulp.task('index', function() {
  delete require.cache[require.resolve(messagesSrc)];

  return gulp.src('./src/templates/index.jade')
    .pipe(wrap(jade({
      pretty: true,
      locals: {
        messages: require(messagesSrc)
      }
    })))
    .pipe(rename('index.html'))
    .pipe(gulp.dest(result));
});

/**
 * Start simple server
 */
gulp.task('server', function() {
  connect.server({
    port: 8123,
    livereload: true,
    root: result
  });
});

/**
 * Big Brother
 */
gulp.task('watch', function() {
  gulp.watch(assetsSrc, ['assets']);
  gulp.watch(lessSrc, ['less']);
  gulp.watch([indexSrc, messagesSrc], ['index']);
  gulp.watch('./dist/**/*', function(){
    gulp.src(result).pipe(connect.reload());
  });
});

gulp.task('default', ['assets', 'less', 'index', 'server', 'watch']);
<commit_msg>debounce and port<commit_after>/*jshint node: true*/
'use strict';
var gulp = require('gulp');
var less = require('gulp-less');
var autoprefix = require('gulp-autoprefixer');
var minifyCss = require('gulp-minify-css');
var size = require('gulp-size');
var jade = require('gulp-jade');
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var _ = require('lodash');

var result = 'dist';
var messagesSrc = './src/messages.js';
var indexSrc = './src/templates/**/*.jade';
var assetsSrc = './src/assets/**/*';
var lessSrc = './src/styles/**/*';
require('colors');

function wrap(stream) {
  function log(error) {
    console.log([
        '',
        "----------ERROR MESSAGE START----------".bold.red.underline,
        ("[" + error.name + " in " + error.plugin + "]").red.bold.inverse,
        error.message,
        "----------ERROR MESSAGE END----------".bold.red.underline,
        ''
    ].join('\n'));

    stream.emit('end'); //ohh, this one restarts watch
    stream.end();
  }

  return stream.on('error', log);
}

/**
 * Copy assets
 */
gulp.task('assets', function() {
  return gulp.src(assetsSrc)
    .pipe(gulp.dest(result));
});

/**
 * Build less files
 */
gulp.task('less', function() {
  return gulp.src('./src/styles/foodzzilla.less')
    .pipe(wrap(less()))
    .pipe(autoprefix('last 2 versions'))
    .pipe(size({title: 'Unminified css'}))
    .pipe(minifyCss())
    .pipe(size({title: 'Minified css'}))
    .pipe(gulp.dest(result));
});

/**
 * Generate index file
 */
gulp.task('index', function() {
  delete require.cache[require.resolve(messagesSrc)];

  return gulp.src('./src/templates/index.jade')
    .pipe(wrap(jade({
      pretty: true,
      locals: {
        messages: require(messagesSrc)
      }
    })))
    .pipe(rename('index.html'))
    .pipe(gulp.dest(result));
});

/**
 * Start simple server
 */
gulp.task('server', function() {
  connect.server({
    port: 8777,
    livereload: true,
    root: result
  });
});

/**
 * Big Brother
 */
gulp.task('watch', function() {
  gulp.watch(assetsSrc, ['assets']);
  gulp.watch(lessSrc, ['less']);
  gulp.watch([indexSrc, messagesSrc], ['index']);
  gulp.watch('./dist/**/*', _.debounce(function(){
    gulp.src(result).pipe(connect.reload());
  }, 1000));
});

gulp.task('default', ['assets', 'less', 'index', 'server', 'watch']);
<|endoftext|>


<commit_before>// @flow

import * as React from 'react'
import {StyleSheet, WebView, ScrollView} from 'react-native'
import glamorous from 'glamorous-native'
import type {PodcastEpisode} from './types'
import moment from 'moment'
import {AllHtmlEntities} from 'html-entities'
import qs from 'querystring'
import {Viewport} from '../components/viewport'
import {TextButton} from '../components/nav-buttons'
import {openUrl} from '../components/open-url'

const entities = new AllHtmlEntities()

const styles = StyleSheet.create({
	audio: {
		width: 200,
		height: 100,
	},
	video: {},
})

const htmlVideo = (params: string) => `<!DOCTYPE html>

`

type Props = {
	navigation: {
		state: {
			params: {
				event: PodcastEpisode,
			},
		},
	},
}

const Title = glamorous.text({
	fontSize: 36,
	textAlign: 'center',
	marginHorizontal: 18,
	marginVertical: 10,
})

const Description = glamorous.text({
	fontSize: 18,
	textAlign: 'left',
	marginHorizontal: 18,
	marginVertical: 10,
})

const ConvoDate = glamorous(Description)({
	textAlign: 'center',
})

const ConvoLength = glamorous(ConvoDate)({})

const CONVO_WIDTH = 639
const CONVO_HEIGHT = 360
const RATIO = CONVO_HEIGHT / CONVO_WIDTH

function getConvoUrlParams(mediaUrl: string) {
	return mediaUrl.split('?')[1]
}

function getConvoId(mediaUrl: string) {
	return qs.parse(entities.decode(getConvoUrlParams(mediaUrl))).media_work_id
}

function getConvoLink(mediaUrl: string) {
	let convoId = getConvoId(mediaUrl)
	return `https://apps.carleton.edu/events/convocations/audio_video/?item_id=${convoId}`
}

export class ArchivedConvocationDetailView extends React.Component<Props> {
	static navigationOptions = ({navigation}: any) => {
		const {params: {event} = {}} = navigation.state

		if (!event.enclosure) {
			return {}
		}

		let link = getConvoLink(event.enclosure.url)

		return {
			headerRight: (
				<TextButton
					onPress={() => openUrl(link)}
					title="Open on carleton.edu"
				/>
			),
		}
	}

	render() {
		const {navigation: {state: {params: {event}}}} = this.props

		let style = null
		if (event.enclosure && event.enclosure.type.startsWith('audio/')) {
			style = styles.audio
		} else if (event.enclosure && event.enclosure.type.startsWith('video/')) {
			style = styles.video
		}

		let title = event.title.replace(/^Convocation: /, '')
		let date = event.pubDate.format('dddd, MMMM Do YYYY')

		let convoUrlParams = event.enclosure
			? getConvoUrlParams(event.enclosure.url)
			: ''

		let convoLength = null
		if (event.enclosure) {
			let duration = moment.duration(parseInt(event.enclosure.length) / 100)

			let hours =
				duration.hours() === 1
					? `${duration.hours()} hour`
					: `${duration.hours()} hours`

			let minutes =
				duration.minutes() === 0
					? ''
					: duration.minutes() === 1
						? `, ${duration.minutes()} minute`
						: `, ${duration.minutes()} minutes`

			convoLength = `${hours}${minutes}`
		}

		return (
			<ScrollView>
				<ConvoDate>{date}</ConvoDate>
				<Title>{title}</Title>
				<Description>{event.description}</Description>

				{event.enclosure ? (
					<React.Fragment>
						<Viewport
							render={({width}) => (
								<WebView
									scrollEnabled={false}
									source={{html: htmlVideo(convoUrlParams)}}
									style={[style, {width: width, height: RATIO * width}]}
								/>
							)}
						/>

						<ConvoLength>{convoLength}</ConvoLength>
					</React.Fragment>
				) : null}
			</ScrollView>
		)
	}
}
<commit_msg>prettify<commit_after>// @flow

import * as React from 'react'
import {StyleSheet, WebView, ScrollView} from 'react-native'
import glamorous from 'glamorous-native'
import type {PodcastEpisode} from './types'
import moment from 'moment'
import {AllHtmlEntities} from 'html-entities'
import qs from 'querystring'
import {Viewport} from '../components/viewport'
import {TextButton} from '../components/nav-buttons'
import {openUrl} from '../components/open-url'

const entities = new AllHtmlEntities()

const styles = StyleSheet.create({
	audio: {
		width: 200,
		height: 100,
	},
	video: {},
})

const htmlVideo = (params: string) => `<!DOCTYPE html>

`

type Props = {
	navigation: {
		state: {
			params: {
				event: PodcastEpisode,
			},
		},
	},
}

const Title = glamorous.text({
	fontSize: 36,
	textAlign: 'center',
	marginHorizontal: 18,
	marginVertical: 10,
})

const Description = glamorous.text({
	fontSize: 18,
	textAlign: 'left',
	marginHorizontal: 18,
	marginVertical: 10,
})

const ConvoDate = glamorous(Description)({
	textAlign: 'center',
})

const ConvoLength = glamorous(ConvoDate)({})

const CONVO_WIDTH = 639
const CONVO_HEIGHT = 360
const RATIO = CONVO_HEIGHT / CONVO_WIDTH

function getConvoUrlParams(mediaUrl: string) {
	return mediaUrl.split('?')[1]
}

function getConvoId(mediaUrl: string) {
	return qs.parse(entities.decode(getConvoUrlParams(mediaUrl))).media_work_id
}

function getConvoLink(mediaUrl: string) {
	let convoId = getConvoId(mediaUrl)
	return `https://apps.carleton.edu/events/convocations/audio_video/?item_id=${convoId}`
}

export class ArchivedConvocationDetailView extends React.Component<Props> {
	static navigationOptions = ({navigation}: any) => {
		const {params: {event} = {}} = navigation.state

		if (!event.enclosure) {
			return {}
		}

		let link = getConvoLink(event.enclosure.url)

		return {
			headerRight: (
				<TextButton
					onPress={() => openUrl(link)}
					title="Open on carleton.edu"
				/>
			),
		}
	}

	render() {
		const {
			navigation: {
				state: {
					params: {event},
				},
			},
		} = this.props

		let style = null
		if (event.enclosure && event.enclosure.type.startsWith('audio/')) {
			style = styles.audio
		} else if (event.enclosure && event.enclosure.type.startsWith('video/')) {
			style = styles.video
		}

		let title = event.title.replace(/^Convocation: /, '')
		let date = event.pubDate.format('dddd, MMMM Do YYYY')

		let convoUrlParams = event.enclosure
			? getConvoUrlParams(event.enclosure.url)
			: ''

		let convoLength = null
		if (event.enclosure) {
			let duration = moment.duration(parseInt(event.enclosure.length) / 100)

			let hours =
				duration.hours() === 1
					? `${duration.hours()} hour`
					: `${duration.hours()} hours`

			let minutes =
				duration.minutes() === 0
					? ''
					: duration.minutes() === 1
						? `, ${duration.minutes()} minute`
						: `, ${duration.minutes()} minutes`

			convoLength = `${hours}${minutes}`
		}

		return (
			<ScrollView>
				<ConvoDate>{date}</ConvoDate>
				<Title>{title}</Title>
				<Description>{event.description}</Description>

				{event.enclosure ? (
					<React.Fragment>
						<Viewport
							render={({width}) => (
								<WebView
									scrollEnabled={false}
									source={{html: htmlVideo(convoUrlParams)}}
									style={[style, {width: width, height: RATIO * width}]}
								/>
							)}
						/>

						<ConvoLength>{convoLength}</ConvoLength>
					</React.Fragment>
				) : null}
			</ScrollView>
		)
	}
}
<|endoftext|>


<commit_before>// @flow weak

import React, { PropTypes } from 'react';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

export const styleSheet = createStyleSheet('Chart', (theme) => {
  const { palette } = theme;

  return {
    chart: {
      backgroundColor: palette.background.paper,
      width: '500px',
      height: '0px',
      position: 'relative',
    },
  };
});

/**
 * A piece of material Chart.
 *
 * ```js
 * import Chart from 'material-charts/Chart';
 *
 * const Component = () => <Chart zDepth={8}>Hello World</Chart>;
 * ```
 */
export default function Chart(props, context) {
  const { className, view, trbl } = props;
  const classes = context.styleManager.render(styleSheet);

  return (
    <div
      className={classNames(classes.chart, className)}
      style={{ paddingTop: `${(Math.round(view[1] / view[0]) * 100)}%` }}
    >
      <svg
        style={{ position: 'absolute', top: 0, left: 0 }}
        viewBox={`0 0 ${view[0]} ${view[1]}`}
      >
        <g transform={`translate(${trbl[3]} ,${trbl[0]})`}>
          {props.children}
        </g>
      </svg>
    </div>
  );
}

Chart.propTypes = {
  /**
   * The CSS class name of the root element.
   */
  children: PropTypes.node,
  /**
   * The CSS class name of the root element.
   */
  className: PropTypes.string,
  /**
   * Shadow depth, corresponds to `dp` in the spec.
   */
  trbl: PropTypes.array,
  /**
   * Set to false to disable rounded corners.
   */
  view: PropTypes.array,
};

Chart.defaultProps = {
  view: [1000, 500],
  trbl: [0, 0, 0, 0],
};

Chart.contextTypes = {
  styleManager: customPropTypes.muiRequired,
};
<commit_msg>move svg styles to new class name<commit_after>// @flow weak

import React, { PropTypes } from 'react';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

export const styleSheet = createStyleSheet('Chart', (theme) => {
  const { palette } = theme;

  return {
    chart: {
      backgroundColor: palette.background.paper,
      width: '100%',
      height: '0px',
      position: 'relative',
    },
    svg: {
      top: 0,
      left: 0,
      position: 'absolute',
    },
  };
});

/**
 * A piece of material Chart.
 *
 * ```js
 * import Chart from 'material-charts/Chart';
 *
 * const Component = () => <Chart zDepth={8}>Hello World</Chart>;
 * ```
 */
export default function Chart(props, context) {
  const { className, view, trbl } = props;
  const classes = context.styleManager.render(styleSheet);

  return (
    <div
      className={classNames(classes.chart, className)}
      style={{ paddingTop: `${(Math.round(view[1] / view[0]) * 100)}%` }}
    >
      <svg
        className={classes.svg}
        viewBox={`0 0 ${view[0]} ${view[1]}`}
      >
        <g transform={`translate(${trbl[3]} ,${trbl[0]})`}>
          {props.children}
        </g>
      </svg>
    </div>
  );
}

Chart.propTypes = {
  /**
   * The CSS class name of the root element.
   */
  children: PropTypes.node,
  /**
   * The CSS class name of the root element.
   */
  className: PropTypes.string,
  /**
   * Shadow depth, corresponds to `dp` in the spec.
   */
  trbl: PropTypes.array,
  /**
   * Set to false to disable rounded corners.
   */
  view: PropTypes.array,
};

Chart.defaultProps = {
  view: [1000, 500],
  trbl: [0, 0, 0, 0],
};

Chart.contextTypes = {
  styleManager: customPropTypes.muiRequired,
};
<|endoftext|>


<commit_before>import DefineMap from 'can-define/map/map';
import Base from 'spectre-canjs/util/field/Field';
import parseFieldArray from 'spectre-canjs/util/field/parseFieldArray/parseFieldArray';
import mapToFields from 'spectre-canjs/util/field/mapToFields/mapToFields';

/**
 * A <sp-subform-field /> component's ViewModel
 * @class ViewModel
 * @extends Field
 * @memberof sp-subform-field
 *
 */
export default Base.extend('SubformField', {
    /** @lends sp-subform-field.ViewModel.prototype */
    /**
     * The current value of the field. This is a json serialized value
     * paths.
     * @type {String}
     * @memberof sp-subform-field.ViewModel.prototype
     */
    value: {
        Value: DefineMap,
        Type: DefineMap,
        set (val) {
            if (this.value !== val) {
                this.dispatch('fieldchange', [{
                    value: val,
                    name: this.name
                }]);
            }
            return val;
        }
    },
    /**
     * The field properties to set up the form fields functionality, this is
     * set up automatically from the `fields` property or the `subobject`
     * if `fields` is not provided.
     * @type {Array<Field>}
     * @memberof sp-subform-field.ViewModel.prototype
     */
    formFields: {
        get () {
            if (this.fields && this.fields.length) {
                return parseFieldArray(this.fields);
            }
            return mapToFields(this.Type);
        }
    },
    /**
     * Called whenever a field changes its value to update this form's json
     * string value. Dispatches the `fieldchange` event with the serialized form object
     * @param  {Array} args the arguments dispatched from the event
     */
    saveField (args) {
        const [props] = args;
        this.value.assign(props.dirty.get());
        this.dispatch('fieldchange', [this]);
    }
});<commit_msg>add subType to subform-field as alternative to "Type"<commit_after>import DefineMap from 'can-define/map/map';
import Base from 'spectre-canjs/util/field/Field';
import parseFieldArray from 'spectre-canjs/util/field/parseFieldArray/parseFieldArray';
import mapToFields from 'spectre-canjs/util/field/mapToFields/mapToFields';

/**
 * A <sp-subform-field /> component's ViewModel
 * @class ViewModel
 * @extends Field
 * @memberof sp-subform-field
 *
 */
export default Base.extend('SubformField', {
    /** @lends sp-subform-field.ViewModel.prototype */
    /**
     * The current value of the field. This is a json serialized value
     * paths.
     * @type {String}
     * @memberof sp-subform-field.ViewModel.prototype
     */
    value: {
        Value: DefineMap,
        Type: DefineMap,
        set (val) {
            if (this.value !== val) {
                this.dispatch('fieldchange', [{
                    value: val,
                    name: this.name
                }]);
            }
            return val;
        }
    },
    /**
     * An alternative property to using Type. Since Type is a DefineMap keyword,
     * subType is provided to allow for customizability between the field and
     * the map
     * @type {Constructor}
     * @memberof sp-subform-field.ViewModel.prototype
     */
    subType: '*',
    /**
     * The field properties to set up the form fields functionality, this is
     * set up automatically from the `fields` property or the `subobject`
     * if `fields` is not provided.
     * @type {Array<Field>}
     * @memberof sp-subform-field.ViewModel.prototype
     */
    formFields: {
        get () {
            if (this.fields && this.fields.length) {
                return parseFieldArray(this.fields);
            }

            const type = this.subType || this.Type;
            return mapToFields(type);
        }
    },
    /**
     * Called whenever a field changes its value to update this form's json
     * string value. Dispatches the `fieldchange` event with the serialized form object
     * @param  {Array} args the arguments dispatched from the event
     */
    saveField (args) {
        const [props] = args;
        this.value.assign(props.dirty.get());
        this.dispatch('fieldchange', [this]);
    }
});<|endoftext|>


<commit_before>var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var clean = require('gulp-clean')

var paths = {
  scripts: ['src/js/**/*.js']
};

gulp.task('scripts', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(sourcemaps.init())
    .pipe(uglify())
    .pipe(concat('all.min.js'))
    .pipe(sourcemaps.write('../maps'))
    .pipe(gulp.dest('dist/js/'))
});

gulp.task('clean', function () {
  return gulp.src('dist')
    .pipe(clean());
});
<commit_msg>Add watch task<commit_after>var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var clean = require('gulp-clean')

var paths = {
  scripts: ['src/js/**/*.js']
};

gulp.task('scripts', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(sourcemaps.init())
    .pipe(uglify())
    .pipe(concat('all.min.js'))
    .pipe(sourcemaps.write('../maps'))
    .pipe(gulp.dest('dist/js/'))
});

gulp.task('clean', function () {
  return gulp.src('dist')
    .pipe(clean());
});

gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['scripts']);
});

gulp.task('default', ['watch', 'scripts']);
<|endoftext|>


<commit_before>function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }
    }

    document.body.appendChild(form);
    form.submit();
}

post('https://nosedive.hackmirror.icu/beta/boost_rating/', {username: 'meganung_20560f'});
<commit_msg>rip rip<commit_after><|endoftext|>


<commit_before>import Resource from '../ClassyResource/main';
import _ from 'lodash';
const resources = require('../resources.json');

class Classy {
  constructor(config) {
    const DEFAULT_BASE_URL = 'https://api.classy.org';
    const DEFAULT_PATH = '2.0';
    const DEFAULT_STRICT_SSL = true;
    const DEFAULT_REQUEST_DEBUG = true;
    const DEFAULT_REQUEST_DEBUG_ACTION = (type, data) => console.log(data);

    /** Handle errors */
    if (_.isUndefined(config)
    ||  (!_.isUndefined(config.headers)
        && (_.isUndefined(config.clientId) ||  _.isUndefined(config.clientSecret)))) {
      throw new Error('Classy needs to be called with a `clientId` and `clientSecret`');
    }

    this.appToken = null;
    this.ClassyResource = Resource;

    /** Set required params */
    this.clientId = config.clientId;
    this.clientSecret = config.clientSecret;

    /** Override and replace headers if config.headers is set */
    this.headers = config.headers;

    /** Override defaults if asked */
    this.requestDebug = (
      !_.isUndefined(config.requestDebug) ?
      config.requestDebug :
      DEFAULT_REQUEST_DEBUG
    );

    this.requestDebugAction = (
      !_.isUndefined(config.onRequestDebug) ?
      config.onRequestDebug :
      DEFAULT_REQUEST_DEBUG_ACTION
    );

    this.basePath = (
      !_.isUndefined(config.basePath) ?
      config.basePath :
      DEFAULT_PATH
    );

    this.baseUrl = (
      !_.isUndefined(config.baseUrl) ?
      config.baseUrl :
      DEFAULT_BASE_URL
    );

    this.strictSsl = (
      !_.isUndefined(config.strictSsl) ?
      config.strictSsl :
      DEFAULT_STRICT_SSL
    );

    this._prepResources();
  }

};

import _prepResources from './_prepResources';
import app from './app';
import getAppToken from './getAppToken';
import setAppToken from './setAppToken';

Object.assign(Classy.prototype, {
  _prepResources,
  app,
  getAppToken,
  setAppToken
});

module.exports = Classy;
<commit_msg>Remove stray const<commit_after>import Resource from '../ClassyResource/main';
import _ from 'lodash';

class Classy {
  constructor(config) {
    const DEFAULT_BASE_URL = 'https://api.classy.org';
    const DEFAULT_PATH = '2.0';
    const DEFAULT_STRICT_SSL = true;
    const DEFAULT_REQUEST_DEBUG = true;
    const DEFAULT_REQUEST_DEBUG_ACTION = (type, data) => console.log(data);

    /** Handle errors */
    if (_.isUndefined(config)
    ||  (!_.isUndefined(config.headers)
        && (_.isUndefined(config.clientId) ||  _.isUndefined(config.clientSecret)))) {
      throw new Error('Classy needs to be called with a `clientId` and `clientSecret`');
    }

    this.appToken = null;
    this.ClassyResource = Resource;

    /** Set required params */
    this.clientId = config.clientId;
    this.clientSecret = config.clientSecret;

    /** Override and replace headers if config.headers is set */
    this.headers = config.headers;

    /** Override defaults if asked */
    this.requestDebug = (
      !_.isUndefined(config.requestDebug) ?
      config.requestDebug :
      DEFAULT_REQUEST_DEBUG
    );

    this.requestDebugAction = (
      !_.isUndefined(config.onRequestDebug) ?
      config.onRequestDebug :
      DEFAULT_REQUEST_DEBUG_ACTION
    );

    this.basePath = (
      !_.isUndefined(config.basePath) ?
      config.basePath :
      DEFAULT_PATH
    );

    this.baseUrl = (
      !_.isUndefined(config.baseUrl) ?
      config.baseUrl :
      DEFAULT_BASE_URL
    );

    this.strictSsl = (
      !_.isUndefined(config.strictSsl) ?
      config.strictSsl :
      DEFAULT_STRICT_SSL
    );

    this._prepResources();
  }

};

import _prepResources from './_prepResources';
import app from './app';
import getAppToken from './getAppToken';
import setAppToken from './setAppToken';

Object.assign(Classy.prototype, {
  _prepResources,
  app,
  getAppToken,
  setAppToken
});

module.exports = Classy;
<|endoftext|>


<commit_before>// 禁止提示框
process.env.DISABLE_NOTIFIER = true;
// 载入插件
var gulp = require('gulp'),
    $ = require('gulp-load-plugins')(),
    browserSync = require('browser-sync');
// 压缩vendor
// gulp.task('vendor', ['clean:vendor'], function () {
//     var filterJS = $.filter('**/*.js', {restore: true});
//     var filterCss = $.filter('**/*.css', {restore: true});
//     return gulp.src('app/vendor/**/*.*')
//         .pipe(filterJS)
//         .pipe($.uglify())
//         .pipe(filterJS.restore)
//         .pipe(filterCss)
//         .pipe($.cleanCss())
//         .pipe(filterCss.restore)
//         .pipe(gulp.dest('dist/vendor'))
//         .pipe($.notify({message: 'vendor task complete'}));
// });

gulp.task('vendor', function(){
    return gulp.src('app/vendor/**/*.*')
        .pipe(gulp.dest('dist/vendor'));
});

// 清除dist/vendor
gulp.task('clean:vendor', function () {
    return gulp.src(['dist/vendor/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩scripts
gulp.task('scripts', function () {
    return gulp.src('app/scripts/**/*.js')
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.ngAnnotate())
        .pipe($.uglify({output:{max_line_len: 120000}}))
        .pipe(gulp.dest('dist/scripts'))
        .pipe($.notify({message: 'scripts task complete'}));
});

// 清除dist/scripts
gulp.task('clean:scripts', function () {
    return gulp.src(['dist/scripts/**/*.js'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩json
gulp.task('json', function () {
    return gulp.src('app/json/**/*.json')
        .pipe(gulp.dest('dist/json'))
        .pipe($.notify({message: 'json task complete'}));
});
// 清除dist/json
gulp.task('clean:json', function () {
    return gulp.src(['dist/json/**/*.json'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩styles
gulp.task('styles', function () {
    return gulp.src('app/styles/**/*.css')
        .pipe($.autoprefixer())
        .pipe($.csscomb())
        .pipe($.cleanCss())
        .pipe(gulp.dest('dist/styles'))
        .pipe($.notify({message: 'styles task complete'}));
});
// 清除dist/styles
gulp.task('clean:styles', function () {
    return gulp.src(['dist/styles/**/*.css', 'dist/styles/*.css'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩images
gulp.task('images', function () {
    return gulp.src('app/images/*.*')
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.cache($.imagemin({optimizationLevel: 3, progressive: true, interlaced: true})))
        .pipe(gulp.dest('dist/images'))
        .pipe($.notify({message: 'images task complete'}));
});
// 清除dist/images
gulp.task('clean:images', function () {
    return gulp.src(['dist/images/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩views
gulp.task('views', function () {
    return gulp.src('app/views/**/*.html')
        .pipe($.htmlmin({
            collapseWhitespace: true,
            collapseBooleanAttributes: true,
            removeComments: true,
            removeEmptyAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            minifyJS: true,
            minifyCSS: true
        }))
        .pipe(gulp.dest('dist/views'))
        .pipe($.notify({message: 'images task complete'}));
});
// 清除dist/views
gulp.task('clean:views', function () {
    return gulp.src(['dist/views/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 生成template 缓存模块
gulp.task('template', function(){
    return gulp.src('app/views/**/*.html')
        .pipe($.angularTemplatecache({
            root: 'app/views/'
        }))
        .pipe(gulp.dest('app/scripts/template-cache'))
});

var copyA2B = function (A, B) {
    var dirs = ['images', 'json', 'scripts', 'styles', 'views'];
    for (var i = 0, l = dirs.length; i < l; i++) {
        var dir = dirs[i],
            start = '' + A + '/' + dir + '/**/*.*',
            end = '' + B + '/' + dir;
        gulp.src(start)
            .pipe(gulp.dest(end))
            .pipe($.notify({message: 'copy ' + dir + ' complete'}));
    }
};

// clean app
gulp.task('clean:app', function () {
    return gulp.src(['app/**/*.*'], {read: false})
        .pipe($.clean());
});
// clean .temp
gulp.task('clean:temp', function () {
    return gulp.src(['.temp/**/*.*'], {read: false})
        .pipe($.clean());
});
// clean dist
gulp.task('clean:dist', function () {
    return gulp.src(['dist'], {read: false})
        .pipe($.clean());
});
gulp.task('jshint', function () {
    return gulp.src('app/scripts/**/*.js')
        .pipe($.jshint())
        .pipe($.jshint.reporter('default'));
});

// 静态服务
gulp.task('serve', function () {
    browserSync.init({
        open: false,
        server: {
            baseDir: './'
        }
    });
    gulp.watch(['app/**/*.*']).on('change', browserSync.reload);
});
// 监听任务
gulp.task('watch', function () {
    gulp.watch('app/images/**/*.*', ['images']);
    gulp.watch('app/json/*.json', ['json']);
    gulp.watch('app/scripts/**/*.js', ['jshint', 'scripts']);
    gulp.watch('app/styles/**/*.css', ['styles']);
    gulp.watch('app/vendor/**/*.*', ['vendor']);
    gulp.watch('app/views/**/*.html', ['views']);

});
gulp.task('watch:ts', function(){
    gulp.watch('app/scripts/research/*.ts', ['ts']);
});
// gulp.task('watch:ts', function(){
//     gulp.watch('tss/**/*.ts', ['ts']);
// });

var tsProject = $.typescript.createProject('tsconfig.json')
// typescript 任务 // es6 任务
// gulp.task('ts', function(){
//     return tsProject.src().pipe(tsProject()).pipe(gulp.dest('ts-dist'));
// });
gulp.task('ts', function(){
    return tsProject.src().pipe(tsProject()).pipe(gulp.dest('app/scripts/research'));
});

// 组合任务build，老任务，没有使用template
gulp.task('build:old', function () {
    gulp.start('clean:dist', 'images', 'json', 'scripts', 'styles', 'vendor', 'views');
});
// 组合任务build，使用template 2017-6-19
gulp.task('build', function () {
    gulp.start('template', 'images', 'json', 'scripts', 'styles');
});

// release步骤 更新时间： 2017-06-20
// 1.gulp clean:dist
// 2.gulp build
// 3.gulp replace
// 4.vendor文件夹的复制 -- 如果有问题的话
// 5.template.js的修改，加上,[]

// copy app -- 备份app
gulp.task('bak', ['clean:temp'], function () {
    return copyA2B('app', '.temp');
});

// 进入release模式之前，需要先进行template的缓存，（再修改部分代码？）如何用gulp执行
// copy dist -- 进入release模式
gulp.task('replace', ['clean:app'], function () {
    return copyA2B('dist', 'app');
});

// copy .temp -- 恢复到开发模式
gulp.task('dev', ['clean:app'], function () {
    return copyA2B('.temp', 'app');
});

// release 任务
// gulp.task('release', ['build', 'bak', 'replace']);// 执行组合任务时出现问题，分开执行正常

// 默认组合任务
// gulp.task('default', ['serve', 'watch']);
gulp.task('default', ['serve', 'watch:ts']);

// 在服务器上运行：只需要启动服务即可
gulp.task('start', ['serve']);

<commit_msg>修改gulpfile<commit_after>// 禁止提示框
process.env.DISABLE_NOTIFIER = true;
// 载入插件
var gulp = require('gulp'),
    $ = require('gulp-load-plugins')(),
    browserSync = require('browser-sync');
// 压缩vendor
// gulp.task('vendor', ['clean:vendor'], function () {
//     var filterJS = $.filter('**/*.js', {restore: true});
//     var filterCss = $.filter('**/*.css', {restore: true});
//     return gulp.src('app/vendor/**/*.*')
//         .pipe(filterJS)
//         .pipe($.uglify())
//         .pipe(filterJS.restore)
//         .pipe(filterCss)
//         .pipe($.cleanCss())
//         .pipe(filterCss.restore)
//         .pipe(gulp.dest('dist/vendor'))
//         .pipe($.notify({message: 'vendor task complete'}));
// });

gulp.task('vendor', function(){
    return gulp.src('app/vendor/**/*.*')
        .pipe(gulp.dest('dist/vendor'));
});

// 清除dist/vendor
gulp.task('clean:vendor', function () {
    return gulp.src(['dist/vendor/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩scripts
gulp.task('scripts', function () {
    return gulp.src('app/scripts/**/*.js')
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.ngAnnotate())
        .pipe($.uglify({output:{max_line_len: 120000}}))
        .pipe(gulp.dest('dist/scripts'))
        .pipe($.notify({message: 'scripts task complete'}));
});

// 清除dist/scripts
gulp.task('clean:scripts', function () {
    return gulp.src(['dist/scripts/**/*.js'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩json
gulp.task('json', function () {
    return gulp.src('app/json/**/*.json')
        .pipe(gulp.dest('dist/json'))
        .pipe($.notify({message: 'json task complete'}));
});
// 清除dist/json
gulp.task('clean:json', function () {
    return gulp.src(['dist/json/**/*.json'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩styles
gulp.task('styles', function () {
    return gulp.src('app/styles/**/*.css')
        .pipe($.autoprefixer())
        .pipe($.csscomb())
        .pipe($.cleanCss())
        .pipe(gulp.dest('dist/styles'))
        .pipe($.notify({message: 'styles task complete'}));
});
// 清除dist/styles
gulp.task('clean:styles', function () {
    return gulp.src(['dist/styles/**/*.css', 'dist/styles/*.css'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩images
gulp.task('images', function () {
    return gulp.src('app/images/*.*')
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.cache($.imagemin({optimizationLevel: 3, progressive: true, interlaced: true})))
        .pipe(gulp.dest('dist/images'))
        .pipe($.notify({message: 'images task complete'}));
});
// 清除dist/images
gulp.task('clean:images', function () {
    return gulp.src(['dist/images/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 压缩views
gulp.task('views', function () {
    return gulp.src('app/views/**/*.html')
        .pipe($.htmlmin({
            collapseWhitespace: true,
            collapseBooleanAttributes: true,
            removeComments: true,
            removeEmptyAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            minifyJS: true,
            minifyCSS: true
        }))
        .pipe(gulp.dest('dist/views'))
        .pipe($.notify({message: 'images task complete'}));
});
// 清除dist/views
gulp.task('clean:views', function () {
    return gulp.src(['dist/views/**/*.*'], {read: false})
        // .pipe($.plumber({
        //     errorHandler: function (error) {
        //         $.notify.onError('Error: <%= error.message %>')
        //     }
        // }))
        .pipe($.clean());
});
// 生成template 缓存模块
gulp.task('template', function(){
    return gulp.src('app/views/**/*.html')
        .pipe($.angularTemplatecache({
            root: 'app/views/'
        }))
        .pipe(gulp.dest('app/scripts/template-cache'))
});

var copyA2B = function (A, B) {
    var dirs = ['images', 'json', 'scripts', 'styles', 'views'];
    for (var i = 0, l = dirs.length; i < l; i++) {
        var dir = dirs[i],
            start = '' + A + '/' + dir + '/**/*.*',
            end = '' + B + '/' + dir;
        gulp.src(start)
            .pipe(gulp.dest(end))
            .pipe($.notify({message: 'copy ' + dir + ' complete'}));
    }
};

// clean app
gulp.task('clean:app', function () {
    return gulp.src(['app/**/*.*'], {read: false})
        .pipe($.clean());
});
// clean .temp
gulp.task('clean:temp', function () {
    return gulp.src(['.temp/**/*.*'], {read: false})
        .pipe($.clean());
});
// clean dist
gulp.task('clean:dist', function () {
    return gulp.src(['dist'], {read: false})
        .pipe($.clean());
});
gulp.task('jshint', function () {
    return gulp.src('app/scripts/**/*.js')
        .pipe($.jshint())
        .pipe($.jshint.reporter('default'));
});

// 静态服务
gulp.task('serve', function () {
    browserSync.init({
        open: false,
        server: {
            baseDir: './'
        }
    });
    gulp.watch(['app/**/*.*']).on('change', browserSync.reload);
});
// 监听任务
gulp.task('watch', function () {
    gulp.watch('app/images/**/*.*', ['images']);
    gulp.watch('app/json/*.json', ['json']);
    gulp.watch('app/scripts/**/*.js', ['jshint', 'scripts']);
    gulp.watch('app/styles/**/*.css', ['styles']);
    gulp.watch('app/vendor/**/*.*', ['vendor']);
    gulp.watch('app/views/**/*.html', ['views']);

});
gulp.task('watch:ts', function(){
    gulp.watch('app/scripts/research/*.ts', ['ts']);
});
// gulp.task('watch:ts', function(){
//     gulp.watch('tss/**/*.ts', ['ts']);
// });

var tsProject = $.typescript.createProject('tsconfig.json')
// typescript 任务 // es6 任务
// gulp.task('ts', function(){
//     return tsProject.src().pipe(tsProject()).pipe(gulp.dest('ts-dist'));
// });
gulp.task('ts', function(){
    return tsProject.src().pipe(tsProject()).pipe(gulp.dest('app/scripts/research'));
});

// 组合任务build，老任务，没有使用template
gulp.task('build:old', function () {
    gulp.start('clean:dist', 'images', 'json', 'scripts', 'styles', 'vendor', 'views');
});
// 组合任务build，使用template 2017-6-19
gulp.task('build', function () {
    gulp.start('template', 'images', 'json', 'scripts', 'styles', 'views');
});

// release步骤 更新时间： 2017-06-20
// 1.gulp clean:dist
// 2.gulp build
// 3.gulp replace
// 4.vendor文件夹的复制 -- 如果有问题的话
// 5.template.js的修改，加上,[]

// copy app -- 备份app
gulp.task('bak', ['clean:temp'], function () {
    return copyA2B('app', '.temp');
});

// 进入release模式之前，需要先进行template的缓存，（再修改部分代码？）如何用gulp执行
// copy dist -- 进入release模式
gulp.task('replace', ['clean:app'], function () {
    return copyA2B('dist', 'app');
});

// copy .temp -- 恢复到开发模式
gulp.task('dev', ['clean:app'], function () {
    return copyA2B('.temp', 'app');
});

// release 任务
// gulp.task('release', ['build', 'bak', 'replace']);// 执行组合任务时出现问题，分开执行正常

// 默认组合任务
// gulp.task('default', ['serve', 'watch']);
gulp.task('default', ['serve', 'watch:ts']);

// 在服务器上运行：只需要启动服务即可
gulp.task('start', ['serve']);

<|endoftext|>


<commit_before>var browserify = require('browserify');
var gulp = require('gulp');
var connect = require('gulp-connect');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify')
var uglify = require('gulp-uglify');

gulp.task('sass', function() {
  return gulp.src('scss/literally.scss')
    .pipe(sass({ style: 'compressed' }))
    .pipe(gulp.dest('lib/css'))
    .pipe(connect.reload())
});

gulp.task('browserify', function() {
  var bundleStream = browserify({
      basedir: 'src', extensions: ['.js', '.coffee']
  }).add('./index.coffee')
    .external('React/addons')
    .external('React')
    .transform('coffeeify')
    .bundle({standalone: 'LC'})

  return bundleStream
    .pipe(source('./src/index.coffee'))
    //.pipe(streamify(uglify()))
    .pipe(rename('literallycanvas.js'))
    .pipe(gulp.dest('./lib/js/'))
    .pipe(connect.reload());
});

gulp.task('uglify', ['browserify'], function() {
  return gulp.src('./lib/js/literallycanvas.js')
    .pipe(uglify())
    .pipe(rename('literallycanvas.min.js'))
    .pipe(gulp.dest('./lib/js'));
});

gulp.task('default', ['uglify', 'sass'], function() {
});

gulp.task('demo-reload', function () {
  return gulp.src('demo/*').pipe(connect.reload());
});

gulp.task('watch', function() {
  gulp.watch(['src/*.coffee', 'src/*/*.coffee'], ['browserify']);
  gulp.watch('scss/*.scss', ['sass']);
  gulp.watch('demo/*', ['demo-reload']);
});

gulp.task('serve', function() {
  connect.server({
    livereload: true
  });
});

gulp.task('dev', ['browserify', 'sass', 'watch', 'serve'], function() {
});
<commit_msg>Give livereload a different port because I use it for like six things<commit_after>var browserify = require('browserify');
var gulp = require('gulp');
var connect = require('gulp-connect');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify')
var uglify = require('gulp-uglify');

gulp.task('sass', function() {
  return gulp.src('scss/literally.scss')
    .pipe(sass({ style: 'compressed' }))
    .pipe(gulp.dest('lib/css'))
    .pipe(connect.reload())
});

gulp.task('browserify', function() {
  var bundleStream = browserify({
      basedir: 'src', extensions: ['.js', '.coffee']
  }).add('./index.coffee')
    .external('React/addons')
    .external('React')
    .transform('coffeeify')
    .bundle({standalone: 'LC'})

  return bundleStream
    .pipe(source('./src/index.coffee'))
    //.pipe(streamify(uglify()))
    .pipe(rename('literallycanvas.js'))
    .pipe(gulp.dest('./lib/js/'))
    .pipe(connect.reload());
});

gulp.task('uglify', ['browserify'], function() {
  return gulp.src('./lib/js/literallycanvas.js')
    .pipe(uglify())
    .pipe(rename('literallycanvas.min.js'))
    .pipe(gulp.dest('./lib/js'));
});

gulp.task('default', ['uglify', 'sass'], function() {
});

gulp.task('demo-reload', function () {
  return gulp.src('demo/*').pipe(connect.reload());
});

gulp.task('watch', function() {
  gulp.watch(['src/*.coffee', 'src/*/*.coffee'], ['browserify']);
  gulp.watch('scss/*.scss', ['sass']);
  gulp.watch('demo/*', ['demo-reload']);
});

gulp.task('serve', function() {
  connect.server({
    livereload: {port: 35728}
  });
});

gulp.task('dev', ['browserify', 'sass', 'watch', 'serve'], function() {
});
<|endoftext|>