Merge branch 'master' into testing

This commit is contained in:
Holger 2015-08-11 14:40:12 +02:00
commit 29fa276737
861 changed files with 253282 additions and 723 deletions

2
.gitignore vendored
View File

@ -14,3 +14,5 @@
.idea/watcherTasks.xml .idea/watcherTasks.xml
.idea/watcherTasks.xml .idea/watcherTasks.xml
.sass-cache

0
404.php Normal file → Executable file
View File

View File

@ -3,6 +3,35 @@ UnderStrap Wordpress Theme Framework
Live Demo: http://holgerkoenemann.de/understrap/ Live Demo: http://holgerkoenemann.de/understrap/
Changelog
=
- **0.3.0 Mar. 23th 2015**
- Streamlining some code, adding extra "sticky" area (sticky posts above the main content area inside an extra loop). Fixing some child theme issues (now its really child theme ready...really...trust me...)
- **0.2.9 Mar. 10th 2015**
- Adding a new theme customizer option. It lets you add a code snippet right before the closing </body> tag.
For example for Google Analytics, Google Tag Mananger, Pingdom etc. Just copy and past your code to the input field and save the setting.
So you don´t have to edit the theme source file´s directly and your theme stay´s updateable
- **0.2.8 Feb. 6th 2015**
- Adding Grunt and Grunt SASS task
- **0.2.7 Jan. 26th 2015**
- Adding some basic theme option for the build-in slider script
- **0.2.6 Dec. 28th 2014**
- CLean up
- **0.2 Dec. 22th 2014**
- Adding Jasny Off-Canvas nav and Owl.Carousel Slider script
- Enqueue scipts and styled dynamically
- **0.1 Dec. 10th 2014 - First commit**
About
=
Basically I like the _s Wordpress Starter Theme from Automattic and the grid Framework Bootstrap. Additionally I´am a huge SASS/COMPASS fan. Why don´t combine all these three things into a solid Wordpress Theme Framework? Basically I like the _s Wordpress Starter Theme from Automattic and the grid Framework Bootstrap. Additionally I´am a huge SASS/COMPASS fan. Why don´t combine all these three things into a solid Wordpress Theme Framework?
That´s what UnderStrap is (or will be...) That´s what UnderStrap is (or will be...)
@ -11,11 +40,10 @@ At the moment UnderStrap is in a very early stage. But if you wan´t feel free t
Basic Features Basic Features
= =
- Combines the _s Wordpress Starter Theme and Bootstrap - Combines the _s Wordpress Starter Theme and Bootstrap
- Comes with Bootstrap SASS source files and additonal scss files. Nicely sorted and ready to add your own variables/customize the Bootstrap variables. - Comes with Bootstrap SASS source files and additional scss files. Nicely sorted and ready to add your own variables/customize the Bootstrap variables.
- Uses a single and minified CSS file - Uses a single and minified CSS file for all the basic stuff
- Font Awesome Icon Font integrated - Font Awesome Icon Font integrated (V 4.2.0): http://fortawesome.github.io/Font-Awesome/
- Off-Canvas navigation - By Jasny Bootstrap Plugin (activate it by adding a widget to widget position "Off Canvas" - It works but did not looks good at the moment... ) - Comes with extra slider script - By owl.carousel (V 2.0.0-beta.2.4): http://www.owlcarousel.owlgraphic.com/
- Comes with extra slider script - By owl.carousel
- Simple RTL file - Simple RTL file
- Jetpack ready - Jetpack ready
- Child Theme ready (A basic starter Child Theme will be released in the future as a separate Repository) - Child Theme ready (A basic starter Child Theme will be released in the future as a separate Repository)
@ -45,4 +73,10 @@ Some basics about the SCSS and CSS files comes with UnderStrap:
- Don´t edit the first four files/filesets or you aren´t able to update it without overwriting your own work! - Don´t edit the first four files/filesets or you aren´t able to update it without overwriting your own work!
- Your design goes into: /sass/theme directory. Add your styles to the theme.scss file and your variables to the _theme_variables.scss. Or add other scss files into it and @import it into theme.scss - Your design goes into: /sass/theme directory. Add your styles to the theme.scss file and your variables to the _theme_variables.scss. Or add other scss files into it and @import it into theme.scss
Installation
=
- Download the understrap folder
- Upload it into your Wordpress installation subfolder here: /wp-content/themes/
- Login to your Wordpress backend
- Go to Appearance -> Themes
- Activate the UnderStrap theme

0
archive.php Normal file → Executable file
View File

View File

@ -64,6 +64,12 @@ if ( post_password_required() ) {
<p class="no-comments"><?php _e( 'Comments are closed.', 'understrap' ); ?></p> <p class="no-comments"><?php _e( 'Comments are closed.', 'understrap' ); ?></p>
<?php endif; ?> <?php endif; ?>
<?php get_template_part('comment-form'); ?> <?php
/* Loads the comment-form.php template
/* get_template_part('comment-form');
*/
?>
<?php comment_form(); ?>
</div><!-- #comments --> </div><!-- #comments -->

View File

@ -23,7 +23,6 @@
<div class="entry-content"> <div class="entry-content">
<?php <?php
/* translators: %s: Name of current post */
the_excerpt(); the_excerpt();
?> ?>

0
css/jasny-bootstrap.css Normal file → Executable file
View File

0
css/jasny-bootstrap.min.css vendored Normal file → Executable file
View File

0
css/owl.carousel.css Normal file → Executable file
View File

File diff suppressed because one or more lines are too long

9306
css/theme.css Normal file → Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
css/theme.min.css vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -32,14 +32,16 @@
<!-- Loads slider script and settings if a widget on pos hero is published --> <!-- Loads slider script and settings if a widget on pos hero is published -->
<?php if ( is_active_sidebar( 'hero' ) ): ?> <?php if ( is_active_sidebar( 'hero' ) ): ?>
<script> <script>
jQuery(document).ready(function() { jQuery(document).ready(function() {
var owl = jQuery('.owl-carousel'); var owl = jQuery('.owl-carousel');
owl.owlCarousel({ owl.owlCarousel({
items:1, items:<?php echo get_theme_mod( 'understrap_theme_slider_count_setting', 1 );?>,
loop:true, loop:<?php echo get_theme_mod( 'understrap_theme_slider_loop_setting', true );?>,
autoplay:true, autoplay:true,
autoplayTimeout:5000, autoplayTimeout:<?php echo get_theme_mod( 'understrap_theme_slider_time_setting', 5000 );?>,
animateOut: 'fadeOut', animateOut: 'fadeOut',
animateIn: 'fadeIn', animateIn: 'fadeIn',
nav: false, nav: false,

View File

@ -43,6 +43,11 @@ require get_template_directory() . '/inc/extras.php';
*/ */
require get_template_directory() . '/inc/customizer.php'; require get_template_directory() . '/inc/customizer.php';
/**
* Customizer additions.
*/
require get_template_directory() . '/inc/custom-comments.php';
/** /**
* Load Jetpack compatibility file. * Load Jetpack compatibility file.
*/ */

46
gruntfile.js Normal file
View File

@ -0,0 +1,46 @@
module.exports = function(grunt) {
//2. Project configuration.
grunt.initConfig({
//define what to do with the SASS process
sass: { // Task
dev: { // Target
options: { // Target options
style: 'expanded',
sourcemap: 'none'
},
files: [{
src: ['sass/theme.scss'],
dest: 'css/theme.css',
ext: '.css'
}]
},
dist: { // Target
options: { // Target options
style: 'compressed',
sourcemap: 'none'
},
files: [{
src: ['sass/theme.scss'],
dest: 'css/theme.min.css',
ext: '.css'
}]
}
},
watch: {
css: {
files: ['sass/**/*.scss'],
tasks: ['sass']
}
}
});
//1. load task libraries for use
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
//3. register a named task ( 'process' ) that runs Grunt processes ( 'imagemin', 'concat' )
grunt.registerTask( 'process', [ 'sass:dev', 'sass:dist' ] );
};

View File

@ -14,6 +14,7 @@
<link rel="profile" href="http://gmpg.org/xfn/11"> <link rel="profile" href="http://gmpg.org/xfn/11">
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>"> <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
<?php wp_head(); ?> <?php wp_head(); ?>
<?php echo get_theme_mod( 'understrap_theme_script_code_setting' ); ?>
</head> </head>
<body <?php body_class(); ?>> <body <?php body_class(); ?>>
@ -21,7 +22,7 @@
<div id="page" class="hfeed site"> <div id="page" class="hfeed site">
<!-- ******************* The Navbar Area ******************* --> <!-- ******************* The Navbar Area ******************* -->
<div class="wrapper-fluid wrapper-navbar"> <div class="wrapper-fluid wrapper-navbar" id="wrapper-navbar">
<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'understrap' ); ?></a> <a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'understrap' ); ?></a>
@ -69,28 +70,10 @@
</div> <!-- .col-md-11 or col-md-12 end --> </div> <!-- .col-md-11 or col-md-12 end -->
</div> <!-- .container --> </div> <!-- .container -->
</div><!-- .navbar --> </div><!-- .navbar -->
<?php if ( is_active_sidebar( 'off-canvas' ) ): ?>
<div class="navmenu navmenu-inverse navmenu-fixed-left offcanvas">
<!-- Off Canvas Toggle -->
<a class="off-canvas-toggle-link" data-toggle="offcanvas" data-target=".navmenu" data-canvas="body">
menu
</a>
<!-- Off Canvas Widget itself -->
<?php dynamic_sidebar( 'off-canvas' ); ?>
</div>
<?php else : ?>
<?php endif; ?>
</nav><!-- .site-navigation --> </nav><!-- .site-navigation -->
</div><!-- .wrapper-navbar end --> </div><!-- .wrapper-navbar end -->

View File

@ -1,10 +1,8 @@
<?php if ( is_active_sidebar( 'hero' ) ): ?> <?php if ( is_active_sidebar( 'hero' ) ): ?>
<!-- ******************* The Hero Widget Area ******************* -->
<div class="wrapper" id="hero-wrapper"> <div class="wrapper" id="wrapper-hero">
<div class="owl-carousel"> <div class="owl-carousel">
<?php dynamic_sidebar( 'hero' ); ?> <?php dynamic_sidebar( 'hero' ); ?>
</div> </div>
</div> </div>

29
inc/custom-comments.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/************* COMMENT LAYOUT *********************/
// Comment Form
add_filter( 'comment_form_default_fields', 'bootstrap3_comment_form_fields' );
function bootstrap3_comment_form_fields( $fields ) {
$commenter = wp_get_current_commenter();
$req = get_option( 'require_name_email' );
$aria_req = ( $req ? " aria-required='true'" : '' );
$html5 = current_theme_supports( 'html5', 'comment-form' ) ? 1 : 0;
$fields = array(
'author' => '<div class="form-group comment-form-author">' . '<label for="author">' . __( 'Name' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
'<input class="form-control" id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' /></div>',
'email' => '<div class="form-group comment-form-email"><label for="email">' . __( 'Email' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
'<input class="form-control" id="email" name="email" ' . ( $html5 ? 'type="email"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' /></div>',
'url' => '<div class="form-group comment-form-url"><label for="url">' . __( 'Website' ) . '</label> ' .
'<input class="form-control" id="url" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></div>',
);
return $fields;
}
add_filter( 'comment_form_defaults', 'bootstrap3_comment_form' );
function bootstrap3_comment_form( $args ) {
$args['comment_field'] = '<div class="form-group comment-form-comment">
<label for="comment">' . _x( 'Comment', 'noun' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label>
<textarea class="form-control" id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea>
</div>';
return $args;
}

View File

@ -18,6 +18,72 @@ function understrap_customize_register( $wp_customize ) {
} }
add_action( 'customize_register', 'understrap_customize_register' ); add_action( 'customize_register', 'understrap_customize_register' );
function understrap_theme_customize_register( $wp_customize ) {
$wp_customize->add_section( 'understrap_theme_slider_options', array(
'title' => __( 'Slider Settings', 'understrap' )
) );
$wp_customize->add_setting( 'understrap_theme_slider_count_setting', array(
'default' => '1',
'sanitize_callback' => 'esc_textarea'
) );
$wp_customize->add_control( 'understrap_theme_slider_count', array(
'label' => __( 'Number of slides displaying at once', 'understrap' ),
'section' => 'understrap_theme_slider_options',
'type' => 'text',
'settings' => 'understrap_theme_slider_count_setting'
) );
$wp_customize->add_setting( 'understrap_theme_slider_time_setting', array(
'default' => '5000',
'sanitize_callback' => 'esc_textarea'
) );
$wp_customize->add_control( 'understrap_theme_slider_time', array(
'label' => __( 'Slider Time (in ms)', 'understrap' ),
'section' => 'understrap_theme_slider_options',
'type' => 'text',
'settings' => 'understrap_theme_slider_time_setting'
) );
$wp_customize->add_setting( 'understrap_theme_slider_loop_setting', array(
'default' => 'true',
'sanitize_callback' => 'esc_textarea'
) );
$wp_customize->add_control( 'understrap_theme_loop', array(
'label' => __( 'Loop Slider Content', 'understrap' ),
'section' => 'understrap_theme_slider_options',
'type' => 'radio',
'choices' => array(
'true' => 'yes',
'false' => 'no',
),
'settings' => 'understrap_theme_slider_loop_setting'
) );
$wp_customize->add_section( 'understrap_theme_script_options', array(
'title' => __( 'Add scripts', 'understrap' )
) );
$wp_customize->add_setting( 'understrap_theme_script_code_setting', array(
'default' => '',
'sanitize_callback' => 'esc_textarea'
) );
$wp_customize->add_control( 'understrap_theme_script_code', array(
'label' => __( 'Add custom JS code here', 'understrap' ),
'section' => 'understrap_theme_script_options',
'type' => 'textarea',
'settings' => 'understrap_theme_script_code_setting'
) );
}
add_action( 'customize_register', 'understrap_theme_customize_register' );
/** /**
* Binds JS handlers to make Theme Customizer preview reload changes asynchronously. * Binds JS handlers to make Theme Customizer preview reload changes asynchronously.
*/ */

View File

@ -1,7 +1,7 @@
<?php <?php
function understrap_scripts() { function understrap_scripts() {
wp_enqueue_style( 'understrap-theme', get_stylesheet_directory_uri() . '/css/theme.css', array(), '0.1', false ); wp_enqueue_style( 'understrap-theme', get_stylesheet_directory_uri() . '/css/theme.min.css', array(), '0.2.8', false );
wp_enqueue_script('jquery'); wp_enqueue_script('jquery');
wp_enqueue_script( 'understrap-navigation', get_template_directory_uri() . '/js/bootstrap.min.js', array(), '20120206', true ); wp_enqueue_script( 'understrap-navigation', get_template_directory_uri() . '/js/bootstrap.min.js', array(), '20120206', true );
@ -17,10 +17,4 @@ function understrap_scripts() {
wp_enqueue_script( 'understrap-carousel-script', get_template_directory_uri() . '/js/owl.carousel.min.js', array(), '20024', true );} wp_enqueue_script( 'understrap-carousel-script', get_template_directory_uri() . '/js/owl.carousel.min.js', array(), '20024', true );}
} }
if ( is_active_sidebar( 'off-canvas' ) ) {
wp_enqueue_style('understrap-off-canvas-style', get_template_directory_uri() . '/css/jasny-bootstrap.min.css', array(), '310', false);
wp_enqueue_script('understrap-off-canvas-script', get_template_directory_uri() . '/js/jasny-bootstrap.min.js', array(), '310', true);
}
add_action( 'wp_enqueue_scripts', 'understrap_scripts' ); add_action( 'wp_enqueue_scripts', 'understrap_scripts' );

View File

@ -35,7 +35,7 @@ function understrap_body_classes( $classes ) {
} }
add_filter( 'body_class', 'understrap_body_classes' ); add_filter( 'body_class', 'understrap_body_classes' );
if ( ! function_exists( '_wp_render_title_tag' ) ) : if ( version_compare( $GLOBALS['wp_version'], '4.1', '<' ) ) :
/** /**
* Filters wp_title to print a neat <title> tag based on what is being viewed. * Filters wp_title to print a neat <title> tag based on what is being viewed.
* *
@ -47,26 +47,35 @@ if ( ! function_exists( '_wp_render_title_tag' ) ) :
if ( is_feed() ) { if ( is_feed() ) {
return $title; return $title;
} }
global $page, $paged; global $page, $paged;
// Add the blog name // Add the blog name
$title .= get_bloginfo( 'name', 'display' ); $title .= get_bloginfo( 'name', 'display' );
// Add the blog description for the home/front page. // Add the blog description for the home/front page.
$site_description = get_bloginfo( 'description', 'display' ); $site_description = get_bloginfo( 'description', 'display' );
if ( $site_description && ( is_home() || is_front_page() ) ) { if ( $site_description && ( is_home() || is_front_page() ) ) {
$title .= " $sep $site_description"; $title .= " $sep $site_description";
} }
// Add a page number if necessary: // Add a page number if necessary:
if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) { if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) {
$title .= " $sep " . sprintf( __( 'Page %s', 'understrap' ), max( $paged, $page ) ); $title .= " $sep " . sprintf( __( 'Page %s', 'understrap' ), max( $paged, $page ) );
} }
return $title; return $title;
} }
add_filter( 'wp_title', 'understrap_wp_title', 10, 2 ); add_filter( 'wp_title', 'understrap_wp_title', 10, 2 );
/**
* Title shim for sites older than WordPress 4.1.
*
* @link https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/
* @todo Remove this function when WordPress 4.3 is released.
*/
function understrap_render_title() {
?>
<title><?php wp_title( '|', true, 'right' ); ?></title>
<?php
}
add_action( 'wp_head', 'understrap_render_title' );
endif; endif;
if ( ! function_exists( '_wp_render_title_tag' ) ) : if ( ! function_exists( '_wp_render_title_tag' ) ) :
@ -76,8 +85,11 @@ if ( ! function_exists( '_wp_render_title_tag' ) ) :
* @link https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/ * @link https://make.wordpress.org/core/2014/10/29/title-tags-in-4-1/
* @todo Remove this function when WordPress 4.3 is released. * @todo Remove this function when WordPress 4.3 is released.
*/ */
function understrap_render_title() { function understrap_render_title() {
echo '<title>' . wp_title( '|', false, 'right' ) . "</title>\n"; ?>
<title><?php wp_title( '|', true, 'right' ); ?></title>
<?php
} }
add_action( 'wp_head', 'understrap_render_title' ); add_action( 'wp_head', 'understrap_render_title' );
endif; endif;

View File

@ -100,6 +100,6 @@ add_theme_support( 'post-thumbnails' );
function all_excerpts_get_more_link($post_excerpt) { function all_excerpts_get_more_link($post_excerpt) {
return $post_excerpt . ' [...]<p><a class="btn btn-default" href="'. get_permalink($post->ID) . '">' . 'Read More...' . '</a></p>'; return $post_excerpt . ' [...]<p><a class="btn btn-default understrap-read-more-link" href="'. get_permalink($post->ID) . '">' . 'Read More...' . '</a></p>';
} }
add_filter('wp_trim_excerpt', 'all_excerpts_get_more_link'); add_filter('wp_trim_excerpt', 'all_excerpts_get_more_link');

View File

@ -19,7 +19,7 @@ function understrap_widgets_init() {
'before_title' => '', 'before_title' => '',
'after_title' => '', 'after_title' => '',
) ); ) );
/*
register_sidebar( array( register_sidebar( array(
'name' => __( 'Off Canvas', 'understrap' ), 'name' => __( 'Off Canvas', 'understrap' ),
'id' => 'off-canvas', 'id' => 'off-canvas',
@ -28,6 +28,6 @@ function understrap_widgets_init() {
'after_widget' => '</div>', 'after_widget' => '</div>',
'before_title' => '', 'before_title' => '',
'after_title' => '', 'after_title' => '',
) ); ) );*/
} }
add_action( 'widgets_init', 'understrap_widgets_init' ); add_action( 'widgets_init', 'understrap_widgets_init' );

68
inc/wp-updates-theme.php Normal file
View File

@ -0,0 +1,68 @@
<?php
/*
WPUpdates Theme Updater Class
http://wp-updates.com
v2.0
Example Usage:
require_once('wp-updates-theme.php');
new WPUpdatesThemeUpdater_1114( 'http://wp-updates.com/api/2/theme', basename(get_template_directory()) );
*/
if( !class_exists('WPUpdatesThemeUpdater_1114') ) {
class WPUpdatesThemeUpdater_1114 {
var $api_url;
var $theme_id = 1114;
var $theme_slug;
var $license_key;
function __construct( $api_url, $theme_slug, $license_key = null ) {
$this->api_url = $api_url;
$this->theme_slug = $theme_slug;
$this->license_key = $license_key;
add_filter( 'pre_set_site_transient_update_themes', array(&$this, 'check_for_update') );
// This is for testing only!
//set_site_transient('update_themes', null);
}
function check_for_update( $transient ) {
if (empty($transient->checked)) return $transient;
$request_args = array(
'id' => $this->theme_id,
'slug' => $this->theme_slug,
'version' => $transient->checked[$this->theme_slug]
);
if ($this->license_key) $request_args['license'] = $this->license_key;
$request_string = $this->prepare_request( 'theme_update', $request_args );
$raw_response = wp_remote_post( $this->api_url, $request_string );
$response = null;
if( !is_wp_error($raw_response) && ($raw_response['response']['code'] == 200) )
$response = unserialize($raw_response['body']);
if( !empty($response) ) // Feed the update data into WP updater
$transient->response[$this->theme_slug] = $response;
return $transient;
}
function prepare_request( $action, $args ) {
global $wp_version;
return array(
'body' => array(
'action' => $action,
'request' => serialize($args),
'api-key' => md5(home_url())
),
'user-agent' => 'WordPress/'. $wp_version .'; '. home_url()
);
}
}
}

View File

@ -15,7 +15,9 @@ get_header(); ?>
<?php get_template_part('hero'); ?> <?php get_template_part('hero'); ?>
<div class="wrapper" id="index-wrapper"> <?php get_template_part('sticky'); ?>
<div class="wrapper" id="wrapper-index">
<div class="container"> <div class="container">
@ -23,11 +25,10 @@ get_header(); ?>
<main id="main" class="site-main" role="main"> <main id="main" class="site-main" role="main">
<?php if ( have_posts() ) : ?> <?php
$the_query = new WP_Query( array( 'post__not_in' => get_option( 'sticky_posts' ) ) );
<?php /* Start the Loop */ ?> if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<?php while ( have_posts() ) : the_post(); ?>
<?php <?php
/* Include the Post-Format-specific template for the content. /* Include the Post-Format-specific template for the content.

0
js/bootstrap.js vendored Normal file → Executable file
View File

0
js/bootstrap.min.js vendored Normal file → Executable file
View File

0
js/customizer.js Normal file → Executable file
View File

View File

@ -1,369 +0,0 @@
/* ========================================================================
* Bootstrap: offcanvas.js v3.1.3
* http://jasny.github.io/bootstrap/javascript/#offcanvas
* ========================================================================
* Copyright 2013-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// OFFCANVAS PUBLIC CLASS DEFINITION
// =================================
var OffCanvas = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, OffCanvas.DEFAULTS, options)
this.state = null
this.placement = null
if (this.options.recalc) {
this.calcClone()
$(window).on('resize', $.proxy(this.recalc, this))
}
if (this.options.autohide)
$(document).on('click', $.proxy(this.autohide, this))
if (this.options.toggle) this.toggle()
if (this.options.disablescrolling) {
this.options.disableScrolling = this.options.disablescrolling
delete this.options.disablescrolling
}
}
OffCanvas.DEFAULTS = {
toggle: true,
placement: 'auto',
autohide: true,
recalc: true,
disableScrolling: true
}
OffCanvas.prototype.offset = function () {
switch (this.placement) {
case 'left':
case 'right': return this.$element.outerWidth()
case 'top':
case 'bottom': return this.$element.outerHeight()
}
}
OffCanvas.prototype.calcPlacement = function () {
if (this.options.placement !== 'auto') {
this.placement = this.options.placement
return
}
if (!this.$element.hasClass('in')) {
this.$element.css('visiblity', 'hidden !important').addClass('in')
}
var horizontal = $(window).width() / this.$element.width()
var vertical = $(window).height() / this.$element.height()
var element = this.$element
function ab(a, b) {
if (element.css(b) === 'auto') return a
if (element.css(a) === 'auto') return b
var size_a = parseInt(element.css(a), 10)
var size_b = parseInt(element.css(b), 10)
return size_a > size_b ? b : a
}
this.placement = horizontal >= vertical ? ab('left', 'right') : ab('top', 'bottom')
if (this.$element.css('visibility') === 'hidden !important') {
this.$element.removeClass('in').css('visiblity', '')
}
}
OffCanvas.prototype.opposite = function (placement) {
switch (placement) {
case 'top': return 'bottom'
case 'left': return 'right'
case 'bottom': return 'top'
case 'right': return 'left'
}
}
OffCanvas.prototype.getCanvasElements = function() {
// Return a set containing the canvas plus all fixed elements
var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
var fixed_elements = canvas.find('*').filter(function() {
return $(this).css('position') === 'fixed'
}).not(this.options.exclude)
return canvas.add(fixed_elements)
}
OffCanvas.prototype.slide = function (elements, offset, callback) {
// Use jQuery animation if CSS transitions aren't supported
if (!$.support.transition) {
var anim = {}
anim[this.placement] = "+=" + offset
return elements.animate(anim, 350, callback)
}
var placement = this.placement
var opposite = this.opposite(placement)
elements.each(function() {
if ($(this).css(placement) !== 'auto')
$(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
if ($(this).css(opposite) !== 'auto')
$(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
})
this.$element
.one($.support.transition.end, callback)
.emulateTransitionEnd(350)
}
OffCanvas.prototype.disableScrolling = function() {
var bodyWidth = $('body').width()
var prop = 'padding-' + this.opposite(this.placement)
if ($('body').data('offcanvas-style') === undefined) {
$('body').data('offcanvas-style', $('body').attr('style') || '')
}
$('body').css('overflow', 'hidden')
if ($('body').width() > bodyWidth) {
var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
setTimeout(function() {
$('body').css(prop, padding)
}, 1)
}
}
OffCanvas.prototype.show = function () {
if (this.state) return
var startEvent = $.Event('show.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
this.state = 'slide-in'
this.calcPlacement();
var elements = this.getCanvasElements()
var placement = this.placement
var opposite = this.opposite(placement)
var offset = this.offset()
if (elements.index(this.$element) !== -1) {
$(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '')
this.$element.css(placement, -1 * offset)
this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code
}
elements.addClass('canvas-sliding').each(function() {
if ($(this).data('offcanvas-style') === undefined) $(this).data('offcanvas-style', $(this).attr('style') || '')
if ($(this).css('position') === 'static') $(this).css('position', 'relative')
if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
$(this).css(placement, 0)
}
})
if (this.options.disableScrolling) this.disableScrolling()
var complete = function () {
if (this.state != 'slide-in') return
this.state = 'slid'
elements.removeClass('canvas-sliding').addClass('canvas-slid')
this.$element.trigger('shown.bs.offcanvas')
}
setTimeout($.proxy(function() {
this.$element.addClass('in')
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.hide = function (fast) {
if (this.state !== 'slid') return
var startEvent = $.Event('hide.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
this.state = 'slide-out'
var elements = $('.canvas-slid')
var placement = this.placement
var offset = -1 * this.offset()
var complete = function () {
if (this.state != 'slide-out') return
this.state = null
this.placement = null
this.$element.removeClass('in')
elements.removeClass('canvas-sliding')
elements.add(this.$element).add('body').each(function() {
$(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
})
this.$element.trigger('hidden.bs.offcanvas')
}
elements.removeClass('canvas-slid').addClass('canvas-sliding')
setTimeout($.proxy(function() {
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.toggle = function () {
if (this.state === 'slide-in' || this.state === 'slide-out') return
this[this.state === 'slid' ? 'hide' : 'show']()
}
OffCanvas.prototype.calcClone = function() {
this.$calcClone = this.$element.clone()
.html('')
.addClass('offcanvas-clone').removeClass('in')
.appendTo($('body'))
}
OffCanvas.prototype.recalc = function () {
if (this.$calcClone.css('display') === 'none' || (this.state !== 'slid' && this.state !== 'slide-in')) return
this.state = null
this.placement = null
var elements = this.getCanvasElements()
this.$element.removeClass('in')
elements.removeClass('canvas-slid')
elements.add(this.$element).add('body').each(function() {
$(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
})
}
OffCanvas.prototype.autohide = function (e) {
if ($(e.target).closest(this.$element).length === 0) this.hide()
}
// OFFCANVAS PLUGIN DEFINITION
// ==========================
var old = $.fn.offcanvas
$.fn.offcanvas = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.offcanvas')
var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option === 'object' && option)
if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
if (typeof option === 'string') data[option]()
})
}
$.fn.offcanvas.Constructor = OffCanvas
// OFFCANVAS NO CONFLICT
// ====================
$.fn.offcanvas.noConflict = function () {
$.fn.offcanvas = old
return this
}
// OFFCANVAS DATA-API
// =================
$(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
var $this = $(this), href
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $canvas = $(target)
var data = $canvas.data('bs.offcanvas')
var option = data ? 'toggle' : $this.data()
e.stopPropagation()
if (data) data.toggle()
else $canvas.offcanvas(option)
})
}(window.jQuery);
/* ========================================================================
* Bootstrap: transition.js v3.1.3
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
return false // explicit for ie8 ( ._.)
}
if ($.support.transition !== undefined) return // Prevent conflict with Twitter Bootstrap
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
var called = false, $el = this
$(this).one($.support.transition.end, function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
return this
}
$(function () {
$.support.transition = transitionEnd()
})
}(window.jQuery);

File diff suppressed because one or more lines are too long

0
js/navigation.js Normal file → Executable file
View File

0
js/owl.carousel.js Normal file → Executable file
View File

0
js/owl.carousel.min.js vendored Normal file → Executable file
View File

0
js/skip-link-focus-fix.js Normal file → Executable file
View File

13
node_modules/grunt-contrib-sass/.jshintrc generated vendored Executable file
View File

@ -0,0 +1,13 @@
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"boss": true,
"eqnull": true,
"node": true
}

1
node_modules/grunt-contrib-sass/AUTHORS generated vendored Executable file
View File

@ -0,0 +1 @@
Sindre Sorhus (http://github.com/sindresorhus)

88
node_modules/grunt-contrib-sass/CHANGELOG generated vendored Executable file
View File

@ -0,0 +1,88 @@
v0.8.1:
date: 2014-08-24
changes:
- Fix `check` option.
v0.8.0:
date: 2014-08-21
changes:
- Support Sass 3.4 Source Map option.
- Add `update` option.
v0.7.4:
date: 2014-08-09
changes:
- Fix bundleExec option.
- Fix `os.cpus()` issue.
- Log `sass` command when `--verbose` flag is set.
v0.7.3:
date: 2014-03-06
changes:
- Only create empty dest files when they don't already exist.
v0.7.2:
date: 2014-02-02
changes:
- Fix error reporting when Sass is not available.
v0.7.1:
date: 2014-01-28
changes:
- Fix regression of Bundler support.
v0.7.0:
date: 2014-01-26
changes:
- Improve Windows support.
v0.6.0:
date: 2013-12-10
changes:
- Ignore files where filename have leading underscore.
v0.5.0:
date: 2013-08-21
changes:
- Add banner option.
v0.4.1:
date: 2013-07-06
changes:
- Use file.orig.src if file.src does not exist and return early to avoid passing non-existent files to sass binary.
v0.4.0:
date: 2013-06-30
changes:
- Rewrite task to be able to support Source Maps.
- Compile Sass files in parallel for better performance.
v0.3.0:
date: 2013-03-26
changes:
- Add support for `bundle exec`. Make sure `.css` files are compiled with SCSS.
v0.2.2:
date: 2013-02-15
changes:
- First official release for Grunt 0.4.0.
v0.2.2rc7:
date: 2013-01-25
changes:
- Updating grunt/gruntplugin dependencies to rc7.
- Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
v0.2.2rc5:
date: 2013-01-09
changes:
- Updating to work with grunt v0.4.0rc5.
- Switching to this.files api.
- Add separator option.
v0.2.0:
date: 2012-11-05
changes:
- Grunt 0.4 compatibility.
- Improve error message when Sass binary couldn't be found
v0.1.3:
date: 2012-10-12
changes:
- Rename grunt-contrib-lib dep to grunt-lib-contrib.
v0.1.2:
date: 2012-10-08
changes:
- Fix regression for darwin.
v0.1.1:
date: 2012-10-05
changes:
- Windows support.
v0.1.0:
date: 2012-09-24
changes:
- Initial release.

1
node_modules/grunt-contrib-sass/CONTRIBUTING.md generated vendored Executable file
View File

@ -0,0 +1 @@
Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.

92
node_modules/grunt-contrib-sass/Gruntfile.js generated vendored Executable file
View File

@ -0,0 +1,92 @@
/*
* grunt-contrib-sass
* http://gruntjs.com/
*
* Copyright (c) 2012 Sindre Sorhus, contributors
* Licensed under the MIT license.
*/
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
pkg: {
name: 'grunt-contrib-sass'
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: [
'Gruntfile.js',
'tasks/*.js',
'<%= nodeunit.tests %>'
]
},
clean: {
test: [
'test/tmp',
'.sass-cache'
]
},
nodeunit: {
tests: ['test/*_test.js']
},
sass: {
options: {
sourcemap: 'none'
},
compile: {
files: {
'test/tmp/scss.css': ['test/fixtures/compile.scss'],
'test/tmp/sass.css': ['test/fixtures/compile.sass'],
'test/tmp/css.css': ['test/fixtures/compile.css']
}
},
compileBanner: {
options: {
banner: '/* <%= pkg.name %> banner */'
},
files: {
'test/tmp/scss-banner.css': ['test/fixtures/banner.scss'],
'test/tmp/sass-banner.css': ['test/fixtures/banner.sass'],
'test/tmp/css-banner.css': ['test/fixtures/banner.css']
}
},
ignorePartials: {
cwd: 'test/fixtures/partials',
src: '*.scss',
dest: 'test/tmp',
expand: true,
ext: '.css'
},
updateTrue: {
options: {
update: true
},
files: [{
expand: true,
cwd: 'test/fixtures',
src: ['updatetrue.scss', 'updatetrue.sass', 'updatetrue.css'],
dest: 'test/tmp',
ext: '.css'
}]
}
}
});
grunt.loadTasks('tasks');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-contrib-internal');
grunt.registerTask('mkdir', grunt.file.mkdir);
grunt.registerTask('test', [
'clean',
'mkdir:tmp',
'sass',
'nodeunit',
'clean'
]);
grunt.registerTask('default', ['jshint', 'test', 'build-contrib']);
};

22
node_modules/grunt-contrib-sass/LICENSE-MIT generated vendored Executable file
View File

@ -0,0 +1,22 @@
Copyright (c) 2012 Sindre Sorhus, contributors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

286
node_modules/grunt-contrib-sass/README.md generated vendored Executable file
View File

@ -0,0 +1,286 @@
# grunt-contrib-sass v0.8.1 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-sass.png?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-sass)
> Compile Sass to CSS
## Getting Started
This plugin requires Grunt `>=0.4.0`
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
```shell
npm install grunt-contrib-sass --save-dev
```
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
```js
grunt.loadNpmTasks('grunt-contrib-sass');
```
## Sass task
_Run this task with the `grunt sass` command._
[Sass](http://sass-lang.com) is a preprocessor that adds nested rules, variables, mixins and functions, selector inheritance, and more to CSS. Sass files compile into well-formatted, standard CSS to use in your site or application.
This task requires you to have [Ruby](http://www.ruby-lang.org/en/downloads/) and [Sass](http://sass-lang.com/download.html) installed. If you're on OS X or Linux you probably already have Ruby installed; test with `ruby -v` in your terminal. When you've confirmed you have Ruby installed, run `gem install sass` to install Sass.
Note: Files that begin with "_" are ignored even if they match the globbing pattern. This is done to match the expected [Sass partial behaviour](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#partials).
### Options
#### sourcemap
Type: `String`
Default: `auto`
Values:
- `auto` - relative paths where possible, file URIs elsewhere
- `file` - always absolute file URIs
- `inline` - include the source text in the sourcemap
- `none`- no sourcemaps
**Requires Sass 3.4.0, which can be installed with `gem install sass`**
#### trace
Type: `Boolean`
Default: `false`
Show a full traceback on error.
#### unixNewlines
Type: `Boolean`
Default: `false` on Windows, otherwise `true`
Force Unix newlines in written files.
#### check
Type: `Boolean`
Default: `false`
Just check the Sass syntax, does not evaluate and write the output.
#### style
Type: `String`
Default: `nested`
Output style. Can be `nested`, `compact`, `compressed`, `expanded`.
#### precision
Type: `Number`
Default: `5`
How many digits of precision to use when outputting decimal numbers.
#### quiet
Type: `Boolean`
Default: `false`
Silence warnings and status messages during compilation.
#### compass
Type: `Boolean`
Default: `false`
Make Compass imports available and load project configuration (`config.rb` located close to the `Gruntfile.js`).
#### debugInfo
Type: `Boolean`
Default: `false`
Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin.
#### lineNumbers
Type: `Boolean`
Default: `false`
Emit comments in the generated CSS indicating the corresponding source line.
#### loadPath
Type: `String|Array`
Add a (or multiple) Sass import path.
#### require
Type: `String|Array`
Require a (or multiple) Ruby library before running Sass.
#### cacheLocation
Type: `String`
Default: `.sass-cache`
The path to put cached Sass files.
#### noCache
Type: `Boolean`
Default: `false`
Don't cache to sassc files.
#### bundleExec
Type: `Boolean`
Default: `false`
Run `sass` with [bundle exec](http://gembundler.com/man/bundle-exec.1.html): `bundle exec sass`.
#### banner
Type: `String`
Prepend the specified string to the output file. Useful for licensing information.
*Can't be used if you use the `sourcemap` option.*
#### update
Type: `Boolean`
Default: `false`
Only compile changed files.
### Examples
#### Example config
```javascript
grunt.initConfig({
sass: { // Task
dist: { // Target
options: { // Target options
style: 'expanded'
},
files: { // Dictionary of files
'main.css': 'main.scss', // 'destination': 'source'
'widgets.css': 'widgets.scss'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['sass']);
```
#### Compile
```javascript
grunt.initConfig({
sass: {
dist: {
files: {
'main.css': 'main.scss'
}
}
}
});
```
#### Concat and compile
Instead of concatenating the files, just `@import` them into another `.sass` file eg. `main.scss`.
#### Compile multiple files
You can specify multiple `destination: source` items in `files`.
```javascript
grunt.initConfig({
sass: {
dist: {
files: {
'main.css': 'main.scss',
'widgets.css': 'widgets.scss'
}
}
}
});
```
#### Compile files in a directory
Instead of naming all files you want to compile, you can use the `expand` property allowing you to specify a directory. More information available in the [grunt docs](http://gruntjs.com/configuring-tasks) - `Building the files object dynamically`.
```javascript
grunt.initConfig({
sass: {
dist: {
files: [{
expand: true,
cwd: 'styles',
src: ['*.scss'],
dest: '../public',
ext: '.css'
}]
}
}
});
```
## Release History
* 2014-08-24v0.8.1Fix `check` option.
* 2014-08-21v0.8.0Support Sass 3.4 Source Map option. Add `update` option.
* 2014-08-09v0.7.4Fix bundleExec option. Fix `os.cpus()` issue. Log `sass` command when `--verbose` flag is set.
* 2014-03-06v0.7.3Only create empty dest files when they don't already exist.
* 2014-02-02v0.7.2Fix error reporting when Sass is not available.
* 2014-01-28v0.7.1Fix regression of Bundler support.
* 2014-01-26v0.7.0Improve Windows support.
* 2013-12-10v0.6.0Ignore files where filename have leading underscore.
* 2013-08-21v0.5.0Add banner option.
* 2013-07-06v0.4.1Use file.orig.src if file.src does not exist and return early to avoid passing non-existent files to sass binary.
* 2013-06-30v0.4.0Rewrite task to be able to support Source Maps. Compile Sass files in parallel for better performance.
* 2013-03-26v0.3.0Add support for `bundle exec`. Make sure `.css` files are compiled with SCSS.
* 2013-02-15v0.2.2First official release for Grunt 0.4.0.
* 2013-01-25v0.2.2rc7Updating grunt/gruntplugin dependencies to rc7. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
* 2013-01-09v0.2.2rc5Updating to work with grunt v0.4.0rc5. Switching to this.files api. Add separator option.
* 2012-11-05v0.2.0Grunt 0.4 compatibility. Improve error message when Sass binary couldn't be found
* 2012-10-12v0.1.3Rename grunt-contrib-lib dep to grunt-lib-contrib.
* 2012-10-08v0.1.2Fix regression for darwin.
* 2012-10-05v0.1.1Windows support.
* 2012-09-24v0.1.0Initial release.
---
Task submitted by [Sindre Sorhus](http://github.com/sindresorhus)
*This file was generated on Sun Aug 24 2014 16:51:41.*

79
node_modules/grunt-contrib-sass/docs/sass-examples.md generated vendored Executable file
View File

@ -0,0 +1,79 @@
# Examples
## Example config
```javascript
grunt.initConfig({
sass: { // Task
dist: { // Target
options: { // Target options
style: 'expanded'
},
files: { // Dictionary of files
'main.css': 'main.scss', // 'destination': 'source'
'widgets.css': 'widgets.scss'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['sass']);
```
## Compile
```javascript
grunt.initConfig({
sass: {
dist: {
files: {
'main.css': 'main.scss'
}
}
}
});
```
## Concat and compile
Instead of concatenating the files, just `@import` them into another `.sass` file eg. `main.scss`.
## Compile multiple files
You can specify multiple `destination: source` items in `files`.
```javascript
grunt.initConfig({
sass: {
dist: {
files: {
'main.css': 'main.scss',
'widgets.css': 'widgets.scss'
}
}
}
});
```
## Compile files in a directory
Instead of naming all files you want to compile, you can use the `expand` property allowing you to specify a directory. More information available in the [grunt docs](http://gruntjs.com/configuring-tasks) - `Building the files object dynamically`.
```javascript
grunt.initConfig({
sass: {
dist: {
files: [{
expand: true,
cwd: 'styles',
src: ['*.scss'],
dest: '../public',
ext: '.css'
}]
}
}
});
```

143
node_modules/grunt-contrib-sass/docs/sass-options.md generated vendored Executable file
View File

@ -0,0 +1,143 @@
# Options
## sourcemap
Type: `String`
Default: `auto`
Values:
- `auto` - relative paths where possible, file URIs elsewhere
- `file` - always absolute file URIs
- `inline` - include the source text in the sourcemap
- `none`- no sourcemaps
**Requires Sass 3.4.0, which can be installed with `gem install sass`**
## trace
Type: `Boolean`
Default: `false`
Show a full traceback on error.
## unixNewlines
Type: `Boolean`
Default: `false` on Windows, otherwise `true`
Force Unix newlines in written files.
## check
Type: `Boolean`
Default: `false`
Just check the Sass syntax, does not evaluate and write the output.
## style
Type: `String`
Default: `nested`
Output style. Can be `nested`, `compact`, `compressed`, `expanded`.
## precision
Type: `Number`
Default: `5`
How many digits of precision to use when outputting decimal numbers.
## quiet
Type: `Boolean`
Default: `false`
Silence warnings and status messages during compilation.
## compass
Type: `Boolean`
Default: `false`
Make Compass imports available and load project configuration (`config.rb` located close to the `Gruntfile.js`).
## debugInfo
Type: `Boolean`
Default: `false`
Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin.
## lineNumbers
Type: `Boolean`
Default: `false`
Emit comments in the generated CSS indicating the corresponding source line.
## loadPath
Type: `String|Array`
Add a (or multiple) Sass import path.
## require
Type: `String|Array`
Require a (or multiple) Ruby library before running Sass.
## cacheLocation
Type: `String`
Default: `.sass-cache`
The path to put cached Sass files.
## noCache
Type: `Boolean`
Default: `false`
Don't cache to sassc files.
## bundleExec
Type: `Boolean`
Default: `false`
Run `sass` with [bundle exec](http://gembundler.com/man/bundle-exec.1.html): `bundle exec sass`.
## banner
Type: `String`
Prepend the specified string to the output file. Useful for licensing information.
*Can't be used if you use the `sourcemap` option.*
## update
Type: `Boolean`
Default: `false`
Only compile changed files.

5
node_modules/grunt-contrib-sass/docs/sass-overview.md generated vendored Executable file
View File

@ -0,0 +1,5 @@
[Sass](http://sass-lang.com) is a preprocessor that adds nested rules, variables, mixins and functions, selector inheritance, and more to CSS. Sass files compile into well-formatted, standard CSS to use in your site or application.
This task requires you to have [Ruby](http://www.ruby-lang.org/en/downloads/) and [Sass](http://sass-lang.com/download.html) installed. If you're on OS X or Linux you probably already have Ruby installed; test with `ruby -v` in your terminal. When you've confirmed you have Ruby installed, run `gem install sass` to install Sass.
Note: Files that begin with "_" are ignored even if they match the globbing pattern. This is done to match the expected [Sass partial behaviour](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#partials).

1
node_modules/grunt-contrib-sass/node_modules/.bin/which generated vendored Symbolic link
View File

@ -0,0 +1 @@
../which/bin/which

View File

@ -0,0 +1 @@
../win-spawn/bin/win-spawn

View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- "0.10"

19
node_modules/grunt-contrib-sass/node_modules/async/LICENSE generated vendored Executable file
View File

@ -0,0 +1,19 @@
Copyright (c) 2010-2014 Caolan McMahon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1646
node_modules/grunt-contrib-sass/node_modules/async/README.md generated vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
{
"name": "async",
"repo": "caolan/async",
"description": "Higher-order functions and common patterns for asynchronous code",
"version": "0.1.23",
"keywords": [],
"dependencies": {},
"development": {},
"main": "lib/async.js",
"scripts": [ "lib/async.js" ]
}

1123
node_modules/grunt-contrib-sass/node_modules/async/lib/async.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
"main": "./lib/async",
"author": {
"name": "Caolan McMahon"
},
"version": "0.9.0",
"repository": {
"type": "git",
"url": "https://github.com/caolan/async.git"
},
"bugs": {
"url": "https://github.com/caolan/async/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/caolan/async/raw/master/LICENSE"
}
],
"devDependencies": {
"nodeunit": ">0.0.0",
"uglify-js": "1.2.x",
"nodelint": ">0.0.0"
},
"jam": {
"main": "lib/async.js",
"include": [
"lib/async.js",
"README.md",
"LICENSE"
]
},
"scripts": {
"test": "nodeunit test/test-async.js"
},
"homepage": "https://github.com/caolan/async",
"_id": "async@0.9.0",
"dist": {
"shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"tarball": "http://registry.npmjs.org/async/-/async-0.9.0.tgz"
},
"_from": "async@^0.9.0",
"_npmVersion": "1.4.3",
"_npmUser": {
"name": "caolan",
"email": "caolan.mcmahon@gmail.com"
},
"maintainers": [
{
"name": "caolan",
"email": "caolan@caolanmcmahon.com"
}
],
"directories": {},
"_shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7",
"_resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz",
"readme": "ERROR: No README data found!"
}

95
node_modules/grunt-contrib-sass/node_modules/chalk/index.js generated vendored Executable file
View File

@ -0,0 +1,95 @@
'use strict';
var escapeStringRegexp = require('escape-string-regexp');
var ansiStyles = require('ansi-styles');
var stripAnsi = require('strip-ansi');
var hasAnsi = require('has-ansi');
var supportsColor = require('supports-color');
var defineProps = Object.defineProperties;
var chalk = module.exports;
function build(_styles) {
var builder = function builder() {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
// __proto__ is used because we must return a function, but there is
// no way to create a function with a different prototype.
builder.__proto__ = proto;
return builder;
}
var styles = (function () {
var ret = {};
ansiStyles.grey = ansiStyles.gray;
Object.keys(ansiStyles).forEach(function (key) {
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
ret[key] = {
get: function () {
return build(this._styles.concat(key));
}
};
});
return ret;
})();
var proto = defineProps(function chalk() {}, styles);
function applyStyle() {
// support varags, but simply cast to string in case there's only one arg
var args = arguments;
var argsLen = args.length;
var str = argsLen !== 0 && String(arguments[0]);
if (argsLen > 1) {
// don't slice `arguments`, it prevents v8 optimizations
for (var a = 1; a < argsLen; a++) {
str += ' ' + args[a];
}
}
if (!chalk.enabled || !str) {
return str;
}
/*jshint validthis: true*/
var nestedStyles = this._styles;
for (var i = 0; i < nestedStyles.length; i++) {
var code = ansiStyles[nestedStyles[i]];
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
str = code.open + str.replace(code.closeRe, code.open) + code.close;
}
return str;
}
function init() {
var ret = {};
Object.keys(styles).forEach(function (name) {
ret[name] = {
get: function () {
return build([name]);
}
};
});
return ret;
}
defineProps(chalk, init());
chalk.styles = ansiStyles;
chalk.hasColor = hasAnsi;
chalk.stripColor = stripAnsi;
chalk.supportsColor = supportsColor;
// detect mode if not set manually
if (chalk.enabled === undefined) {
chalk.enabled = chalk.supportsColor;
}

View File

@ -0,0 +1 @@
../has-ansi/cli.js

View File

@ -0,0 +1 @@
../strip-ansi/cli.js

View File

@ -0,0 +1 @@
../supports-color/cli.js

View File

@ -0,0 +1,40 @@
'use strict';
var styles = module.exports;
var codes = {
reset: [0, 0],
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
gray: [90, 39],
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49]
};
Object.keys(codes).forEach(function (key) {
var val = codes[key];
var style = styles[key] = {};
style.open = '\u001b[' + val[0] + 'm';
style.close = '\u001b[' + val[1] + 'm';
});

View File

@ -0,0 +1,74 @@
{
"name": "ansi-styles",
"version": "1.1.0",
"description": "ANSI escape codes for styling strings in the terminal",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/ansi-styles"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/ansi-styles/issues"
},
"homepage": "https://github.com/sindresorhus/ansi-styles",
"_id": "ansi-styles@1.1.0",
"_shasum": "eaecbf66cd706882760b2f4691582b8f55d7a7de",
"_from": "ansi-styles@^1.1.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "eaecbf66cd706882760b2f4691582b8f55d7a7de",
"tarball": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,70 @@
# ansi-styles [![Build Status](https://travis-ci.org/sindresorhus/ansi-styles.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-styles)
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
You probably want the higher-level [chalk](https://github.com/sindresorhus/chalk) module for styling your strings.
![screenshot](screenshot.png)
## Install
```sh
$ npm install --save ansi-styles
```
## Usage
```js
var ansi = require('ansi-styles');
console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
```
## API
Each style has an `open` and `close` property.
## Styles
### General
- `reset`
- `bold`
- `dim`
- `italic` *(not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(not widely supported)*
### Text colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `gray`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,11 @@
'use strict';
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
module.exports = function (str) {
if (typeof str !== 'string') {
throw new TypeError('Expected a string');
}
return str.replace(matchOperatorsRe, '\\$&');
};

View File

@ -0,0 +1,69 @@
{
"name": "escape-string-regexp",
"version": "1.0.2",
"description": "Escape RegExp special characters",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/sindresorhus/escape-string-regexp"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js"
],
"keywords": [
"regex",
"regexp",
"re",
"regular",
"expression",
"escape",
"string",
"str",
"special",
"characters"
],
"devDependencies": {
"mocha": "*"
},
"gitHead": "0587ee0ee03ea3fcbfa3c15cf67b47f214e20987",
"bugs": {
"url": "https://github.com/sindresorhus/escape-string-regexp/issues"
},
"homepage": "https://github.com/sindresorhus/escape-string-regexp",
"_id": "escape-string-regexp@1.0.2",
"_shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
"_from": "escape-string-regexp@^1.0.0",
"_npmVersion": "1.4.23",
"_npmUser": {
"name": "jbnicolai",
"email": "jappelman@xebia.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
{
"name": "jbnicolai",
"email": "jappelman@xebia.com"
}
],
"dist": {
"shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
"tarball": "http://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,27 @@
# escape-string-regexp [![Build Status](https://travis-ci.org/sindresorhus/escape-string-regexp.svg?branch=master)](https://travis-ci.org/sindresorhus/escape-string-regexp)
> Escape RegExp special characters
## Install
```sh
$ npm install --save escape-string-regexp
```
## Usage
```js
var escapeStringRegexp = require('escape-string-regexp');
var escapedString = escapeStringRegexp('how much $ for a unicorn?');
//=> how much \$ for a unicorn\?
new RegExp(escapedString);
```
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,53 @@
#!/usr/bin/env node
'use strict';
var pkg = require('./package.json');
var hasAnsi = require('./');
var input = process.argv[2];
function stdin(cb) {
var ret = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', function (data) {
ret += data;
});
process.stdin.on('end', function () {
cb(ret);
});
}
function help() {
console.log([
pkg.description,
'',
'Usage',
' $ has-ansi <string>',
' $ echo <string> | has-ansi',
'',
'Exits with code 0 if input has ANSI escape codes and 1 if not'
].join('\n'));
}
function init(data) {
process.exit(hasAnsi(data) ? 0 : 1);
}
if (process.argv.indexOf('--help') !== -1) {
help();
return;
}
if (process.argv.indexOf('--version') !== -1) {
console.log(pkg.version);
return;
}
if (process.stdin.isTTY) {
if (!input) {
help();
return;
}
init(input);
} else {
stdin(init);
}

View File

@ -0,0 +1,4 @@
'use strict';
var ansiRegex = require('ansi-regex');
var re = new RegExp(ansiRegex().source); // remove the `g` flag
module.exports = re.test.bind(re);

View File

@ -0,0 +1,4 @@
'use strict';
module.exports = function () {
return /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;
};

View File

@ -0,0 +1,79 @@
{
"name": "ansi-regex",
"version": "0.2.1",
"description": "Regular expression for matching ANSI escape codes",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/ansi-regex"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/ansi-regex/issues"
},
"homepage": "https://github.com/sindresorhus/ansi-regex",
"_id": "ansi-regex@0.2.1",
"_shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
"_from": "ansi-regex@^0.2.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
"tarball": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,33 @@
# ansi-regex [![Build Status](https://travis-ci.org/sindresorhus/ansi-regex.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-regex)
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
$ npm install --save ansi-regex
```
## Usage
```js
var ansiRegex = require('ansi-regex');
ansiRegex().test('\u001b[4mcake\u001b[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
//=> ['\u001b[4m', '\u001b[0m']
```
*It's a function so you can create multiple instances. Regexes with the global flag will have the `.lastIndex` property changed for each call to methods on the instance. Therefore reusing the instance with multiple calls will not work as expected for `.test()`.*
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,85 @@
{
"name": "has-ansi",
"version": "0.1.0",
"description": "Check if a string has ANSI escape codes",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/has-ansi"
},
"bin": {
"has-ansi": "cli.js"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js",
"cli.js"
],
"keywords": [
"cli",
"bin",
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"string",
"tty",
"escape",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern",
"has"
],
"dependencies": {
"ansi-regex": "^0.2.0"
},
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/has-ansi/issues"
},
"homepage": "https://github.com/sindresorhus/has-ansi",
"_id": "has-ansi@0.1.0",
"_shasum": "84f265aae8c0e6a88a12d7022894b7568894c62e",
"_from": "has-ansi@^0.1.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "84f265aae8c0e6a88a12d7022894b7568894c62e",
"tarball": "http://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,45 @@
# has-ansi [![Build Status](https://travis-ci.org/sindresorhus/has-ansi.svg?branch=master)](https://travis-ci.org/sindresorhus/has-ansi)
> Check if a string has [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
$ npm install --save has-ansi
```
## Usage
```js
var hasAnsi = require('has-ansi');
hasAnsi('\u001b[4mcake\u001b[0m');
//=> true
hasAnsi('cake');
//=> false
```
## CLI
```sh
$ npm install --global has-ansi
```
```
$ has-ansi --help
Usage
$ has-ansi <string>
$ echo <string> | has-ansi
Exits with code 0 if input has ANSI escape codes and 1 if not
```
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,39 @@
#!/usr/bin/env node
'use strict';
var fs = require('fs');
var pkg = require('./package.json');
var strip = require('./');
var input = process.argv[2];
function help() {
console.log([
pkg.description,
'',
'Usage',
' $ strip-ansi <input-file> > <output-file>',
' $ cat <input-file> | strip-ansi > <output-file>',
'',
'Example',
' $ strip-ansi unicorn.txt > unicorn-stripped.txt'
].join('\n'));
}
if (process.argv.indexOf('--help') !== -1) {
help();
return;
}
if (process.argv.indexOf('--version') !== -1) {
console.log(pkg.version);
return;
}
if (input) {
process.stdout.write(strip(fs.readFileSync(input, 'utf8')));
return;
}
process.stdin.setEncoding('utf8');
process.stdin.on('data', function (data) {
process.stdout.write(strip(data));
});

View File

@ -0,0 +1,6 @@
'use strict';
var ansiRegex = require('ansi-regex')();
module.exports = function (str) {
return typeof str === 'string' ? str.replace(ansiRegex, '') : str;
};

View File

@ -0,0 +1,4 @@
'use strict';
module.exports = function () {
return /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;
};

View File

@ -0,0 +1,79 @@
{
"name": "ansi-regex",
"version": "0.2.1",
"description": "Regular expression for matching ANSI escape codes",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/ansi-regex"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/ansi-regex/issues"
},
"homepage": "https://github.com/sindresorhus/ansi-regex",
"_id": "ansi-regex@0.2.1",
"_shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
"_from": "ansi-regex@^0.2.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
"tarball": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,33 @@
# ansi-regex [![Build Status](https://travis-ci.org/sindresorhus/ansi-regex.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-regex)
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
$ npm install --save ansi-regex
```
## Usage
```js
var ansiRegex = require('ansi-regex');
ansiRegex().test('\u001b[4mcake\u001b[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
//=> ['\u001b[4m', '\u001b[0m']
```
*It's a function so you can create multiple instances. Regexes with the global flag will have the `.lastIndex` property changed for each call to methods on the instance. Therefore reusing the instance with multiple calls will not work as expected for `.test()`.*
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,84 @@
{
"name": "strip-ansi",
"version": "0.3.0",
"description": "Strip ANSI escape codes",
"license": "MIT",
"bin": {
"strip-ansi": "cli.js"
},
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/strip-ansi"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js",
"cli.js"
],
"keywords": [
"strip",
"trim",
"remove",
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"dependencies": {
"ansi-regex": "^0.2.1"
},
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/strip-ansi/issues"
},
"homepage": "https://github.com/sindresorhus/strip-ansi",
"_id": "strip-ansi@0.3.0",
"_shasum": "25f48ea22ca79187f3174a4db8759347bb126220",
"_from": "strip-ansi@^0.3.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "25f48ea22ca79187f3174a4db8759347bb126220",
"tarball": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,43 @@
# strip-ansi [![Build Status](https://travis-ci.org/sindresorhus/strip-ansi.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-ansi)
> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
$ npm install --save strip-ansi
```
## Usage
```js
var stripAnsi = require('strip-ansi');
stripAnsi('\x1b[4mcake\x1b[0m');
//=> 'cake'
```
## CLI
```sh
$ npm install --global strip-ansi
```
```sh
$ strip-ansi --help
Usage
$ strip-ansi <input-file> > <output-file>
$ cat <input-file> | strip-ansi > <output-file>
Example
$ strip-ansi unicorn.txt > unicorn-stripped.txt
```
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
'use strict';
var pkg = require('./package.json');
var supportsColor = require('./');
var input = process.argv[2];
function help() {
console.log([
pkg.description,
'',
'Usage',
' $ supports-color',
'',
'Exits with code 0 if color is supported and 1 if not'
].join('\n'));
}
if (!input || process.argv.indexOf('--help') !== -1) {
help();
return;
}
if (process.argv.indexOf('--version') !== -1) {
console.log(pkg.version);
return;
}
process.exit(supportsColor ? 0 : 1);

View File

@ -0,0 +1,32 @@
'use strict';
module.exports = (function () {
if (process.argv.indexOf('--no-color') !== -1) {
return false;
}
if (process.argv.indexOf('--color') !== -1) {
return true;
}
if (process.stdout && !process.stdout.isTTY) {
return false;
}
if (process.platform === 'win32') {
return true;
}
if ('COLORTERM' in process.env) {
return true;
}
if (process.env.TERM === 'dumb') {
return false;
}
if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
return true;
}
return false;
})();

View File

@ -0,0 +1,78 @@
{
"name": "supports-color",
"version": "0.2.0",
"description": "Detect whether a terminal supports color",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/supports-color"
},
"bin": {
"supports-color": "cli.js"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
},
"files": [
"index.js",
"cli.js"
],
"keywords": [
"cli",
"bin",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"ansi",
"styles",
"tty",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"support",
"supports",
"capability",
"detect"
],
"devDependencies": {
"mocha": "*"
},
"bugs": {
"url": "https://github.com/sindresorhus/supports-color/issues"
},
"homepage": "https://github.com/sindresorhus/supports-color",
"_id": "supports-color@0.2.0",
"_shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a",
"_from": "supports-color@^0.2.0",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a",
"tarball": "http://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@ -0,0 +1,44 @@
# supports-color [![Build Status](https://travis-ci.org/sindresorhus/supports-color.svg?branch=master)](https://travis-ci.org/sindresorhus/supports-color)
> Detect whether a terminal supports color
## Install
```sh
$ npm install --save supports-color
```
## Usage
```js
var supportsColor = require('supports-color');
if (supportsColor) {
console.log('Terminal supports color');
}
```
It obeys the `--color` and `--no-color` CLI flags.
## CLI
```sh
$ npm install --global supports-color
```
```sh
$ supports-color --help
Usage
$ supports-color
# Exits with code 0 if color is supported and 1 if not
```
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

View File

@ -0,0 +1,82 @@
{
"name": "chalk",
"version": "0.5.1",
"description": "Terminal string styling done right. Created because the `colors` module does some really horrible things.",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sindresorhus/chalk"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
{
"name": "jbnicolai",
"email": "jappelman@xebia.com"
}
],
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha",
"bench": "matcha benchmark.js"
},
"files": [
"index.js"
],
"keywords": [
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"ansi",
"styles",
"tty",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"dependencies": {
"ansi-styles": "^1.1.0",
"escape-string-regexp": "^1.0.0",
"has-ansi": "^0.1.0",
"strip-ansi": "^0.3.0",
"supports-color": "^0.2.0"
},
"devDependencies": {
"matcha": "^0.5.0",
"mocha": "*"
},
"gitHead": "994758f01293f1fdcf63282e9917cb9f2cfbdaac",
"bugs": {
"url": "https://github.com/sindresorhus/chalk/issues"
},
"homepage": "https://github.com/sindresorhus/chalk",
"_id": "chalk@0.5.1",
"_shasum": "663b3a648b68b55d04690d49167aa837858f2174",
"_from": "chalk@^0.5.1",
"_npmVersion": "1.4.14",
"_npmUser": {
"name": "jbnicolai",
"email": "jappelman@xebia.com"
},
"dist": {
"shasum": "663b3a648b68b55d04690d49167aa837858f2174",
"tarball": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
"readme": "ERROR: No README data found!"
}

175
node_modules/grunt-contrib-sass/node_modules/chalk/readme.md generated vendored Executable file
View File

@ -0,0 +1,175 @@
# <img width="300" src="https://cdn.rawgit.com/sindresorhus/chalk/77ae94f63ab1ac61389b190e5a59866569d1a376/logo.svg" alt="chalk">
> Terminal string styling done right
[![Build Status](https://travis-ci.org/sindresorhus/chalk.svg?branch=master)](https://travis-ci.org/sindresorhus/chalk)
![](http://img.shields.io/badge/unicorn-approved-ff69b4.svg)
[colors.js](https://github.com/Marak/colors.js) is currently the most popular string styling module, but it has serious deficiencies like extending String.prototype which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough.
**Chalk is a clean and focused alternative.**
![screenshot](https://github.com/sindresorhus/ansi-styles/raw/master/screenshot.png)
## Why
- Highly performant
- Doesn't extend String.prototype
- Expressive API
- Ability to nest styles
- Clean and focused
- Auto-detects color support
- Actively maintained
- [Used by 1000+ modules](https://npmjs.org/browse/depended/chalk)
## Install
```sh
$ npm install --save chalk
```
## Usage
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
```js
var chalk = require('chalk');
// style a string
console.log( chalk.blue('Hello world!') );
// combine styled and normal strings
console.log( chalk.blue('Hello'), 'World' + chalk.red('!') );
// compose multiple styles using the chainable API
console.log( chalk.blue.bgRed.bold('Hello world!') );
// pass in multiple arguments
console.log( chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz') );
// nest styles
console.log( chalk.red('Hello', chalk.underline.bgBlue('world') + '!') );
// nest styles of the same type even (color, underline, background)
console.log( chalk.green('I am a green line ' + chalk.blue('with a blue substring') + ' that becomes green again!') );
```
Easily define your own themes.
```js
var chalk = require('chalk');
var error = chalk.bold.red;
console.log(error('Error!'));
```
Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data).
```js
var name = 'Sindre';
console.log(chalk.green('Hello %s'), name);
//=> Hello Sindre
```
## API
### chalk.`<style>[.<style>...](string, [string...])`
Example: `chalk.red.bold.underline('Hello', 'world');`
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter.
Multiple arguments will be separated by space.
### chalk.enabled
Color support is automatically detected, but you can override it.
### chalk.supportsColor
Detect whether the terminal [supports color](https://github.com/sindresorhus/supports-color).
Can be overridden by the user with the flags `--color` and `--no-color`.
Used internally and handled for you, but exposed for convenience.
### chalk.styles
Exposes the styles as [ANSI escape codes](https://github.com/sindresorhus/ansi-styles).
Generally not useful, but you might need just the `.open` or `.close` escape code if you're mixing externally styled strings with yours.
```js
var chalk = require('chalk');
console.log(chalk.styles.red);
//=> {open: '\u001b[31m', close: '\u001b[39m'}
console.log(chalk.styles.red.open + 'Hello' + chalk.styles.red.close);
```
### chalk.hasColor(string)
Check whether a string [has color](https://github.com/sindresorhus/has-ansi).
### chalk.stripColor(string)
[Strip color](https://github.com/sindresorhus/strip-ansi) from a string.
Can be useful in combination with `.supportsColor` to strip color on externally styled text when it's not supported.
Example:
```js
var chalk = require('chalk');
var styledString = getText();
if (!chalk.supportsColor) {
styledString = chalk.stripColor(styledString);
}
```
## Styles
### General
- `reset`
- `bold`
- `dim`
- `italic` *(not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(not widely supported)*
### Text colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `gray`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

42
node_modules/grunt-contrib-sass/node_modules/dargs/index.js generated vendored Executable file
View File

@ -0,0 +1,42 @@
'use strict';
function createArg(key, val) {
key = key.replace(/[A-Z]/g, '-$&').toLowerCase();
return '--' + key + (val ? '=' + val : '');
};
module.exports = function (opts, excludes, includes) {
var args = [];
Object.keys(opts).forEach(function (key) {
var val = opts[key];
if (Array.isArray(excludes) && excludes.indexOf(key) !== -1) {
return;
}
if (Array.isArray(includes) && includes.indexOf(key) === -1) {
return;
}
if (val === true) {
args.push(createArg(key));
}
if (typeof val === 'string') {
args.push(createArg(key, val));
}
if (typeof val === 'number' && isNaN(val) === false) {
args.push(createArg(key, '' + val));
}
if (Array.isArray(val)) {
val.forEach(function (arrVal) {
args.push(createArg(key, arrVal));
});
}
});
return args;
};

View File

@ -0,0 +1,67 @@
{
"name": "dargs",
"version": "2.1.0",
"description": "Convert an object of options into an array of command-line arguments",
"repository": {
"type": "git",
"url": "https://github.com/sindresorhus/dargs"
},
"keywords": [
"options",
"arguments",
"args",
"flags",
"cli",
"nopt",
"minimist",
"bin",
"binary",
"command",
"cmd"
],
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
},
"scripts": {
"test": "mocha"
},
"devDependencies": {
"mocha": "*"
},
"engines": {
"node": ">=0.10.0"
},
"license": "MIT",
"files": [
"index.js"
],
"gitHead": "e1f3e8ae83fe011a2b9ceb9aa596e2e54751e5cd",
"bugs": {
"url": "https://github.com/sindresorhus/dargs/issues"
},
"homepage": "https://github.com/sindresorhus/dargs",
"_id": "dargs@2.1.0",
"_shasum": "46c27ffab1ffb1378ef212597213719fe602bc93",
"_from": "dargs@^2.0.0",
"_npmVersion": "2.1.4",
"_nodeVersion": "0.10.32",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
}
],
"dist": {
"shasum": "46c27ffab1ffb1378ef212597213719fe602bc93",
"tarball": "http://registry.npmjs.org/dargs/-/dargs-2.1.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/dargs/-/dargs-2.1.0.tgz",
"readme": "ERROR: No README data found!"
}

89
node_modules/grunt-contrib-sass/node_modules/dargs/readme.md generated vendored Executable file
View File

@ -0,0 +1,89 @@
# dargs [![Build Status](https://travis-ci.org/sindresorhus/dargs.svg?branch=master)](https://travis-ci.org/sindresorhus/dargs)
> Convert an object of options into an array of command-line arguments
Basically the inverse of an argument parser like minimist. Useful when spawning command-line tools.
## Install
```sh
$ npm install --save dargs
```
#### Usage
```js
var dargs = require('dargs');
var options = {
foo: 'bar',
hello: true, // results in only the key being used
cake: false, // ignored
camelCase: 5, // camelCase is slugged to `camel-case`
multiple: ['value', 'value2'], // converted to multiple arguments
sad: ':('
};
var excludes = ['sad'];
var includes = ['camelCase', 'multiple', 'sad'];
console.log(dargs(options, excludes));
/*
[
'--foo=bar',
'--hello',
'--camel-case=5',
'--multiple=value',
'--multiple=value2'
]
*/
console.log(dargs(options, excludes, includes));
/*
[
'--camel-case=5',
'--multiple=value',
'--multiple=value2'
]
*/
console.log(dargs(options, [], includes));
/*
[
'--camel-case=5',
'--multiple=value',
'--multiple=value2',
'--sad=:(''
]
*/
```
## API
### dargs(options, excludes, includes)
#### options
Type: `object`
Options to convert to command-line arguments.
#### excludes
Type: `array`
Keys to exclude.
Takes precedence over `includes`.
#### includes
Type: `array`
Keys to include.
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)

15
node_modules/grunt-contrib-sass/node_modules/which/LICENSE generated vendored Executable file
View File

@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@ -0,0 +1,5 @@
The "which" util from npm's guts.
Finds the first instance of a specified executable in the PATH
environment variable. Does not cache the results, so `hash -r` is not
needed when the PATH changes.

14
node_modules/grunt-contrib-sass/node_modules/which/bin/which generated vendored Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env node
var which = require("../")
if (process.argv.length < 3) {
console.error("Usage: which <thing>")
process.exit(1)
}
which(process.argv[2], function (er, thing) {
if (er) {
console.error(er.message)
process.exit(er.errno || 127)
}
console.log(thing)
})

View File

@ -0,0 +1,47 @@
{
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me"
},
"name": "which",
"description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
"version": "1.0.8",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-which.git"
},
"main": "which.js",
"bin": {
"which": "./bin/which"
},
"license": "ISC",
"gitHead": "681a9ebbc447cb428232ddf6c0983006d89e7755",
"bugs": {
"url": "https://github.com/isaacs/node-which/issues"
},
"homepage": "https://github.com/isaacs/node-which",
"_id": "which@1.0.8",
"scripts": {},
"_shasum": "c2ff319534ac4a1fa45df2221b56c36279903ded",
"_from": "which@^1.0.5",
"_npmVersion": "2.1.11",
"_nodeVersion": "0.10.16",
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
"maintainers": [
{
"name": "isaacs",
"email": "i@izs.me"
}
],
"dist": {
"shasum": "c2ff319534ac4a1fa45df2221b56c36279903ded",
"tarball": "http://registry.npmjs.org/which/-/which-1.0.8.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/which/-/which-1.0.8.tgz",
"readme": "ERROR: No README data found!"
}

99
node_modules/grunt-contrib-sass/node_modules/which/which.js generated vendored Executable file
View File

@ -0,0 +1,99 @@
module.exports = which
which.sync = whichSync
var path = require("path")
, fs
, COLON = process.platform === "win32" ? ";" : ":"
, isExe
, fs = require("fs")
if (process.platform == "win32") {
// On windows, there is no good way to check that a file is executable
isExe = function isExe () { return true }
} else {
isExe = function isExe (mod, uid, gid) {
//console.error(mod, uid, gid);
//console.error("isExe?", (mod & 0111).toString(8))
var ret = (mod & 0001)
|| (mod & 0010) && process.getgid && gid === process.getgid()
|| (mod & 0100) && process.getuid && uid === process.getuid()
//console.error("isExe?", ret)
return ret
}
}
function which (cmd, cb) {
if (isAbsolute(cmd)) return cb(null, cmd)
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
//console.error("pathEnv", pathEnv)
;(function F (i, l) {
if (i === l) return cb(new Error("not found: "+cmd))
var p = path.resolve(pathEnv[i], cmd)
;(function E (ii, ll) {
if (ii === ll) return F(i + 1, l)
var ext = pathExt[ii]
//console.error(p + ext)
fs.stat(p + ext, function (er, stat) {
if (!er &&
stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) {
//console.error("yes, exe!", p + ext)
return cb(null, p + ext)
}
return E(ii + 1, ll)
})
})(0, pathExt.length)
})(0, pathEnv.length)
}
function whichSync (cmd) {
if (isAbsolute(cmd)) return cmd
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
for (var i = 0, l = pathEnv.length; i < l; i ++) {
var p = path.join(pathEnv[i], cmd)
for (var j = 0, ll = pathExt.length; j < ll; j ++) {
var cur = p + pathExt[j]
var stat
try { stat = fs.statSync(cur) } catch (ex) {}
if (stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) return cur
}
}
throw new Error("not found: "+cmd)
}
var isAbsolute = process.platform === "win32" ? absWin : absUnix
function absWin (p) {
if (absUnix(p)) return true
// pull off the device/UNC bit from a windows path.
// from node's lib/path.js
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
, result = splitDeviceRe.exec(p)
, device = result[1] || ''
, isUnc = device && device.charAt(1) !== ':'
, isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
return isAbsolute
}
function absUnix (p) {
return p.charAt(0) === "/" || p === ""
}

View File

@ -0,0 +1,15 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
node_modules
npm-debug.log

View File

@ -0,0 +1,41 @@
# win-spawn
Spawn for node.js but in a way that works regardless of which OS you're using. Use this if you want to use spawn with a JavaScript file. It works by explicitly invoking node on windows. It also shims support for environment variable setting by attempting to parse the command with a regex. Since all modification is wrapped in `if (os === 'Windows_NT')` it can be safely used on non-windows systems and will not break anything.
## Installation
$ npm install win-spawn
## Usage
### Command Line
All the following will work exactly as if the 'win-spawn ' prefix was ommitted when on unix.
$ win-spawn foo
$ win-spawn ./bin/foo
$ win-spawn NODE_PATH=./lib foo
$ win-spawn NODE_PATH=./lib foo arg1 arg2
You can also transform all the line endings in a directory from `\r\n` to `\n` just by running:
$ win-line-endings
You can preview the changes by running:
$ win-line-endings -p
It will ignore `node_modules` and `.git` by default, but is not clever enough to recognise binary files yet.
### API
This will just pass through to `child_process.spawn` on unix systems, but will correctly parse the arguments on windows.
```javascript
spawn('foo', [], {stdio: 'inherit'});
spawn('./bin/foo', [], {stdio: 'inherit'});
spawn('NODE_PATH=./lib foo', [], {stdio: 'inherit'});
spawn('NODE_PATH=./lib foo', [arg1, arg2], {stdio: 'inherit'});
```
![viewcount](https://viewcount.jepso.com/count/ForbesLindesay/win-spawn.png)

View File

@ -0,0 +1,12 @@
#!/usr/bin/env node
var spawn = require('../index.js');
var args = process.argv.slice(2);
var cmd = '';
while (/^[A-Z_]+\=[^ \=]+$/.test(args[0])) {
cmd += args.shift() + ' ';
}
cmd += args.shift();
spawn(cmd, args, { stdio: 'inherit' });

View File

@ -0,0 +1,64 @@
var cSpawn = require('child_process').spawn;
var os = require('os').type();
exports = module.exports = spawn;
function spawn(command, args, options) {
if (os === 'Windows_NT') {
command = command.replace(/\//g, '\\');
if (command === 'rm') {
command = 'rmdir';
if (args[0] === '-rf' || args[0] == '-fr') {
args[0] = '/q';
args.unshift('/s');
}
if (args[0] === '-f') {
args[0] = '/q';
}
if (args[0] === '-r') {
args[0] = '/s';
}
}
args = args || [];
options = options || {};
var match, matchA;
if (matchA = /((?:[A-Z_]+\=[^ \=]+ )+)?([^\r\n]+)/.exec(command)) {
try {
var file = require('fs').readFileSync(matchA[2], 'utf8');
if (match = /\#\!\/usr\/bin\/env ([^\r\n]+)/.exec(file)) {
args.unshift(matchA[2]);
command = (matchA[1] || '') + match[1];
}
} catch (ex) { }
}
if (match = /((?:[A-Z_]+\=[^ \=]+ )+)([^\r\n]+)/.exec(command)) {
command = match[2];
options.env = options.env || shallowClone(process.env);
var env = match[1].split(' ');
env.forEach(function (v) {
v = v.split('=');
if (v.length === 2) {
options.env[v[0]] = v[1];
}
});
}
args.unshift(command);
args.unshift('/c');
args.unshift('/d');
command = 'cmd';
}
return cSpawn(command, args, options);
}
function shallowClone(obj) {
var out = {};
Object.keys(obj)
.forEach(function (key) {
out[key] = obj[key];
});
return out;
}

View File

@ -0,0 +1,33 @@
{
"name": "win-spawn",
"version": "2.0.0",
"description": "Spawn for node.js but in a way that works regardless of which OS you're using",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/ForbesLindesay/win-spawn.git"
},
"bin": {
"win-spawn": "./bin/win-spawn"
},
"devDependencies": {
"linify": "~1.0.1"
},
"scripts": {
"prepublish": "linify transform bin"
},
"author": {
"name": "ForbesLindesay"
},
"license": "BSD",
"readme": "# win-spawn\n\n Spawn for node.js but in a way that works regardless of which OS you're using. Use this if you want to use spawn with a JavaScript file. It works by explicitly invoking node on windows. It also shims support for environment variable setting by attempting to parse the command with a regex. Since all modification is wrapped in `if (os === 'Windows_NT')` it can be safely used on non-windows systems and will not break anything.\n\n## Installation\n\n $ npm install win-spawn\n\n## Usage\n\n### Command Line\n\n All the following will work exactly as if the 'win-spawn ' prefix was ommitted when on unix.\n\n $ win-spawn foo\n $ win-spawn ./bin/foo\n $ win-spawn NODE_PATH=./lib foo\n $ win-spawn NODE_PATH=./lib foo arg1 arg2\n\n You can also transform all the line endings in a directory from `\\r\\n` to `\\n` just by running:\n\n $ win-line-endings\n\n You can preview the changes by running:\n\n $ win-line-endings -p\n\n It will ignore `node_modules` and `.git` by default, but is not clever enough to recognise binary files yet.\n\n### API\n\nThis will just pass through to `child_process.spawn` on unix systems, but will correctly parse the arguments on windows.\n\n```javascript\nspawn('foo', [], {stdio: 'inherit'});\nspawn('./bin/foo', [], {stdio: 'inherit'});\nspawn('NODE_PATH=./lib foo', [], {stdio: 'inherit'});\nspawn('NODE_PATH=./lib foo', [arg1, arg2], {stdio: 'inherit'});\n```\n\n![viewcount](https://viewcount.jepso.com/count/ForbesLindesay/win-spawn.png)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/ForbesLindesay/win-spawn/issues"
},
"homepage": "https://github.com/ForbesLindesay/win-spawn",
"_id": "win-spawn@2.0.0",
"_shasum": "397a29130ec98d0aa0bc86baa4621393effd0b07",
"_from": "win-spawn@^2.0.0",
"_resolved": "https://registry.npmjs.org/win-spawn/-/win-spawn-2.0.0.tgz"
}

98
node_modules/grunt-contrib-sass/package.json generated vendored Executable file
View File

@ -0,0 +1,98 @@
{
"name": "grunt-contrib-sass",
"description": "Compile Sass to CSS",
"version": "0.8.1",
"homepage": "https://github.com/gruntjs/grunt-contrib-sass",
"author": {
"name": "Grunt Team",
"url": "http://gruntjs.com/"
},
"repository": {
"type": "git",
"url": "git://github.com/gruntjs/grunt-contrib-sass"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/gruntjs/grunt-contrib-sass/blob/master/LICENSE-MIT"
}
],
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
},
"dependencies": {
"async": "^0.9.0",
"chalk": "^0.5.1",
"dargs": "^2.0.0",
"which": "^1.0.5",
"win-spawn": "^2.0.0"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-internal": "^0.4.10",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-nodeunit": "^0.4.1"
},
"peerDependencies": {
"grunt": ">=0.4.0"
},
"keywords": [
"gruntplugin",
"scss",
"sass",
"css",
"compile",
"preprocessor",
"style"
],
"contributors": [
{
"name": "Sindre Sorhus",
"url": "http://github.com/sindresorhus"
}
],
"bugs": {
"url": "https://github.com/gruntjs/grunt-contrib-sass/issues"
},
"_id": "grunt-contrib-sass@0.8.1",
"_shasum": "8de924480dc12a51d35abe96a721682afc88d800",
"_from": "grunt-contrib-sass@",
"_npmVersion": "1.4.9",
"_npmUser": {
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
"maintainers": [
{
"name": "tkellen",
"email": "tyler@sleekcode.net"
},
{
"name": "cowboy",
"email": "cowboy@rj3.net"
},
{
"name": "sindresorhus",
"email": "sindresorhus@gmail.com"
},
{
"name": "shama",
"email": "kyle@dontkry.com"
},
{
"name": "jmeas",
"email": "jellyes2@gmail.com"
}
],
"dist": {
"shasum": "8de924480dc12a51d35abe96a721682afc88d800",
"tarball": "http://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-0.8.1.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-0.8.1.tgz",
"readme": "ERROR: No README data found!"
}

184
node_modules/grunt-contrib-sass/tasks/sass.js generated vendored Executable file
View File

@ -0,0 +1,184 @@
/*
* grunt-contrib-sass
* http://gruntjs.com/
*
* Copyright (c) 2013 Sindre Sorhus, contributors
* Licensed under the MIT license.
*/
'use strict';
var path = require('path');
var dargs = require('dargs');
var numCPUs = require('os').cpus().length || 1;
var async = require('async');
var chalk = require('chalk');
var spawn = require('win-spawn');
var which = require('which');
module.exports = function (grunt) {
var bannerCallback = function (filename, banner) {
grunt.verbose.writeln('Writing CSS banner for ' + filename);
grunt.file.write(filename, banner + grunt.util.linefeed + grunt.file.read(filename));
};
var checkBinary = function (cmd, errMess) {
try {
which.sync(cmd);
} catch (err) {
return grunt.warn(
'\n' + errMess + '\n' +
'More info: https://github.com/gruntjs/grunt-contrib-sass\n'
);
}
};
var checkFiles = function (files, options, cb) {
var failCount = 0;
var filesToCheck = files.filter(function (src) {
return path.basename(src)[0] !== '_' && grunt.file.exists(src);
});
async.eachLimit(filesToCheck, numCPUs, function (src, next) {
var bin;
var args;
if (options.bundleExec) {
bin = 'bundle';
args = ['exec', 'sass', '--check', src];
} else {
bin = 'sass';
args = ['--check', src];
}
grunt.verbose.writeln('Command: ' + bin + ' ' + args.join(' '));
grunt.verbose.writeln('Checking file ' + chalk.cyan(src) + ' syntax.');
spawn(bin, args, { stdio: 'inherit' })
.on('error', grunt.warn)
.on('close', function (code) {
if (code > 0) {
failCount++;
grunt.log.error('Checking file ' + chalk.cyan(src) + ' - ' + chalk.red('failed') + '.');
} else {
grunt.verbose.ok('Checking file ' + chalk.cyan(src) + ' - ' + chalk.green('passed') + '.');
}
next();
});
}, function () {
if (failCount > 0) {
grunt.warn('Sass check failed for ' + failCount + ' files.');
} else {
grunt.log.ok('All ' + chalk.cyan(filesToCheck.length) + ' files passed.');
}
cb();
});
};
grunt.registerMultiTask('sass', 'Compile Sass to CSS', function () {
var cb = this.async();
var options = this.options();
var bundleExec = options.bundleExec;
var banner;
var passedArgs;
if (bundleExec) {
checkBinary('bundle',
'bundleExec options set but no Bundler executable found in your PATH.'
);
} else {
checkBinary('sass',
'You need to have Ruby and Sass installed and in your PATH for this task to work.'
);
}
if (options.check) {
checkFiles(this.filesSrc, options, cb);
return;
}
// Unset banner option if set
if (options.banner) {
banner = options.banner;
delete options.banner;
}
passedArgs = dargs(options, ['bundleExec']);
async.eachLimit(this.files, numCPUs, function (file, next) {
var src = file.src[0];
if (typeof src !== 'string') {
src = file.orig.src[0];
}
if (!grunt.file.exists(src)) {
grunt.log.warn('Source file "' + src + '" not found.');
return next();
}
if (path.basename(src)[0] === '_') {
return next();
}
var args = [
src,
file.dest
].concat(passedArgs);
if (options.update) {
// When the source file hasn't yet been compiled SASS will write an empty file.
// If this is the first time the file has been written we treat it as a if update was not passed
if (!grunt.file.exists(file.dest)) {
// Find where the --update flag is and remove it.
var index = args.indexOf('--update');
args.splice(index, 1);
} else {
// The first two elements in args is our source and destination files,
// we use those values to build a path that SASS recognizes namely: source:destination
var sassPath = args.shift() + ':' + args.shift();
args.push(sassPath);
}
}
var bin = 'sass';
if (bundleExec) {
bin = 'bundle';
args.unshift('exec', 'sass');
}
// If we're compiling scss or css files
if (path.extname(src) === '.css') {
args.push('--scss');
}
// Make sure grunt creates the destination folders if they don't exist
if (!grunt.file.exists(file.dest)) {
grunt.file.write(file.dest, '');
}
grunt.verbose.writeln('Command: ' + bin + ' ' + args.join(' '));
var cp = spawn(bin, args, {stdio: 'inherit'});
cp.on('error', function (err) {
grunt.warn(err);
});
cp.on('close', function (code) {
if (code > 0) {
return grunt.warn('Exited with error code ' + code);
}
// Callback to insert banner
if (banner) {
bannerCallback(file.dest, banner);
}
grunt.verbose.writeln('File ' + chalk.cyan(file.dest) + ' created.');
next();
});
}, cb);
});
};

22
node_modules/grunt-contrib-watch/LICENSE-MIT generated vendored Executable file
View File

@ -0,0 +1,22 @@
Copyright (c) 2014 "Cowboy" Ben Alman, contributors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

486
node_modules/grunt-contrib-watch/README.md generated vendored Executable file
View File

@ -0,0 +1,486 @@
# grunt-contrib-watch v0.6.1 [![Build Status](https://travis-ci.org/gruntjs/grunt-contrib-watch.png?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-watch)
> Run predefined tasks whenever watched file patterns are added, changed or deleted.
## Getting Started
This plugin requires Grunt `~0.4.0`
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
```shell
npm install grunt-contrib-watch --save-dev
```
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
```js
grunt.loadNpmTasks('grunt-contrib-watch');
```
## Watch task
_Run this task with the `grunt watch` command._
### Settings
There are a number of options available. Please review the [minimatch options here](https://github.com/isaacs/minimatch#options). As well as some additional options as follows:
#### files
Type: `String|Array`
This defines what file patterns this task will watch. Can be a string or an array of files and/or minimatch patterns.
#### tasks
Type: `String|Array`
This defines which tasks to run when a watched file event occurs.
#### options.spawn
Type: `Boolean`
Default: true
Whether to spawn task runs in a child process. Setting this option to `false` speeds up the reaction time of the watch (usually 500ms faster for most) and allows subsequent task runs to share the same context. Not spawning task runs can make the watch more prone to failing so please use as needed.
Example:
```js
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
```
*For backwards compatibility the option `nospawn` is still available and will do the opposite of `spawn`.*
#### options.interrupt
Type: `Boolean`
Default: false
As files are modified this watch task will spawn tasks in child processes. The default behavior will only spawn a new child process per target when the previous process has finished. Set the `interrupt` option to true to terminate the previous process and spawn a new one upon later changes.
Example:
```js
watch: {
scripts: {
files: '**/*.js',
tasks: ['jshint'],
options: {
interrupt: true,
},
},
},
```
#### options.debounceDelay
Type: `Integer`
Default: 500
How long to wait before emitting events in succession for the same filepath and status. For example if your `Gruntfile.js` file was `changed`, a `changed` event will only fire again after the given milliseconds.
Example:
```js
watch: {
scripts: {
files: '**/*.js',
tasks: ['jshint'],
options: {
debounceDelay: 250,
},
},
},
```
#### options.interval
Type: `Integer`
Default: 100
The `interval` is passed to `fs.watchFile`. Since `interval` is only used by `fs.watchFile` and this watcher also uses `fs.watch`; it is recommended to ignore this option. *Default is 100ms*.
#### options.event
Type: `String|Array`
Default: `'all'`
Specify the type watch event that trigger the specified task. This option can be one or many of: `'all'`, `'changed'`, `'added'` and `'deleted'`.
Example:
```js
watch: {
scripts: {
files: '**/*.js',
tasks: ['generateFileManifest'],
options: {
event: ['added', 'deleted'],
},
},
},
```
#### options.reload
Type: `Boolean`
Default: `false`
By default, if `Gruntfile.js` is being watched, then changes to it will trigger the watch task to restart, and reload the `Gruntfile.js` changes.
When `reload` is set to `true`, changes to *any* of the watched files will trigger the watch task to restart.
This is especially useful if your `Gruntfile.js` is dependent on other files.
```js
watch: {
configFiles: {
files: [ 'Gruntfile.js', 'config/*.js' ],
options: {
reload: true
}
}
}
```
#### options.forever
Type: `Boolean`
Default: true
This is *only a task level option* and cannot be configured per target. By default the watch task will duck punch `grunt.fatal` and `grunt.warn` to try and prevent them from exiting the watch process. If you don't want `grunt.fatal` and `grunt.warn` to be overridden set the `forever` option to `false`.
#### options.dateFormat
Type: `Function`
This is *only a task level option* and cannot be configured per target. By default when the watch has finished running tasks it will display the message `Completed in 1.301s at Thu Jul 18 2013 14:58:21 GMT-0700 (PDT) - Waiting...`. You can override this message by supplying your own function:
```js
watch: {
options: {
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
grunt.log.writeln('Waiting for more changes...');
},
},
scripts: {
files: '**/*.js',
tasks: 'jshint',
},
},
```
#### options.atBegin
Type: `Boolean`
Default: false
This option will trigger the run of each specified task at startup of the watcher.
#### options.livereload
Type: `Boolean|Number|Object`
Default: false
Set to `true` or set `livereload: 1337` to a port number to enable live reloading. Default and recommended port is `35729`.
If enabled a live reload server will be started with the watch task per target. Then after the indicated tasks have ran, the live reload server will be triggered with the modified files.
Example:
```js
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: true,
},
},
},
```
It's possible to get livereload working over https connections. To do this, pass an object to `livereload` with a `key` and `cert` paths specified.
Example:
```js
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: {
port: 9000,
key: grunt.file.read('path/to/ssl.key'),
cert: grunt.file.read('path/to/ssl.crt')
// you can pass in any other options you'd like to the https server, as listed here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
}
},
},
},
```
#### options.cwd
Type: `String|Object`
Default: `process.cwd()`
Ability to set the current working directory. Defaults to `process.cwd()`. Can either be a string to set the cwd to match files and spawn tasks. Or an object to set each independently. Such as `options: { cwd: { files: 'match/files/from/here', spawn: 'but/spawn/files/from/here' } }`.
#### options.livereloadOnError
Type: `Boolean`
Default: `true`
Option to prevent the livereload if the executed tasks encountered an error. If set to `false`, the livereload will only be triggered if all tasks completed successfully.
### Examples
```js
// Simple config to run jshint any time a file is added, changed or deleted
grunt.initConfig({
watch: {
files: ['**/*'],
tasks: ['jshint'],
},
});
```
```js
// Advanced config. Run specific tasks when specific files are added, changed or deleted.
grunt.initConfig({
watch: {
gruntfile: {
files: 'Gruntfile.js',
tasks: ['jshint:gruntfile'],
},
src: {
files: ['lib/*.js', 'css/**/*.scss', '!lib/dontwatch.js'],
tasks: ['default'],
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit'],
},
},
});
```
#### Using the `watch` event
This task will emit a `watch` event when watched files are modified. This is useful if you would like a simple notification when files are edited or if you're using this task in tandem with another task. Here is a simple example using the `watch` event:
```js
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
},
},
});
grunt.event.on('watch', function(action, filepath, target) {
grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});
```
**The `watch` event is not intended for replacing the standard Grunt API for configuring and running tasks. If you're trying to run tasks from within the `watch` event you're more than likely doing it wrong. Please read [configuring tasks](http://gruntjs.com/configuring-tasks).**
##### Compiling Files As Needed
A very common request is to only compile files as needed. Here is an example that will only lint changed files with the `jshint` task:
```js
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
jshint: {
all: {
src: ['lib/*.js'],
},
},
});
// on watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
grunt.config('jshint.all.src', filepath);
});
```
If you need to dynamically modify your config, the `spawn` option must be disabled to keep the watch running under the same context.
If you save multiple files simultaneously you may opt for a more robust method:
```js
var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
grunt.config('jshint.all.src', Object.keys(changedFiles));
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});
```
#### Live Reloading
Live reloading is built into the watch task. Set the option `livereload` to `true` to enable on the default port `35729` or set to a custom port: `livereload: 1337`.
The simplest way to add live reloading to all your watch targets is by setting `livereload` to `true` at the task level. This will run a single live reload server and trigger the live reload for all your watch targets:
```js
grunt.initConfig({
watch: {
options: {
livereload: true,
},
css: {
files: ['public/scss/*.scss'],
tasks: ['compass'],
},
},
});
```
You can also configure live reload for individual watch targets or run multiple live reload servers. Just be sure if you're starting multiple servers they operate on different ports:
```js
grunt.initConfig({
watch: {
css: {
files: ['public/scss/*.scss'],
tasks: ['compass'],
options: {
// Start a live reload server on the default port 35729
livereload: true,
},
},
another: {
files: ['lib/*.js'],
tasks: ['anothertask'],
options: {
// Start another live reload server on port 1337
livereload: 1337,
},
},
dont: {
files: ['other/stuff/*'],
tasks: ['dostuff'],
},
},
});
```
##### Enabling Live Reload in Your HTML
Once you've started a live reload server you'll be able to access the live reload script. To enable live reload on your page, add a script tag before your closing `</body>` tag pointing to the `livereload.js` script:
```html
<script src="//localhost:35729/livereload.js"></script>
```
Feel free to add this script to your template situation and toggle with some sort of `dev` flag.
##### Using Live Reload with the Browser Extension
Instead of adding a script tag to your page, you can live reload your page by installing a browser extension. Please visit [how do I install and use the browser extensions](http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions-) for help installing an extension for your browser.
Once installed please use the default live reload port `35729` and the browser extension will automatically reload your page without needing the `<script>` tag.
##### Using Connect Middleware
Since live reloading is used when developing, you may want to disable building for production (and are not using the browser extension). One method is to use Connect middleware to inject the script tag into your page. Try the [connect-livereload](https://github.com/intesso/connect-livereload) middleware for injecting the live reload script into your page.
##### Rolling Your Own Live Reload
Live reloading is made easy by the library [tiny-lr](https://github.com/mklabs/tiny-lr). It is encouraged to read the documentation for `tiny-lr`. If you would like to trigger the live reload server yourself, simply POST files to the URL: `http://localhost:35729/changed`. Or if you rather roll your own live reload implementation use the following example:
```js
// Create a live reload server instance
var lrserver = require('tiny-lr')();
// Listen on port 35729
lrserver.listen(35729, function(err) { console.log('LR Server Started'); });
// Then later trigger files or POST to localhost:35729/changed
lrserver.changed({body:{files:['public/css/changed.css']}});
```
##### Live Reload with Preprocessors
Any time a watched file is edited with the `livereload` option enabled, the file will be sent to the live reload server. Some edited files you may desire to have sent to the live reload server, such as when preprocessing (`sass`, `less`, `coffeescript`, etc). As any file not recognized will reload the entire page as opposed to just the `css` or `javascript`.
The solution is to point a `livereload` watch target to your destination files:
```js
grunt.initConfig({
sass: {
dev: {
src: ['src/sass/*.sass'],
dest: 'dest/css/index.css',
},
},
watch: {
sass: {
// We watch and compile sass files as normal but don't live reload here
files: ['src/sass/*.sass'],
tasks: ['sass'],
},
livereload: {
// Here we watch the files the sass task will compile to
// These files are sent to the live reload server after sass compiles to them
options: { livereload: true },
files: ['dest/**/*'],
},
},
});
```
### FAQs
#### How do I fix the error `EMFILE: Too many opened files.`?
This is because of your system's max opened file limit. For OSX the default is very low (256). Temporarily increase your limit with `ulimit -n 10480`, the number being the new max limit.
In some versions of OSX the above solution doesn't work. In that case try `launchctl limit maxfiles 10480 10480 ` and restart your terminal. See [here](http://superuser.com/questions/261023/how-to-change-default-ulimit-values-in-mac-os-x-10-6).
#### Can I use this with Grunt v0.3?
`grunt-contrib-watch@0.1.x` is compatible with Grunt v0.3 but it is highly recommended to upgrade Grunt instead.
#### Why is the watch devouring all my memory/cpu?
Likely because of an enthusiastic pattern trying to watch thousands of files. Such as `'**/*.js'` but forgetting to exclude the `node_modules` folder with `'!**/node_modules/**'`. Try grouping your files within a subfolder or be more explicit with your file matching pattern.
Another reason if you're watching a large number of files could be the low default `interval`. Try increasing with `options: { interval: 5007 }`. Please see issues [#35](https://github.com/gruntjs/grunt-contrib-watch/issues/145) and [#145](https://github.com/gruntjs/grunt-contrib-watch/issues/145) for more information.
#### Why spawn as child processes as a default?
The goal of this watch task is as files are changed, run tasks as if they were triggered by the user themself. Each time a user runs `grunt` a process is spawned and tasks are ran in succession. In an effort to keep the experience consistent and continually produce expected results, this watch task spawns tasks as child processes by default.
Sandboxing task runs also allows this watch task to run more stable over long periods of time. As well as more efficiently with more complex tasks and file structures.
Spawning does cause a performance hit (usually 500ms for most environments). It also cripples tasks that rely on the watch task to share the context with each subsequent run (i.e., reload tasks). If you would like a faster watch task or need to share the context please set the `spawn` option to `false`. Just be aware that with this option enabled, the watch task is more prone to failure.
## Release History
* 2014-03-19v0.6.1Fix for watch targets named "default"
* 2014-03-11v0.6.0Clear changed files after triggering live reload to ensure they're only triggered once. cwd option now accepts separate settings for files and spawn. Fix to make interrupt work more than once. Enable live reload over HTTPS. Print newline after initial 'Waiting...' Remove deprecated grunt.util libs Add reload option to specify files other than Gruntfile files to reload. Update to gaze@0.5.1 Use fork of tiny-lr (which has quiter operation, support for HTTPS and windows path fixes) Add livereloadOnError, which if set to false will not trigger live reload if there is an error.
* 2013-08-25v0.5.3Fixed for live reload missing files.
* 2013-08-16v0.5.2Fixed issue running tasks after gruntfile is reloaded. Ignores empty file paths.
* 2013-07-20v0.5.1Fixed issue with options resetting.
* 2013-07-18v0.5.0Added target name to watch event. Added atBegin option to run tasks when watcher starts. Changed nospawn option to spawn (nospawn still available for backwards compatibility). Moved libs/vars into top scope to prevent re-init. Bumped Gaze version to ~0.4. Re-grab task/target options upon each task run. Add dateFormat option to override the date/time output upon completion.
* 2013-05-27v0.4.4Remove gracefully closing SIGINT. Not needed and causes problems for Windows. Ensure tasks are an array to not conflict with cliArgs.
* 2013-05-11v0.4.3Only group changed files per target to send correct files to live reload.
* 2013-05-09v0.4.2Fix for closing watchers.
* 2013-05-09v0.4.1Removed "beep" notification. Tasks now optional with livereload option. Reverted "run again" with interrupt off to fix infinite recursion issue. Watchers now close more properly on task run.
* 2013-05-03v0.4.0Option livereload to start live reload servers. Will reload a Gruntfile before running tasks if Gruntfile is modified. Option event to only trigger watch on certain events. Refactor watch task into separate task runs per target. Option forever to override grunt.fatal/warn to help keeping the watch alive with nospawn enabled. Emit a beep upon complete. Logs all watched files with verbose flag set. If interrupt is off, will run the tasks once more if watch triggered during a previous task run. tasks property is optional for use with watch event. Watchers properly closed when exiting.
* 2013-02-28v0.3.1Fix for top level options.
* 2013-02-27v0.3.0nospawn option added to run tasks without spawning as child processes. Watch emits 'watch' events upon files being triggered with grunt.event. Completion time in seconds and date/time shown after tasks ran. Negate file patterns fixed. Tasks debounced individually to handle simultaneous triggering for multiple targets. Errors handled better and viewable with --stack cli option. Code complexity reduced making the watch task code easier to read.
* 2013-02-15v0.2.0First official release for Grunt 0.4.0.
* 2013-01-18v0.2.0rc7Updating grunt/gruntplugin dependencies to rc6. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
* 2013-01-09v0.2.0rc5Updating to work with grunt v0.4.0rc5.
* 2012-12-15v0.2.0aConversion to grunt v0.4 conventions. Remove node v0.6 and grunt v0.3 support. Allow watch task to be renamed. Use grunt.util.spawn "grunt" option. Updated to gaze@0.3.0, forceWatchMethod option removed.
* 2012-11-01v0.1.4Prevent watch from spawning duplicate watch tasks
* 2012-10-28v0.1.3Better method to spawn the grunt bin Bump gaze to v0.2.0. Better handles some events and new option forceWatchMethod Only support Node.js >= v0.8
* 2012-10-17v0.1.2Only spawn a process per task one at a time Add interrupt option to cancel previous spawned process Grunt v0.3 compatibility changes
* 2012-10-16v0.1.1Fallback to global grunt bin if local doesnt exist. Fatal if bin cannot be found Update to gaze 0.1.6
* 2012-10-08v0.1.0Release watch task Remove spawn from helper Run on Grunt v0.4
---
Task submitted by [Kyle Robinson Young](http://dontkry.com)
*This file was generated on Wed Mar 19 2014 13:09:11.*

Some files were not shown because too many files have changed in this diff Show More