<commit_before>export configureUrlQuery from './configureUrlQuery';

export * as Serialize, { encode, decode } from './serialize';
export {
  replaceInUrlQuery,
  replaceUrlQuery,
  pushInUrlQuery,
  pushUrlQuery,
  multiReplaceInUrlQuery,
  multiPushInUrlQuery,
} from './updateUrlQuery';
export UrlQueryParamTypes from './UrlQueryParamTypes';
export UrlUpdateTypes from './UrlUpdateTypes';

/** React */
export addUrlProps from './react/addUrlProps';
export RouterToUrlQuery from './react/RouterToUrlQuery';

/** Redux */
export {
  replaceInUrlQueryFromAction,
  replaceUrlQueryFromAction,
  pushInUrlQueryFromAction,
  pushUrlQueryFromAction,
} from './redux/updateUrlQueryFromAction';
export urlAction, {
  urlReplaceAction,
  urlPushAction,
  urlReplaceInAction,
  urlPushInAction,
} from './redux/urlAction';
export urlQueryMiddleware from './redux/urlQueryMiddleware';
export urlQueryReducer from './redux/urlQueryReducer';

/** Utils */
export subquery from './utils/subquery';
export subqueryOmit from './utils/subqueryOmit';
<commit_msg>Exporting urlQueryDecoder<commit_after>export configureUrlQuery from './configureUrlQuery';

export * as Serialize, { encode, decode } from './serialize';
export {
  replaceInUrlQuery,
  replaceUrlQuery,
  pushInUrlQuery,
  pushUrlQuery,
  multiReplaceInUrlQuery,
  multiPushInUrlQuery,
} from './updateUrlQuery';
export urlQueryDecoder from './urlQueryDecoder';
export UrlQueryParamTypes from './UrlQueryParamTypes';
export UrlUpdateTypes from './UrlUpdateTypes';

/** React */
export addUrlProps from './react/addUrlProps';
export RouterToUrlQuery from './react/RouterToUrlQuery';

/** Redux */
export {
  replaceInUrlQueryFromAction,
  replaceUrlQueryFromAction,
  pushInUrlQueryFromAction,
  pushUrlQueryFromAction,
} from './redux/updateUrlQueryFromAction';
export urlAction, {
  urlReplaceAction,
  urlPushAction,
  urlReplaceInAction,
  urlPushInAction,
} from './redux/urlAction';
export urlQueryMiddleware from './redux/urlQueryMiddleware';
export urlQueryReducer from './redux/urlQueryReducer';

/** Utils */
export subquery from './utils/subquery';
export subqueryOmit from './utils/subqueryOmit';
<|endoftext|>


<commit_before>// ┌─────────────┐
// │ Gruntfile   │
// └─────────────┘
// Grunt wraps several tasks to ease development

// Javascript banner
var banner = '/* <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
				'*  <%= pkg.homepage %>\n' +
				'*  Copyright (c) <%= grunt.template.today("yyyy") %> Environmental Systems Research Institute, Inc.\n' +
				'*  Apache 2.0 License */\n';

module.exports = function (grunt) {
	require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
	// Project configuration.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		// Build CSS from SASS
		'sass': {
			options: {
				includePaths: ['./node_modules/bootstrap-sass/assets/stylesheets',
												'./node_modules/calcite-bootstrap/dist/sass']
			},
			expanded: {
				files: {
					'dist/css/calcite-bootstrap-v0.2.css': 'lib/sass/build-calcite-bootstrap.scss',
					'dist/css/calcite-maps-v0.2.css': 'lib/sass/build-calcite-maps.scss',
					'dist/css/calcite-bootstrap-maps-v0.2.css': 'lib/sass/build-all.scss',
					'dist/css/layouts/inline-zoom-v0.2.css': 'lib/sass/layouts/inline-zoom.scss',
					'dist/css/layouts/large-title-v0.2.css': 'lib/sass/layouts/large-title.scss',
					'dist/css/layouts/medium-title-v0.2.css': 'lib/sass/layouts/medium-title.scss',
					'dist/css/support/arcgis-3.x-v0.2.css': 'lib/sass/support/arcgis-3.x.scss',
					'dist/css/support/arcgis-4.x-v0.2.css': 'lib/sass/support/arcgis-4.x.scss',
					'dist/css/support/esri-leaflet-v0.2.css': 'lib/sass/support/esri-leaflet.scss'
				}
			}
		},

		// Minify CSS
		cssmin: {
			target: {
				options: {
					banner: banner
				},
				files: {
					'dist/css/calcite-maps.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css'],
					'dist/css/calcite-bootstrap.min-v0.2.css': ['dist/css/calcite-bootstrap-v0.2.css'],
					'dist/css/calcite-bootstrap-maps.min-v0.2.css': ['dist/css/calcite-bootstrap-maps-v0.2.css'],
					'dist/css/calcite-maps-arcgis-3.x.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css', 'dist/css/support/arcgis-3.x-v0.2.css'],
					'dist/css/calcite-maps-arcgis-4.x.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css','dist/css/support/arcgis-4.x-v0.2.css'],
					'dist/css/calcite-maps-esri-leaflet.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css','dist/css/support/esri-leaflet-v0.2.css']
				}
			}
		},

		// Uglify JS
		'uglify': {
			options: {
					mangle: false,
					banner: banner
			},
			dist: {
				files: {
					'dist/js/dojo/calcitemaps-v0.2.js': ['lib/js/dojo/calcitemaps.js'],
					'dist/js/jquery/calcitemaps-v0.2.js': ['lib/js/jquery/calcitemaps.js']
				}
			}
		},

		// Copy to dist
		'copy': {
			bootstrapfonts: {
				expand: true,
				flatten: true,
				src: ['./node_modules/bootstrap-sass/assets/fonts/bootstrap/*'],
				dest: './dist/fonts/bootstrap/'
			},
			calcitefonts: {
				expand: true,
				flatten: true,
				src: ['./lib/fonts/calcite/*'],
				dest: './dist/fonts/calcite/'
			},
			vendor: {
				expand: true,
				flatten: false,
				cwd: './bower_components/dojo-bootstrap',
				src: '**',
				dest: './dist/vendor/dojo-bootstrap/'
			}
		},

		// Deploy doc site to gh-pages
    // 'gh-pages': {
    //   options: {
    //     base: 'docs/build',
    //     repo: 'https://github.com/Esri/calcite-maps.git'
    //   },
    //   src: ['**']
    // }

	});
	// Default task.
	grunt.registerTask('default', ['sass', 'cssmin', 'uglify', 'copy:bootstrapfonts', 'copy:calcitefonts', 'copy:vendor']);
};<commit_msg>Don't uglify<commit_after>// ┌─────────────┐
// │ Gruntfile   │
// └─────────────┘
// Grunt wraps several tasks to ease development

// Javascript banner
var banner = '/* <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
				'*  <%= pkg.homepage %>\n' +
				'*  Copyright (c) <%= grunt.template.today("yyyy") %> Environmental Systems Research Institute, Inc.\n' +
				'*  Apache 2.0 License */\n';

module.exports = function (grunt) {
	require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
	// Project configuration.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		// Build CSS from SASS
		'sass': {
			options: {
				includePaths: ['./node_modules/bootstrap-sass/assets/stylesheets',
												'./node_modules/calcite-bootstrap/dist/sass']
			},
			expanded: {
				files: {
					'dist/css/calcite-bootstrap-v0.2.css': 'lib/sass/build-calcite-bootstrap.scss',
					'dist/css/calcite-maps-v0.2.css': 'lib/sass/build-calcite-maps.scss',
					'dist/css/calcite-bootstrap-maps-v0.2.css': 'lib/sass/build-all.scss',
					'dist/css/layouts/inline-zoom-v0.2.css': 'lib/sass/layouts/inline-zoom.scss',
					'dist/css/layouts/large-title-v0.2.css': 'lib/sass/layouts/large-title.scss',
					'dist/css/layouts/medium-title-v0.2.css': 'lib/sass/layouts/medium-title.scss',
					'dist/css/support/arcgis-3.x-v0.2.css': 'lib/sass/support/arcgis-3.x.scss',
					'dist/css/support/arcgis-4.x-v0.2.css': 'lib/sass/support/arcgis-4.x.scss',
					'dist/css/support/esri-leaflet-v0.2.css': 'lib/sass/support/esri-leaflet.scss'
				}
			}
		},

		// Minify CSS
		cssmin: {
			target: {
				options: {
					banner: banner
				},
				files: {
					'dist/css/calcite-maps.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css'],
					'dist/css/calcite-bootstrap.min-v0.2.css': ['dist/css/calcite-bootstrap-v0.2.css'],
					'dist/css/calcite-bootstrap-maps.min-v0.2.css': ['dist/css/calcite-bootstrap-maps-v0.2.css'],
					'dist/css/calcite-maps-arcgis-3.x.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css', 'dist/css/support/arcgis-3.x-v0.2.css'],
					'dist/css/calcite-maps-arcgis-4.x.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css','dist/css/support/arcgis-4.x-v0.2.css'],
					'dist/css/calcite-maps-esri-leaflet.min-v0.2.css': ['dist/css/calcite-maps-v0.2.css', 'dist/css/layouts/inline-zoom-v0.2.css', 'dist/css/layouts/large-title-v0.2.css', 'dist/css/layouts/medium-title-v0.2.css','dist/css/support/esri-leaflet-v0.2.css']
				}
			}
		},

		// Uglify JS (optional)
		// 'uglify': {
		// 	options: {
		// 			mangle: false,
		// 			banner: banner
		// 	},
		// 	dist: {
		// 		files: {
		// 			'dist/js/dojo/calcitemaps-v0.2.js': ['lib/js/dojo/calcitemaps.js'],
		// 			'dist/js/jquery/calcitemaps-v0.2.js': ['lib/js/jquery/calcitemaps.js']
		// 		}
		// 	}
		// },

		// Copy to dist
		'copy': {
			calcitemapsdojo: {
				expand: true,
				flatten: true,
				src: ['./lib/js/dojo/*.js'],
				dest:	'./dist/js/dojo/',
				rename: function(dest, src) {
          return dest + '/' + src.replace(/calcitemaps/, "calcitemaps-v0.2");
    		},
			},
			calcitemapsjquery: {
				expand: true,
				flatten: true,
				src: ['./lib/js/jquery/*.js'],
				dest:	'./dist/js/jquery/',
				rename: function(dest, src) {
          return dest + '/' + src.replace(/calcitemaps/, "calcitemaps-v0.2");
    		},
			},
			bootstrapfonts: {
				expand: true,
				flatten: true,
				src: ['./node_modules/bootstrap-sass/assets/fonts/bootstrap/*'],
				dest: './dist/fonts/bootstrap/'
			},
			calcitefonts: {
				expand: true,
				flatten: true,
				src: ['./lib/fonts/calcite/*'],
				dest: './dist/fonts/calcite/'
			},
			vendor: {
				expand: true,
				flatten: false,
				//cwd: './bower_components/dojo-bootstrap',
				cwd: './lib/js/dojo-bootstrap', // Get local build now
				src: '**',
				dest: './dist/vendor/dojo-bootstrap/'
			}
		},

		// Deploy doc site to gh-pages
    // 'gh-pages': {
    //   options: {
    //     base: 'docs/build',
    //     repo: 'https://github.com/Esri/calcite-maps.git'
    //   },
    //   src: ['**']
    // }

	});
	// Default task.
	grunt.registerTask('default', ['sass', 'cssmin', 'copy:calcitemapsdojo', 'copy:calcitemapsjquery', 'copy:bootstrapfonts', 'copy:calcitefonts', 'copy:vendor']);
};<|endoftext|>


<commit_before>'use strict';

const validateOpts = (opts, chunkMultiple) => {
	opts = Object.assign({}, { chunkSize: 10000 }, opts);

	opts.chunkSize = Math.ceil(opts.chunkSize / chunkMultiple) * chunkMultiple;

	if (opts.chunkSize === 0) {
		throw new Error('opts.chunkSize must be larger than 0');
	}

	return opts;
};

const b64 = (input, opts) => {
	if (input instanceof Buffer || typeof input === 'string') {
		const method = input instanceof Buffer ? 'encode' : 'decode';
		return b64[method](input, opts);
	}

	return Promise.reject(new TypeError('input must be a buffer or string'));
};

b64.encode = (input, opts) => new Promise(resolve => {
	const chunkMultiple = 3;
	opts = validateOpts(opts, chunkMultiple);

	if (!(input instanceof Buffer)) {
		throw new TypeError('input must be a buffer');
	}

	const bufferLength = input.length;
	let currentIndex = 0;
	let output = '';

	setImmediate(function encodeChunk() {
		const chunk = input.slice(currentIndex, currentIndex + opts.chunkSize);
		output += chunk.toString('base64');
		currentIndex += opts.chunkSize;
		if (currentIndex < bufferLength) {
			setImmediate(encodeChunk);
		} else {
			resolve(output);
		}
	});
});

b64.decode = (input, opts) => new Promise(resolve => {
	const chunkMultiple = 4;
	opts = validateOpts(opts, chunkMultiple);

	if (typeof input !== 'string') {
		throw new TypeError('input must be a base64 string');
	}

	const stringLength = input.length;
	let currentIndex = 0;
	let output = Buffer.alloc(0);

	setImmediate(function encodeChunk() {
		const chunk = input.slice(currentIndex, currentIndex + opts.chunkSize);
		output = Buffer.concat([output, Buffer.from(chunk, 'base64')]);
		currentIndex += opts.chunkSize;
		if (currentIndex < stringLength) {
			setImmediate(encodeChunk);
		} else {
			resolve(output);
		}
	});
});

module.exports = b64;
<commit_msg>Concat binary data to sting in decode loop The decode binary string after decoding b64. It blocks slightly at the end, but the performance increase from not creating extra buffers in the loop is massive (around 100x faster).<commit_after>'use strict';

const validateOpts = (opts, chunkMultiple) => {
	opts = Object.assign({}, { chunkSize: 10000 }, opts);

	opts.chunkSize = Math.ceil(opts.chunkSize / chunkMultiple) * chunkMultiple;

	if (opts.chunkSize === 0) {
		throw new Error('opts.chunkSize must be larger than 0');
	}

	return opts;
};

const b64 = (input, opts) => {
	if (input instanceof Buffer || typeof input === 'string') {
		const method = input instanceof Buffer ? 'encode' : 'decode';
		return b64[method](input, opts);
	}

	return Promise.reject(new TypeError('input must be a buffer or string'));
};

b64.encode = (input, opts) => new Promise(resolve => {
	const chunkMultiple = 3;
	opts = validateOpts(opts, chunkMultiple);

	if (!(input instanceof Buffer)) {
		throw new TypeError('input must be a buffer');
	}

	const bufferLength = input.length;
	let currentIndex = 0;
	let output = '';

	setImmediate(function encodeChunk() {
		const chunk = input.slice(currentIndex, currentIndex + opts.chunkSize);
		output += chunk.toString('base64');
		currentIndex += opts.chunkSize;
		if (currentIndex < bufferLength) {
			setImmediate(encodeChunk);
		} else {
			resolve(output);
		}
	});
});

b64.decode = (input, opts) => new Promise(resolve => {
	const chunkMultiple = 4;
	opts = validateOpts(opts, chunkMultiple);

	if (typeof input !== 'string') {
		throw new TypeError('input must be a base64 string');
	}

	const stringLength = input.length;
	let currentIndex = 0;
	let output = '';

	setImmediate(function encodeChunk() {
		const chunk = input.slice(currentIndex, currentIndex + opts.chunkSize);
		output += Buffer.from(chunk, 'base64').toString('binary');
		currentIndex += opts.chunkSize;
		if (currentIndex < stringLength) {
			setImmediate(encodeChunk);
		} else {
			output = Buffer.from(output, 'binary');
			resolve(output);
		}
	});
});

module.exports = b64;
<|endoftext|>


<commit_before>const _ = require("lodash")

const PUBLIC_API_DTS_FILES = [
    "lib/src/scan/tokens_public.d.ts",
    "lib/src/scan/lexer_public.d.ts",
    "lib/src/parse/parser_public.d.ts",
    "lib/src/parse/cst/cst_public.d.ts",
    "lib/src/parse/errors_public.d.ts",
    "lib/src/parse/exceptions_public.d.ts",
    "lib/src/parse/grammar/path_public.d.ts",
    "lib/src/parse/grammar/gast_public.d.ts",
    "lib/src/parse/cache_public.d.ts",
    "lib/src/diagrams/render_public.d.ts"
]

const karmaConf = process.env.TRAVIS ? "karma_sauce.conf.js" : "karma.conf.js"

const PUBLIC_API_TS_FILES = _.map(PUBLIC_API_DTS_FILES, function(binDefFile) {
    return binDefFile.replace("lib/", "").replace(".d", "")
})

// so typedoc can compile "module.exports" in cache_public
PUBLIC_API_TS_FILES.push("./node_modules/@types/node/index.d.ts")

const fourSpaces = "    "
const examples_test_command = "npm test"

const INSTALL_LINK = "npm install && npm link chevrotain"
const INSTALL_LINK_TEST = INSTALL_LINK + " && " + examples_test_command

const banner = "/*! <%= pkg.name %> - v<%= pkg.version %> */"

module.exports = function(grunt) {
    const pkg = grunt.file.readJSON("package.json")

    //noinspection UnnecessaryLabelJS
    grunt.initConfig({
        pkg: pkg,

        run: {
            options: {
                failOnError: true
            },
            npm_link: {
                exec: "npm link"
            },
            test_examples_lexer: {
                options: {
                    cwd: process.cwd() + "/examples/lexer/"
                },
                exec: INSTALL_LINK_TEST
            },
            test_examples_grammars: {
                options: {
                    cwd: process.cwd() + "/examples/grammars/"
                },
                exec: INSTALL_LINK_TEST
            },
            test_examples_parser: {
                options: {
                    cwd: process.cwd() + "/examples/parser/"
                },
                exec:
                    INSTALL_LINK +
                    " && " +
                    "grunt --gruntfile minification/gruntfile.js" +
                    " && " +
                    "npm --prefix ./webpack" +
                    " install  ./webpack" +
                    " && " +
                    "npm --prefix ./webpack link chevrotain" +
                    " && " +
                    examples_test_command
            },
            test_examples_implementation_languages: {
                options: {
                    cwd: process.cwd() + "/examples/implementation_languages/"
                },
                exec: INSTALL_LINK + " && npm test"
            },
            test_tutorial: {
                options: {
                    cwd: process.cwd() + "/docs/tutorial/src/"
                },
                exec: INSTALL_LINK + " && npm test"
            }
        },

        karma: {
            options: {
                configFile: karmaConf,
                singleRun: true,
                client: {
                    captureConsole: true
                }
            },

            browsers_unit_tests: {
                options: {
                    port: 9980,
                    files: ["test/test.config.js", "lib/chevrotainSpecs.js"]
                }
            },

            browsers_integration_tests_globals: {
                options: {
                    port: 9982,
                    files: [
                        "lib/chevrotain.js",
                        "test/test.config.js",
                        "test_integration/**/*spec.js"
                    ]
                }
            },

            browsers_integration_tests_amd: {
                options: {
                    port: 9983,
                    frameworks: ["requirejs", "mocha", "chai"],
                    files: [
                        "lib/chevrotain.js",
                        "test/test.config.js",
                        {
                            pattern: "test_integration/*/*.js",
                            included: false
                        },
                        "test_integration/integration_tests_main.js"
                    ]
                }
            },

            browsers_integration_tests_globals_minified: {
                options: {
                    port: 9984,
                    files: [
                        "lib/chevrotain.min.js",
                        "test/test.config.js",
                        "test_integration/**/*spec.js"
                    ]
                }
            },

            browsers_integration_tests_amd_minified: {
                options: {
                    port: 9985,
                    frameworks: ["requirejs", "mocha", "chai"],
                    files: [
                        "lib/chevrotain.min.js",
                        "test/test.config.js",
                        {
                            pattern: "test_integration/*/*.js",
                            included: false
                        },
                        "test_integration/integration_tests_main.js"
                    ]
                }
            }
        },

        concat: {
            release_definitions: {
                options: {
                    // TODO: seems like the HashTable class may need to be included in the public API
                    banner:
                        banner +
                        "\n" +
                        "export as namespace chevrotain;\n" +
                        "declare class HashTable<V>{}\n",

                    process: function processDefinitions(src, filePath) {
                        const withOutImports = src.replace(
                            /import.*;(\n|\r\n)/g,
                            ""
                        )
                        // TODO: investigate why do Typescript definition files include private members.
                        const withoutPrivate = withOutImports.replace(
                            /private.*;(\n|\r\n)/g,
                            ""
                        )

                        return withoutPrivate
                    },

                    // extra spaces needed to fix indentation.
                    separator: grunt.util.linefeed + fourSpaces
                },
                files: {
                    "lib/chevrotain.d.ts": PUBLIC_API_DTS_FILES
                }
            }
        }
    })

    require("load-grunt-tasks")(grunt)

    const integrationTestsNodeTasks = [
        "run:npm_link",
        "run:test_examples_grammars",
        "run:test_examples_parser",
        "run:test_examples_lexer",
        "run:test_examples_implementation_languages",
        "run:test_tutorial"
    ]

    const browserTestsTasks = [
        "karma:browsers_unit_tests",
        "karma:browsers_integration_tests_globals",
        "karma:browsers_integration_tests_globals_minified",
        "karma:browsers_integration_tests_amd",
        "karma:browsers_integration_tests_amd_minified"
    ]

    grunt.registerTask("browsers_tests", browserTestsTasks)
    grunt.registerTask("integration_tests", integrationTestsNodeTasks)
}
<commit_msg>Fix tutorial integration tests.<commit_after>const _ = require("lodash")

const PUBLIC_API_DTS_FILES = [
    "lib/src/scan/tokens_public.d.ts",
    "lib/src/scan/lexer_public.d.ts",
    "lib/src/parse/parser_public.d.ts",
    "lib/src/parse/cst/cst_public.d.ts",
    "lib/src/parse/errors_public.d.ts",
    "lib/src/parse/exceptions_public.d.ts",
    "lib/src/parse/grammar/path_public.d.ts",
    "lib/src/parse/grammar/gast_public.d.ts",
    "lib/src/parse/cache_public.d.ts",
    "lib/src/diagrams/render_public.d.ts"
]

const karmaConf = process.env.TRAVIS ? "karma_sauce.conf.js" : "karma.conf.js"

const PUBLIC_API_TS_FILES = _.map(PUBLIC_API_DTS_FILES, function(binDefFile) {
    return binDefFile.replace("lib/", "").replace(".d", "")
})

// so typedoc can compile "module.exports" in cache_public
PUBLIC_API_TS_FILES.push("./node_modules/@types/node/index.d.ts")

const fourSpaces = "    "
const examples_test_command = "npm test"

const INSTALL_LINK = "npm install && npm link chevrotain"
const INSTALL_LINK_TEST = INSTALL_LINK + " && " + examples_test_command

const banner = "/*! <%= pkg.name %> - v<%= pkg.version %> */"

module.exports = function(grunt) {
    const pkg = grunt.file.readJSON("package.json")

    //noinspection UnnecessaryLabelJS
    grunt.initConfig({
        pkg: pkg,

        run: {
            options: {
                failOnError: true
            },
            npm_link: {
                exec: "npm link"
            },
            test_examples_lexer: {
                options: {
                    cwd: process.cwd() + "/examples/lexer/"
                },
                exec: INSTALL_LINK_TEST
            },
            test_examples_grammars: {
                options: {
                    cwd: process.cwd() + "/examples/grammars/"
                },
                exec: INSTALL_LINK_TEST
            },
            test_examples_parser: {
                options: {
                    cwd: process.cwd() + "/examples/parser/"
                },
                exec:
                    INSTALL_LINK +
                    " && " +
                    "grunt --gruntfile minification/gruntfile.js" +
                    " && " +
                    "npm --prefix ./webpack" +
                    " install  ./webpack" +
                    " && " +
                    "npm --prefix ./webpack link chevrotain" +
                    " && " +
                    examples_test_command
            },
            test_examples_implementation_languages: {
                options: {
                    cwd: process.cwd() + "/examples/implementation_languages/"
                },
                exec: INSTALL_LINK + " && npm test"
            },
            test_tutorial: {
                options: {
                    cwd: process.cwd() + "/docs/01_Tutorial/src/"
                },
                exec: INSTALL_LINK + " && npm test"
            }
        },

        karma: {
            options: {
                configFile: karmaConf,
                singleRun: true,
                client: {
                    captureConsole: true
                }
            },

            browsers_unit_tests: {
                options: {
                    port: 9980,
                    files: ["test/test.config.js", "lib/chevrotainSpecs.js"]
                }
            },

            browsers_integration_tests_globals: {
                options: {
                    port: 9982,
                    files: [
                        "lib/chevrotain.js",
                        "test/test.config.js",
                        "test_integration/**/*spec.js"
                    ]
                }
            },

            browsers_integration_tests_amd: {
                options: {
                    port: 9983,
                    frameworks: ["requirejs", "mocha", "chai"],
                    files: [
                        "lib/chevrotain.js",
                        "test/test.config.js",
                        {
                            pattern: "test_integration/*/*.js",
                            included: false
                        },
                        "test_integration/integration_tests_main.js"
                    ]
                }
            },

            browsers_integration_tests_globals_minified: {
                options: {
                    port: 9984,
                    files: [
                        "lib/chevrotain.min.js",
                        "test/test.config.js",
                        "test_integration/**/*spec.js"
                    ]
                }
            },

            browsers_integration_tests_amd_minified: {
                options: {
                    port: 9985,
                    frameworks: ["requirejs", "mocha", "chai"],
                    files: [
                        "lib/chevrotain.min.js",
                        "test/test.config.js",
                        {
                            pattern: "test_integration/*/*.js",
                            included: false
                        },
                        "test_integration/integration_tests_main.js"
                    ]
                }
            }
        },

        concat: {
            release_definitions: {
                options: {
                    // TODO: seems like the HashTable class may need to be included in the public API
                    banner:
                        banner +
                        "\n" +
                        "export as namespace chevrotain;\n" +
                        "declare class HashTable<V>{}\n",

                    process: function processDefinitions(src, filePath) {
                        const withOutImports = src.replace(
                            /import.*;(\n|\r\n)/g,
                            ""
                        )
                        // TODO: investigate why do Typescript definition files include private members.
                        const withoutPrivate = withOutImports.replace(
                            /private.*;(\n|\r\n)/g,
                            ""
                        )

                        return withoutPrivate
                    },

                    // extra spaces needed to fix indentation.
                    separator: grunt.util.linefeed + fourSpaces
                },
                files: {
                    "lib/chevrotain.d.ts": PUBLIC_API_DTS_FILES
                }
            }
        }
    })

    require("load-grunt-tasks")(grunt)

    const integrationTestsNodeTasks = [
        "run:npm_link",
        "run:test_examples_grammars",
        "run:test_examples_parser",
        "run:test_examples_lexer",
        "run:test_examples_implementation_languages",
        "run:test_tutorial"
    ]

    const browserTestsTasks = [
        "karma:browsers_unit_tests",
        "karma:browsers_integration_tests_globals",
        "karma:browsers_integration_tests_globals_minified",
        "karma:browsers_integration_tests_amd",
        "karma:browsers_integration_tests_amd_minified"
    ]

    grunt.registerTask("browsers_tests", browserTestsTasks)
    grunt.registerTask("integration_tests", integrationTestsNodeTasks)
}
<|endoftext|>


<commit_before>/* eslint func-names: 0*/
/* eslint no-unused-expressions: 0*/

import scrollTop from 'dom-helpers/query/scrollTop'
import on from 'dom-helpers/events/on'
import throttle from 'lodash.throttle'
import { canUseDOM } from 'exenv'

const prefix = '@@POS'
const scrollThreshold = 50

function saveState(key, y) {
  sessionStorage.setItem(`${prefix}${key}`, `${y}`)
}
function getState(key) {
  return sessionStorage.getItem(`${prefix}${key}`)
}
function createKey(loc) {
  const query = loc.query
  const queryString = Object.keys(query).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(query[k])}`).join('&')
  return `${loc.pathname}?${queryString}`
}

function scrollToHash(loc) {
  //
  if (!loc.hash) {
    return false
  }
  const hash = decodeURIComponent(loc.hash)
  const hashParts = hash.split('#')

  if (hashParts.length >= 2) {
    const _hash = hashParts[1]
    const element = document.querySelector(`#${_hash}`)
    if (element) {
      element.scrollIntoView()
      return true
    }
  }
  return false
}

function scrollToState(key) {
  const y = getState(key)
  if (!y) {
    return false
  }
  // setTimeout 0 for avoid page rendering
  setTimeout( () => {
    window.scrollTo(0, y)
  }, 0)
  return true
}

export default function (history) {
  if (!canUseDOM) {
    return history
  }
  let currentKey = null
  history.listen( function (loc) {
    currentKey = createKey(loc)
    // first try to check hash
    // second try to scrollTo State
    // finally scrollToTop
    !scrollToHash(loc) && !scrollToState(currentKey) && window.scrollTo(0, 0)
  })
  const onScroll = () => {
    const y = scrollTop(window)
    saveState(currentKey, y)
  }

  on(window, 'scroll', throttle(onScroll, scrollThreshold))
  return history
}
<commit_msg>resolve #2 for supporting history/lib/createBrowserHistory<commit_after>/* eslint func-names: 0*/
/* eslint no-unused-expressions: 0*/

import scrollTop from 'dom-helpers/query/scrollTop'
import on from 'dom-helpers/events/on'
import throttle from 'lodash.throttle'
import { canUseDOM } from 'exenv'

const prefix = '@@POS'
const scrollThreshold = 50

function saveState(key, y) {
  sessionStorage.setItem(`${prefix}${key}`, `${y}`)
}
function getState(key) {
  return sessionStorage.getItem(`${prefix}${key}`)
}
function createKey(loc) {
  let queryString = '';
  if (loc.query && typeof loc.query === 'object') {
    const query = loc.query
    queryString = '?' + Object.keys(query).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(query[k])}`).join('&')
  } else if (loc.search) {
    queryString = loc.search;
  }

  return `${loc.pathname}?${queryString}`
}

function scrollToHash(loc) {
  //
  if (!loc.hash) {
    return false
  }
  const hash = decodeURIComponent(loc.hash)
  const hashParts = hash.split('#')

  if (hashParts.length >= 2) {
    const _hash = hashParts[1]
    const element = document.querySelector(`#${_hash}`)
    if (element) {
      element.scrollIntoView()
      return true
    }
  }
  return false
}

function scrollToState(key) {
  const y = getState(key)
  if (!y) {
    return false
  }
  // setTimeout 0 for avoid page rendering
  setTimeout( () => {
    window.scrollTo(0, y)
  }, 0)
  return true
}

export default function (history) {
  if (!canUseDOM) {
    return history
  }
  let currentKey = null
  history.listen( function (loc) {
    currentKey = createKey(loc)
    // first try to check hash
    // second try to scrollTo State
    // finally scrollToTop
    !scrollToHash(loc) && !scrollToState(currentKey) && window.scrollTo(0, 0)
  })
  const onScroll = () => {
    const y = scrollTop(window)
    saveState(currentKey, y)
  }

  on(window, 'scroll', throttle(onScroll, scrollThreshold))
  return history
}
<|endoftext|>


<commit_before>var shell = require('shelljs')

module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt)

  grunt.initConfig({
    standard: {
      options: { format: false },
      gruntfile: { src: ['gruntfile.js'] },
      scripts: { src: 'scripts/**/*.js' },
      js: { src: 'src/**/*.js' }
    },
    browserify: {
      dist: { src: 'index.js', dest: 'plugin.js' }
    },
    uglify: {
      dist: { files: { 'plugin.min.js': ['plugin.js'] } }
    },
    watch: {
      gruntfile: {
        options: {reload: true},
        files: 'Gruntfile.js',
        tasks: ['standard:gruntfile']
      },
      js: {
        files: ['src/**/*.js'],
        tasks: ['standard:js', 'browserify', 'jsdoc']
      }
    },
    bump: {
      options: {
        files: ['package.json', 'bower.json'],
        updateConfigs: [],
        commit: true,
        commitMessage: 'Release v%VERSION%',
        commitFiles: ['package.json', 'bower.json'],
        createTag: true,
        tagName: 'v%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'gh-sirap-group',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
        globalReplace: false,
        prereleaseName: false,
        regExp: false
      }
    }
  })

  grunt.registerTask('jsdoc', function () {
    shell.exec('npm run jsdoc')
  })

  grunt.registerTask('build', ['standard', 'browserify', 'uglify', 'jsdoc'])

  grunt.registerTask('dev', ['standard', 'browserify', 'watch'])

  grunt.registerTask('default', ['dev'])
}
<commit_msg>use default 'rc' prerelease postfix<commit_after>var shell = require('shelljs')

module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt)

  grunt.initConfig({
    standard: {
      options: { format: false },
      gruntfile: { src: ['gruntfile.js'] },
      scripts: { src: 'scripts/**/*.js' },
      js: { src: 'src/**/*.js' }
    },
    browserify: {
      dist: { src: 'index.js', dest: 'plugin.js' }
    },
    uglify: {
      dist: { files: { 'plugin.min.js': ['plugin.js'] } }
    },
    watch: {
      gruntfile: {
        options: {reload: true},
        files: 'Gruntfile.js',
        tasks: ['standard:gruntfile']
      },
      js: {
        files: ['src/**/*.js'],
        tasks: ['standard:js', 'browserify', 'jsdoc']
      }
    },
    bump: {
      options: {
        files: ['package.json', 'bower.json'],
        updateConfigs: [],
        commit: true,
        commitMessage: 'Release v%VERSION%',
        commitFiles: ['package.json', 'bower.json'],
        createTag: true,
        tagName: 'v%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'gh-sirap-group',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
        globalReplace: false,
        // prereleaseName: 'rc',
        regExp: false
      }
    }
  })

  grunt.registerTask('jsdoc', function () {
    shell.exec('npm run jsdoc')
  })

  grunt.registerTask('build', ['standard', 'browserify', 'uglify', 'jsdoc'])

  grunt.registerTask('dev', ['standard', 'browserify', 'watch'])

  grunt.registerTask('default', ['dev'])
}
<|endoftext|>


<commit_before>var EMPTY_OBJECT = {}
var EMPTY_ARRAY = []

var map = EMPTY_ARRAY.map
var isArray = Array.isArray

var DEFAULT_NODE = 0
var RECYCLED_NODE = 1
var LAZY_NODE = 2
var TEXT_NODE = 3

var defer =
  typeof Promise === "function"
    ? function(cb) {
        Promise.resolve().then(cb)
      }
    : setTimeout

var merge = function(a, b) {
  var out = {}

  for (var i in a) out[i] = a[i]
  for (var i in b) out[i] = b[i]

  return out
}

var batch = function(list) {
  return list.reduce(function(out, obj) {
    return out.concat(
      !obj || obj === true
        ? false
        : typeof obj[0] === "function"
        ? [obj]
        : batch(obj)
    )
  }, EMPTY_ARRAY)
}

var isSameAction = function(a, b) {
  return isArray(a) && isArray(b) && a[0] === b[0] && typeof a[0] === "function"
}

var shouldRestart = function(a, b) {
  for (var k in merge(a, b)) {
    if (a[k] === b[k] || isSameAction(a[k], b[k])) b[k] = a[k]
    else return true
  }
}

var patchSub = function(sub, newSub, dispatch) {
  return batch(newSub).map(function(a, b) {
    b = sub[b]
    return a
      ? !b || a[0] !== b[0] || shouldRestart(a[1], b[1])
        ? [a[0], a[1], a[0](a[1], dispatch), b && b[2]()]
        : b
      : b && b[2]()
  })
}

var createClass = function(obj) {
  var out = ""
  var tmp = typeof obj

  if (tmp === "string" || tmp === "number") return obj

  if (isArray(obj) && obj.length > 0) {
    for (var i = 0; i < obj.length; i++) {
      if ((tmp = createClass(obj[i])) !== "") out += (out && " ") + tmp
    }
  } else {
    for (var i in obj) {
      if (obj[i]) out += (out && " ") + i
    }
  }

  return out
}

var updateProperty = function(element, name, value, newValue, eventCb, isSvg) {
  if (name === "key") {
  } else if (name === "style") {
    for (var i in merge(value, newValue)) {
      var style = newValue == null || newValue[i] == null ? "" : newValue[i]
      if (i[0] === "-") {
        element[name].setProperty(i, style)
      } else {
        element[name][i] = style
      }
    }
  } else {
    if (name[0] === "o" && name[1] === "n") {
      if (
        !((element.events || (element.events = {}))[
          (name = name.slice(2).toLowerCase())
        ] = newValue)
      ) {
        element.removeEventListener(name, eventCb)
      } else if (!value) {
        element.addEventListener(name, eventCb)
      }
    } else if (name !== "list" && !isSvg && name in element) {
      element[name] = newValue == null ? "" : newValue
    } else if (
      newValue == null ||
      newValue === false ||
      (name === "class" && !(newValue = createClass(newValue)))
    ) {
      element.removeAttribute(name)
    } else {
      element.setAttribute(name, newValue)
    }
  }
}

var removeElement = function(parent, node) {
  parent.removeChild(node.element)
}

var createElement = function(node, eventCb, isSvg) {
  var element =
    node.type === TEXT_NODE
      ? document.createTextNode(node.name)
      : (isSvg = isSvg || node.name === "svg")
      ? document.createElementNS("http://www.w3.org/2000/svg", node.name)
      : document.createElement(node.name)
  var props = node.props

  for (var i = 0, len = node.children.length; i < len; i++) {
    element.appendChild(
      createElement(
        (node.children[i] = getNode(node.children[i])),
        eventCb,
        isSvg
      )
    )
  }

  for (var k in props) {
    updateProperty(element, k, null, props[k], eventCb, isSvg)
  }

  return (node.element = element)
}

var updateElement = function(element, props, newProps, eventCb, isSvg) {
  for (var k in merge(props, newProps)) {
    if (
      (k === "value" || k === "checked" ? element[k] : props[k]) !== newProps[k]
    ) {
      updateProperty(element, k, props[k], newProps[k], eventCb, isSvg)
    }
  }
}

var getKey = function(node) {
  return node == null ? null : node.key
}

var createKeyMap = function(children, start, end) {
  for (var out = {}, key, node; start <= end; start++) {
    if ((key = (node = children[start]).key) != null) {
      out[key] = node
    }
  }
  return out
}

var patch = function(parent, element, node, newNode, eventCb, isSvg) {
  if (newNode === node) {
  } else if (
    node != null &&
    node.type === TEXT_NODE &&
    newNode.type === TEXT_NODE
  ) {
    if (node.name !== newNode.name) element.nodeValue = newNode.name
  } else if (node == null || node.name !== newNode.name) {
    var newElement = parent.insertBefore(
      createElement((newNode = getNode(newNode)), eventCb, isSvg),
      element
    )

    if (node != null) removeElement(parent, node)

    element = newElement
  } else {
    updateElement(
      element,
      node.props,
      newNode.props,
      eventCb,
      (isSvg = isSvg || newNode.name === "svg")
    )

    var savedNode
    var childNode

    var key
    var children = node.children
    var start = 0
    var end = children.length - 1

    var newKey
    var newChildren = newNode.children
    var newStart = 0
    var newEnd = newChildren.length - 1

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[start])
      newKey = getKey(newChildren[newStart])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[start].element,
        children[start],
        (newChildren[newStart] = getNode(
          newChildren[newStart],
          children[start]
        )),
        eventCb,
        isSvg
      )

      start++
      newStart++
    }

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[end])
      newKey = getKey(newChildren[newEnd])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[end].element,
        children[end],
        (newChildren[newEnd] = getNode(newChildren[newEnd], children[end])),
        eventCb,
        isSvg
      )

      end--
      newEnd--
    }

    if (start > end) {
      while (newStart <= newEnd) {
        element.insertBefore(
          createElement(
            (newChildren[newStart] = getNode(newChildren[newStart++])),
            eventCb,
            isSvg
          ),
          (childNode = children[start]) && childNode.element
        )
      }
    } else if (newStart > newEnd) {
      while (start <= end) {
        removeElement(element, children[start++])
      }
    } else {
      var keyed = createKeyMap(children, start, end)
      var newKeyed = {}

      while (newStart <= newEnd) {
        key = getKey((childNode = children[start]))
        newKey = getKey(
          (newChildren[newStart] = getNode(newChildren[newStart], childNode))
        )

        if (
          newKeyed[key] ||
          (newKey != null && newKey === getKey(children[start + 1]))
        ) {
          if (key == null) {
            removeElement(element, childNode)
          }
          start++
          continue
        }

        if (newKey == null || node.type === RECYCLED_NODE) {
          if (key == null) {
            patch(
              element,
              childNode && childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newStart++
          }
          start++
        } else {
          if (key === newKey) {
            patch(
              element,
              childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newKeyed[newKey] = true
            start++
          } else {
            if ((savedNode = keyed[newKey]) != null) {
              patch(
                element,
                element.insertBefore(
                  savedNode.element,
                  childNode && childNode.element
                ),
                savedNode,
                newChildren[newStart],
                eventCb,
                isSvg
              )
              newKeyed[newKey] = true
            } else {
              patch(
                element,
                childNode && childNode.element,
                null,
                newChildren[newStart],
                eventCb,
                isSvg
              )
            }
          }
          newStart++
        }
      }

      while (start <= end) {
        if (getKey((childNode = children[start++])) == null) {
          removeElement(element, childNode)
        }
      }

      for (var key in keyed) {
        if (newKeyed[key] == null) {
          removeElement(element, keyed[key])
        }
      }
    }
  }

  return (newNode.element = element)
}

var shouldUpdate = function(a, b) {
  for (var k in a) if (a[k] !== b[k]) return true
  for (var k in b) if (a[k] !== b[k]) return true
}

var getNode = function(newNode, node) {
  return newNode.type === LAZY_NODE
    ? !node || shouldUpdate(newNode.lazy, node.lazy)
      ? newNode.render()
      : node
    : newNode
}

var createVNode = function(name, props, children, element, key, type) {
  return {
    name: name,
    props: props,
    children: children,
    element: element,
    type: type,
    key: key
  }
}

var createTextVNode = function(text, element) {
  return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
}

var recycleChild = function(element) {
  return element.nodeType === TEXT_NODE
    ? createTextVNode(element.nodeValue, element)
    : recycleElement(element)
}

var recycleElement = function(element) {
  return createVNode(
    element.nodeName.toLowerCase(),
    EMPTY_OBJECT,
    map.call(element.childNodes, recycleChild),
    element,
    null,
    RECYCLED_NODE
  )
}

export var Lazy = function(props) {
  return {
    type: LAZY_NODE,
    key: props.key,
    lazy: props,
    render: function() {
      var node = props.render(props)
      node.lazy = props
      return node
    }
  }
}

export var h = function(name, props) {
  for (var node, rest = [], children = [], i = arguments.length; i-- > 2; ) {
    rest.push(arguments[i])
  }

  for (; rest.length > 0; ) {
    if (isArray((node = rest.pop()))) {
      for (i = node.length; i-- > 0; ) rest.push(node[i])
    } else if (node === false || node === true || node == null) {
    } else {
      children.push(typeof node === "object" ? node : createTextVNode(node))
    }
  }

  props = props || EMPTY_OBJECT

  return typeof name === "function"
    ? name(props, children)
    : createVNode(name, props, children, null, props.key, DEFAULT_NODE)
}

export var app = function(props) {
  var container = props.container
  var element = container && container.children[0]
  var node = element && recycleElement(element)
  var subs = props.subscriptions
  var view = props.view
  var lock = false
  var sub = []
  var state

  var eventCb = function(event) {
    dispatch(event.currentTarget.events[event.type], event)
  }

  var setState = function(newState) {
    if (!(state === newState || lock)) {
      defer(render, (lock = true))
    }
    state = newState
  }

  var dispatch = function(obj, props) {
    if (typeof obj === "function") {
      dispatch(obj(state, props))
    } else if (isArray(obj)) {
      if (typeof obj[0] === "function") {
        dispatch(obj[0](state, obj[1], props))
      } else {
        batch(obj.slice(1)).map(function(fx) {
          fx && fx[0](fx[1], dispatch)
        }, setState(obj[0]))
      }
    } else {
      setState(obj)
    }
  }

  var render = function() {
    lock = false
    if (subs) sub = patchSub(sub, subs(state), dispatch)
    if (view) {
      element = patch(container, element, node, (node = view(state)), eventCb)
    }
  }

  dispatch(props.init || {})
}
<commit_msg>Make state {} by default<commit_after>var EMPTY_OBJECT = {}
var EMPTY_ARRAY = []

var map = EMPTY_ARRAY.map
var isArray = Array.isArray

var DEFAULT_NODE = 0
var RECYCLED_NODE = 1
var LAZY_NODE = 2
var TEXT_NODE = 3

var defer =
  typeof Promise === "function"
    ? function(cb) {
        Promise.resolve().then(cb)
      }
    : setTimeout

var merge = function(a, b) {
  var out = {}

  for (var i in a) out[i] = a[i]
  for (var i in b) out[i] = b[i]

  return out
}

var batch = function(list) {
  return list.reduce(function(out, obj) {
    return out.concat(
      !obj || obj === true
        ? false
        : typeof obj[0] === "function"
        ? [obj]
        : batch(obj)
    )
  }, EMPTY_ARRAY)
}

var isSameAction = function(a, b) {
  return isArray(a) && isArray(b) && a[0] === b[0] && typeof a[0] === "function"
}

var shouldRestart = function(a, b) {
  for (var k in merge(a, b)) {
    if (a[k] === b[k] || isSameAction(a[k], b[k])) b[k] = a[k]
    else return true
  }
}

var patchSub = function(sub, newSub, dispatch) {
  return batch(newSub).map(function(a, b) {
    b = sub[b]
    return a
      ? !b || a[0] !== b[0] || shouldRestart(a[1], b[1])
        ? [a[0], a[1], a[0](a[1], dispatch), b && b[2]()]
        : b
      : b && b[2]()
  })
}

var createClass = function(obj) {
  var out = ""
  var tmp = typeof obj

  if (tmp === "string" || tmp === "number") return obj

  if (isArray(obj) && obj.length > 0) {
    for (var i = 0; i < obj.length; i++) {
      if ((tmp = createClass(obj[i])) !== "") out += (out && " ") + tmp
    }
  } else {
    for (var i in obj) {
      if (obj[i]) out += (out && " ") + i
    }
  }

  return out
}

var updateProperty = function(element, name, value, newValue, eventCb, isSvg) {
  if (name === "key") {
  } else if (name === "style") {
    for (var i in merge(value, newValue)) {
      var style = newValue == null || newValue[i] == null ? "" : newValue[i]
      if (i[0] === "-") {
        element[name].setProperty(i, style)
      } else {
        element[name][i] = style
      }
    }
  } else {
    if (name[0] === "o" && name[1] === "n") {
      if (
        !((element.events || (element.events = {}))[
          (name = name.slice(2).toLowerCase())
        ] = newValue)
      ) {
        element.removeEventListener(name, eventCb)
      } else if (!value) {
        element.addEventListener(name, eventCb)
      }
    } else if (name !== "list" && !isSvg && name in element) {
      element[name] = newValue == null ? "" : newValue
    } else if (
      newValue == null ||
      newValue === false ||
      (name === "class" && !(newValue = createClass(newValue)))
    ) {
      element.removeAttribute(name)
    } else {
      element.setAttribute(name, newValue)
    }
  }
}

var removeElement = function(parent, node) {
  parent.removeChild(node.element)
}

var createElement = function(node, eventCb, isSvg) {
  var element =
    node.type === TEXT_NODE
      ? document.createTextNode(node.name)
      : (isSvg = isSvg || node.name === "svg")
      ? document.createElementNS("http://www.w3.org/2000/svg", node.name)
      : document.createElement(node.name)
  var props = node.props

  for (var i = 0, len = node.children.length; i < len; i++) {
    element.appendChild(
      createElement(
        (node.children[i] = getNode(node.children[i])),
        eventCb,
        isSvg
      )
    )
  }

  for (var k in props) {
    updateProperty(element, k, null, props[k], eventCb, isSvg)
  }

  return (node.element = element)
}

var updateElement = function(element, props, newProps, eventCb, isSvg) {
  for (var k in merge(props, newProps)) {
    if (
      (k === "value" || k === "checked" ? element[k] : props[k]) !== newProps[k]
    ) {
      updateProperty(element, k, props[k], newProps[k], eventCb, isSvg)
    }
  }
}

var getKey = function(node) {
  return node == null ? null : node.key
}

var createKeyMap = function(children, start, end) {
  for (var out = {}, key, node; start <= end; start++) {
    if ((key = (node = children[start]).key) != null) {
      out[key] = node
    }
  }
  return out
}

var patch = function(parent, element, node, newNode, eventCb, isSvg) {
  if (newNode === node) {
  } else if (
    node != null &&
    node.type === TEXT_NODE &&
    newNode.type === TEXT_NODE
  ) {
    if (node.name !== newNode.name) element.nodeValue = newNode.name
  } else if (node == null || node.name !== newNode.name) {
    var newElement = parent.insertBefore(
      createElement((newNode = getNode(newNode)), eventCb, isSvg),
      element
    )

    if (node != null) removeElement(parent, node)

    element = newElement
  } else {
    updateElement(
      element,
      node.props,
      newNode.props,
      eventCb,
      (isSvg = isSvg || newNode.name === "svg")
    )

    var savedNode
    var childNode

    var key
    var children = node.children
    var start = 0
    var end = children.length - 1

    var newKey
    var newChildren = newNode.children
    var newStart = 0
    var newEnd = newChildren.length - 1

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[start])
      newKey = getKey(newChildren[newStart])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[start].element,
        children[start],
        (newChildren[newStart] = getNode(
          newChildren[newStart],
          children[start]
        )),
        eventCb,
        isSvg
      )

      start++
      newStart++
    }

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[end])
      newKey = getKey(newChildren[newEnd])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[end].element,
        children[end],
        (newChildren[newEnd] = getNode(newChildren[newEnd], children[end])),
        eventCb,
        isSvg
      )

      end--
      newEnd--
    }

    if (start > end) {
      while (newStart <= newEnd) {
        element.insertBefore(
          createElement(
            (newChildren[newStart] = getNode(newChildren[newStart++])),
            eventCb,
            isSvg
          ),
          (childNode = children[start]) && childNode.element
        )
      }
    } else if (newStart > newEnd) {
      while (start <= end) {
        removeElement(element, children[start++])
      }
    } else {
      var keyed = createKeyMap(children, start, end)
      var newKeyed = {}

      while (newStart <= newEnd) {
        key = getKey((childNode = children[start]))
        newKey = getKey(
          (newChildren[newStart] = getNode(newChildren[newStart], childNode))
        )

        if (
          newKeyed[key] ||
          (newKey != null && newKey === getKey(children[start + 1]))
        ) {
          if (key == null) {
            removeElement(element, childNode)
          }
          start++
          continue
        }

        if (newKey == null || node.type === RECYCLED_NODE) {
          if (key == null) {
            patch(
              element,
              childNode && childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newStart++
          }
          start++
        } else {
          if (key === newKey) {
            patch(
              element,
              childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newKeyed[newKey] = true
            start++
          } else {
            if ((savedNode = keyed[newKey]) != null) {
              patch(
                element,
                element.insertBefore(
                  savedNode.element,
                  childNode && childNode.element
                ),
                savedNode,
                newChildren[newStart],
                eventCb,
                isSvg
              )
              newKeyed[newKey] = true
            } else {
              patch(
                element,
                childNode && childNode.element,
                null,
                newChildren[newStart],
                eventCb,
                isSvg
              )
            }
          }
          newStart++
        }
      }

      while (start <= end) {
        if (getKey((childNode = children[start++])) == null) {
          removeElement(element, childNode)
        }
      }

      for (var key in keyed) {
        if (newKeyed[key] == null) {
          removeElement(element, keyed[key])
        }
      }
    }
  }

  return (newNode.element = element)
}

var shouldUpdate = function(a, b) {
  for (var k in a) if (a[k] !== b[k]) return true
  for (var k in b) if (a[k] !== b[k]) return true
}

var getNode = function(newNode, node) {
  return newNode.type === LAZY_NODE
    ? !node || shouldUpdate(newNode.lazy, node.lazy)
      ? newNode.render()
      : node
    : newNode
}

var createVNode = function(name, props, children, element, key, type) {
  return {
    name: name,
    props: props,
    children: children,
    element: element,
    type: type,
    key: key
  }
}

var createTextVNode = function(text, element) {
  return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
}

var recycleChild = function(element) {
  return element.nodeType === TEXT_NODE
    ? createTextVNode(element.nodeValue, element)
    : recycleElement(element)
}

var recycleElement = function(element) {
  return createVNode(
    element.nodeName.toLowerCase(),
    EMPTY_OBJECT,
    map.call(element.childNodes, recycleChild),
    element,
    null,
    RECYCLED_NODE
  )
}

export var Lazy = function(props) {
  return {
    type: LAZY_NODE,
    key: props.key,
    lazy: props,
    render: function() {
      var node = props.render(props)
      node.lazy = props
      return node
    }
  }
}

export var h = function(name, props) {
  for (var node, rest = [], children = [], i = arguments.length; i-- > 2; ) {
    rest.push(arguments[i])
  }

  for (; rest.length > 0; ) {
    if (isArray((node = rest.pop()))) {
      for (i = node.length; i-- > 0; ) rest.push(node[i])
    } else if (node === false || node === true || node == null) {
    } else {
      children.push(typeof node === "object" ? node : createTextVNode(node))
    }
  }

  props = props || EMPTY_OBJECT

  return typeof name === "function"
    ? name(props, children)
    : createVNode(name, props, children, null, props.key, DEFAULT_NODE)
}

export var app = function(props) {
  var container = props.container
  var element = container && container.children[0]
  var node = element && recycleElement(element)
  var lock = false
  var subs = props.subscriptions
  var view = props.view
  var state = {}
  var sub = []

  var eventCb = function(event) {
    dispatch(event.currentTarget.events[event.type], event)
  }

  var setState = function(newState) {
    if (!(state === newState || lock)) {
      defer(render, (lock = true))
    }
    state = newState
  }

  var dispatch = function(obj, props) {
    if (typeof obj === "function") {
      dispatch(obj(state, props))
    } else if (isArray(obj)) {
      if (typeof obj[0] === "function") {
        dispatch(obj[0](state, obj[1], props))
      } else {
        batch(obj.slice(1)).map(function(fx) {
          fx && fx[0](fx[1], dispatch)
        }, setState(obj[0]))
      }
    } else {
      setState(obj)
    }
  }

  var render = function() {
    lock = false
    if (subs) sub = patchSub(sub, subs(state), dispatch)
    if (view) {
      element = patch(container, element, node, (node = view(state)), eventCb)
    }
  }

  dispatch(props.init)
}
<|endoftext|>


<commit_before>module.exports = function (grunt) {
  grunt.initConfig({
    pkgFile: 'package.json',
    simplemocha: {
      options: {
        ui: 'bdd',
        reporter: 'dot'
      },
      unit: {
        src: [
          'test/mocha-globals.js',
          'test/*.spec.js'
        ]
      }
    },
    'npm-contributors': {
      options: {
        commitMessage: 'chore: update contributors'
      }
    },
    bump: {
      options: {
        commitMessage: 'chore: release v%VERSION%',
        pushTo: 'upstream',
        commitFiles: [
          'package.json',
          'CHANGELOG.md'
        ]
      }
    },
    conventionalChangelog: {
      release: {
        options: {
          changelogOpts: {
            preset: 'angular'
          }
        },
        src: 'CHANGELOG.md'
      }
    },
    conventionalGithubReleaser: {
      release: {
        options: {
          auth: {
            type: 'oauth',
            token: process.env.GH_TOKEN
          },
          changelogOpts: {
            preset: 'angular',
            releaseCount: 0
          }
        }
      }
    },
    eslint: {
      target: [
        'index.js',
        'gruntfile.js',
        'karma.conf.js',
        'test/*.js'
      ]
    }
  })

  require('load-grunt-tasks')(grunt)

  grunt.registerTask('test', ['simplemocha'])
  grunt.registerTask('default', ['eslint', 'test'])

  grunt.registerTask('release', 'Bump the version and publish to NPM.', function (type) {
    grunt.task.run([
      'npm-contributors',
      'bump-only:' + (type || 'patch'),
      'conventionalChangelog',
      'bump-commit',
      'conventionalGithubReleaser',
      'npm-publish'
    ])
  })
}
<commit_msg>chore(release): fixup version bump<commit_after>module.exports = function (grunt) {
  grunt.initConfig({
    pkgFile: 'package.json',
    simplemocha: {
      options: {
        ui: 'bdd',
        reporter: 'dot'
      },
      unit: {
        src: [
          'test/mocha-globals.js',
          'test/*.spec.js'
        ]
      }
    },
    'npm-contributors': {
      options: {
        commitMessage: 'chore: update contributors'
      }
    },
    bump: {
      options: {
        commitMessage: 'chore: release v%VERSION%',
        pushTo: 'upstream',
        commitFiles: [
          'package.json',
          'CHANGELOG.md'
        ]
      }
    },
    conventionalChangelog: {
      release: {
        options: {
          changelogOpts: {
            preset: 'angular'
          }
        },
        src: 'CHANGELOG.md'
      }
    },
    conventionalGithubReleaser: {
      release: {
        options: {
          auth: {
            type: 'oauth',
            token: process.env.GH_TOKEN
          },
          changelogOpts: {
            preset: 'angular',
            releaseCount: 0
          }
        }
      }
    },
    eslint: {
      target: [
        'index.js',
        'gruntfile.js',
        'karma.conf.js',
        'test/*.js'
      ]
    }
  })

  require('load-grunt-tasks')(grunt)

  grunt.registerTask('test', ['simplemocha'])
  grunt.registerTask('default', ['eslint', 'test'])

  grunt.registerTask('release', 'Bump the version and publish to NPM.', function (type) {
    grunt.task.run([
      'npm-contributors',
      'bump:' + (type || 'patch') + ':bump-only',
      'conventionalChangelog',
      'bump-commit',
      'conventionalGithubReleaser',
      'npm-publish'
    ])
  })
}
<|endoftext|>


<commit_before>var module, require;

module.exports = function (grunt) {
    'use strict';

    // Configuration goes here
    grunt.initConfig({

        // Retrieve project's metadata
        pkg: grunt.file.readJSON('package.json'),

        mybanner:   '-------------------------------------\n' +
                    '         <%= pkg.name %>\n' +
                    'Copyright © <%= pkg.author.name %>  2015-<%= grunt.template.today("yyyy") %>\n' +
                    '-------------------------------------\n' +
                    '     Version: <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>)',

        // Compiles Sass files into CSS files
        sass: {
            scss: {
                options: {
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/scss/',
                    src: [
                        '**/*.sass',
                        '**/*.scss'
                    ],
                    dest: 'src/css/origin/',
                    ext: '.css'
                }]
            }
        },

        // Enhances CSS in order to be compatible with more browsers
        postcss: {
            css_origin: {
                options: {
                    map: true,
                    processors: [
                        require('autoprefixer')({browsers: 'last 2 versions'})
                    ]
                },
                files: [{
                    expand: true,
                    cwd: 'src/css/origin/',
                    src: ['**/*.css'],
                    dest: 'src/css/origin/'
                }]
            }
        },

        // Minify CSS
        cssmin: {
            css: {
                options: {
                    //banner: '/*\n<%= mybanner %>\n*/\n',
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/css/origin/',
                    src: ['**/*.css'],
                    dest: 'src/css/',
                    ext: '.min.css'
                }]
            }
        },

        // Minify JavaScript
        uglify: {
            js: {
                options: {
                    //banner: '/*\n<%= mybanner %>\n*/\n',
                    preserveComments: false,
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/js/origin/',
                    src: ['**/*.js'],
                    dest: 'src/js/',
                    ext: '.min.js'
                }]
            }
        },

        // Minify HTML
        minifyHtml: {
            html_minified: {
                options: {
                    conditionals: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/html/_minified/',
                    src: ['**'],
                    dest: 'src/html/_minified/',
                    filter: 'isFile'
                }]
            }
        },

        // Copies files from 3rd party sources to the `src` folder
        // Copies files from `src` folder to `dist` folder on production
        copy: {
            components: {
                files: [{
                    expand: true,
                    cwd: 'components/bootswatch/',
                    src: ['superhero/**'],
                    dest: 'src/scss/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        var output = dest + src;
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            bootstrap_assets: {
                files: [{
                    expand: true,
                    cwd: 'bower_components/bootstrap-sass/assets/',
                    src: [
                        'stylesheets/bootstrap/**',
                        'stylesheets/_bootstrap.scss',
                        'fonts/bootstrap/**',
                        'javascripts/bootstrap.js'
                    ],
                    dest: 'src/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^stylesheets\//, 'scss/').replace(/^scss\/_/, 'scss/').replace(/^javascripts\//, 'js/origin/');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            bower_components: {
                files: [{
                    expand: true,
                    cwd: 'bower_components/',
                    src: [
                        'font-awesome/scss/_**',
                        '!font-awesome/scss/_variables.scss',
                        'font-awesome/fonts/**',
                        'jquery/dist/jquery.js',
                        'html5shiv/dist/html5shiv.js',
                        'respond/dest/respond.src.js'
                    ],
                    dest: 'src/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^font-awesome\/(.*)\//, '$1/font-awesome/').replace(/^jquery\/dist\//, 'js/origin/').replace(/^html5shiv\/dist\//, 'js/origin/polyfill/').replace(/^respond\/dest\/respond.src.js/, 'js/origin/polyfill/respond.js');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            process__fontawesome: {
                options: {
                    process: function (content, path) {
                        if (~path.indexOf('font-awesome.scss')) {
                            return content.replace(/@import "/g, '@import "font-awesome/');
                        } else if (~path.indexOf('_variables.scss')) {
                            return content.replace(/"\.\.\/fonts"/, '"../fonts/font-awesome"');
                        }
                    }
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/font-awesome/scss/',
                    src: [
                        'font-awesome.scss',
                        '_variables.scss'
                    ],
                    dest: 'src/scss/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^_/, 'font-awesome/_');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            process_html: {
                options: {
                    process: function (content, path) {
                        var strDepth = '../';
                        for (var i = path.match(/\//g).length - 2; i; i--) {
                            strDepth = strDepth + '../';
                        }
                        // RegExp to find an opening and closing custom tag
                        // The closing tag is mentioned twice; this helps the opening tag match with the first available closing tag (as opposed to the last found tag)
                        return content.replace(/<!--concat:css-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<link href="' + strDepth + 'css/master.min.css" rel="stylesheet">').replace(/<!--concat:js-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<link href="' + strDepth + 'js/master.min.js" rel="stylesheet">').replace(/<!--concat:polyfill-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<!--[if lt IE 9]><link href="' + strDepth + 'js/polyfill/master.min.js" rel="stylesheet"><![endif]-->').replace(/<!--concat:css_bootswatch-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<link href="' + strDepth + 'css/master_bootswatch.min.css" rel="stylesheet">');
                    }
                },
                files: [{
                    expand: true,
                    cwd: 'src/html/',
                    src: ['**', '!_minified/**'],
                    dest: 'src/html/_minified/',
                    filter: 'isFile'
                }]
            },
            css_origin: {
                files: [{
                    expand: true,
                    cwd: 'src/css/',
                    src: [
                        '**',
                        '!origin/**',
                        '!**/*.min.css',
                        '!**/*.min.css.map'
                    ],
                    dest: 'src/css/origin/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Copies but doesn't replace existing files
                        var output = dest + src;
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            js_origin: {
                files: [{
                    expand: true,
                    cwd: 'src/js/',
                    src: [
                        '**',
                        '!origin/**',
                        '!**/*.min.js',
                        '!**/*.min.js.map'
                    ],
                    dest: 'src/js/origin/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Copies but doesn't replace existing files
                        var output = dest + src;
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: 'src/',
                    src: [
                        'css/**',
                        '!css/origin/**',
                        'fonts/**',
                        'html/_minified/**',
                        'images/**',
                        'js/**',
                        '!js/origin/**',
                        '../LICENSE',
                        '../README.md'
                    ],
                    dest: 'dist/',
                    filter: 'isFile',
                    rename: function (dest, src) {
                        return dest + src.replace(/^html\/_minified/, 'html');
                    }
                }]
            }
        },

        // Merges all CSS files, JS files, and polyfill files into single files
        // Allows for fewer HTTP requests, and faster browser load speeds
        concat: {
            css: {
                files: [{
                    'dist/css/master.min.css': [
                        'src/css/bootstrap.min.css',
                        'src/css/font-awesome.min.css'
                    ]
                }]
            },
            css_bootswatch: {
                files: [{
                    'dist/css/master_bootswatch.min.css': [
                        'src/css/bootswatch.min.css',
                        'src/css/font-awesome.min.css'
                    ]
                }]
            },
            js: {
                files: [{
                    'dist/js/master.min.js': [
                        'src/js/jquery.min.js',
                        'src/js/bootstrap.min.js'
                    ]
                }]
            },
            polyfill: {
                files: [{
                    'dist/js/polyfill/master.min.js': [
                        'src/js/polyfill/html5shiv.min.js',
                        'src/js/polyfill/respond.min.js'
                    ]
                }]
            }
        },

        // Cleans directories which only contain minified files
        clean: {
            dot_delete: {src: ['.DELETE']},
            dist: {
                src: ['dist']
            },
            css_minified: {
                src: ['src/css/*', '!src/css/origin/**']
            },
            js_minified: {
                src: ['src/js/*', '!src/js/origin/**']
            },
            html_minified: {
                src: ['src/html/_minified/**']
            }
        },

        // Watches `src` files for changes, and performs appropriate tasks on-the-fly
        watch: {
            configFiles: {
                options: {
                    reload: true
                },
                files: ['gruntfile.js']
            },
            scss: {
                files: ['src/scss/**/*.sass', 'src/scss/**/*.scss'],
                tasks: ['sass:scss']
            },
            css: {
                files: [
                    'src/css/**/*',
                    '!src/css/**/*.min.css',
                    '!src/css/**/*.min.css.map',
                    '!src/css/origin/**'
                ],
                tasks: ['copy:css_origin', 'clean:css_minified']
            },
            css_origin: {
                files: ['src/css/origin/**/*.css'],
                tasks: ['postcss:css_origin', 'cssmin:css']
            },
            js: {
                files: [
                    'src/js/**/*',
                    '!src/js/**/*.min.js',
                    '!src/js/**/*.min.js.map',
                    '!src/js/origin/**'
                ],
                tasks: ['copy:js_origin', 'clean:js_minified']
            },
            js_origin: {
                files: ['src/js/origin/**/*.js'],
                tasks: ['uglify:js']
            }
        },

        // Create directory template
        mkdir: {
            src: {
                options: {
                    create: [
                        'src/js',
                        'src/css',
                        'src/html',
                        'src/image'
                    ]
                }
            },
            dist: {
                options: {
                    create: [
                        'dist/js',
                        'dist/css',
                        'dist/html',
                        'dist/image'
                    ]
                }
            },
            test: {
                options: {
                    create: ['test']
                }
            },
            docs: {
                options: {
                    create: ['docs/image']
                }
            }
        }

    });

    // Load Grunt plugins
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-minify-html');
    grunt.loadNpmTasks('grunt-mkdir');
    grunt.loadNpmTasks('grunt-postcss');
    grunt.loadNpmTasks('grunt-sass');

    // Register Grunt tasks
    grunt.registerTask('default', ['Compilation-Tasks', 'watch']);

    grunt.registerTask('Make-Directories', ['mkdir:docs']);

    grunt.registerTask('Distribute', [
        'clean:dist',
        'concat',
        'copy:dist'
    ]);

    grunt.registerTask('Compilation-Tasks', [
        'Import-Missing-Assets',
        'Pre-Minify-Cleanup',
        'Preprocess-Sass-CSS',
        'Minify-SRC'
    ]);

    grunt.registerTask('Import-Missing-Assets', [
        'copy:process__fontawesome',
        'copy:bower_components',
        'copy:bootstrap_assets',
        'copy:components',
        'clean:dot_delete'
    ]);

    grunt.registerTask('Pre-Minify-Cleanup', [
        'copy:css_origin',
        'clean:css_minified',
        'copy:js_origin',
        'clean:js_minified',
        'clean:html_minified',
        'clean:dot_delete'
    ]);

    grunt.registerTask('Preprocess-Sass-CSS', [
        'sass:scss',
        'postcss:css_origin'
    ]);

    grunt.registerTask('Minify-SRC', [
        'cssmin',
        'uglify',
        'copy:process_html',
        'minifyHtml'
    ]);

};
<commit_msg>Scripts being interpreted as stylesheets — Fixed<commit_after>var module, require;

module.exports = function (grunt) {
    'use strict';

    // Configuration goes here
    grunt.initConfig({

        // Retrieve project's metadata
        pkg: grunt.file.readJSON('package.json'),

        mybanner:   '-------------------------------------\n' +
                    '         <%= pkg.name %>\n' +
                    'Copyright © <%= pkg.author.name %>  2015-<%= grunt.template.today("yyyy") %>\n' +
                    '-------------------------------------\n' +
                    '     Version: <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>)',

        // Compiles Sass files into CSS files
        sass: {
            scss: {
                options: {
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/scss/',
                    src: [
                        '**/*.sass',
                        '**/*.scss'
                    ],
                    dest: 'src/css/origin/',
                    ext: '.css'
                }]
            }
        },

        // Enhances CSS in order to be compatible with more browsers
        postcss: {
            css_origin: {
                options: {
                    map: true,
                    processors: [
                        require('autoprefixer')({browsers: 'last 2 versions'})
                    ]
                },
                files: [{
                    expand: true,
                    cwd: 'src/css/origin/',
                    src: ['**/*.css'],
                    dest: 'src/css/origin/'
                }]
            }
        },

        // Minify CSS
        cssmin: {
            css: {
                options: {
                    //banner: '/*\n<%= mybanner %>\n*/\n',
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/css/origin/',
                    src: ['**/*.css'],
                    dest: 'src/css/',
                    ext: '.min.css'
                }]
            }
        },

        // Minify JavaScript
        uglify: {
            js: {
                options: {
                    //banner: '/*\n<%= mybanner %>\n*/\n',
                    preserveComments: false,
                    sourceMap: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/js/origin/',
                    src: ['**/*.js'],
                    dest: 'src/js/',
                    ext: '.min.js'
                }]
            }
        },

        // Minify HTML
        minifyHtml: {
            html_minified: {
                options: {
                    conditionals: true
                },
                files: [{
                    expand: true,
                    cwd: 'src/html/_minified/',
                    src: ['**'],
                    dest: 'src/html/_minified/',
                    filter: 'isFile'
                }]
            }
        },

        // Copies files from 3rd party sources to the `src` folder
        // Copies files from `src` folder to `dist` folder on production
        copy: {
            components: {
                files: [{
                    expand: true,
                    cwd: 'components/bootswatch/',
                    src: ['superhero/**'],
                    dest: 'src/scss/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        var output = dest + src;
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            bootstrap_assets: {
                files: [{
                    expand: true,
                    cwd: 'bower_components/bootstrap-sass/assets/',
                    src: [
                        'stylesheets/bootstrap/**',
                        'stylesheets/_bootstrap.scss',
                        'fonts/bootstrap/**',
                        'javascripts/bootstrap.js'
                    ],
                    dest: 'src/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^stylesheets\//, 'scss/').replace(/^scss\/_/, 'scss/').replace(/^javascripts\//, 'js/origin/');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            bower_components: {
                files: [{
                    expand: true,
                    cwd: 'bower_components/',
                    src: [
                        'font-awesome/scss/_**',
                        '!font-awesome/scss/_variables.scss',
                        'font-awesome/fonts/**',
                        'jquery/dist/jquery.js',
                        'html5shiv/dist/html5shiv.js',
                        'respond/dest/respond.src.js'
                    ],
                    dest: 'src/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^font-awesome\/(.*)\//, '$1/font-awesome/').replace(/^jquery\/dist\//, 'js/origin/').replace(/^html5shiv\/dist\//, 'js/origin/polyfill/').replace(/^respond\/dest\/respond.src.js/, 'js/origin/polyfill/respond.js');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            process__fontawesome: {
                options: {
                    process: function (content, path) {
                        if (~path.indexOf('font-awesome.scss')) {
                            return content.replace(/@import "/g, '@import "font-awesome/');
                        } else if (~path.indexOf('_variables.scss')) {
                            return content.replace(/"\.\.\/fonts"/, '"../fonts/font-awesome"');
                        }
                    }
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/font-awesome/scss/',
                    src: [
                        'font-awesome.scss',
                        '_variables.scss'
                    ],
                    dest: 'src/scss/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Renames folders
                        var output = dest + src.replace(/^_/, 'font-awesome/_');
                        //Copies but doesn't replace existing files
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            process_html: {
                options: {
                    process: function (content, path) {
                        var strDepth = '../';
                        for (var i = path.match(/\//g).length - 2; i; i--) {
                            strDepth = strDepth + '../';
                        }
                        // RegExp to find an opening and closing custom tag
                        // The closing tag is mentioned twice; this helps the opening tag match with the first available closing tag (as opposed to the last found tag)
                        return content.replace(/<!--concat:css-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<link href="' + strDepth + 'css/master.min.css" rel="stylesheet">').replace(/<!--concat:js-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<script src="' + strDepth + 'js/master.min.js"></script>').replace(/<!--concat:polyfill-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<!--[if lt IE 9]><script src="' + strDepth + 'js/polyfill/master.min.js"></script><![endif]-->').replace(/<!--concat:css_bootswatch-->(?:(?!<!--\/concat-->)(?:.|\n))*<!--\/concat-->/g, '<link href="' + strDepth + 'css/master_bootswatch.min.css" rel="stylesheet">');
                    }
                },
                files: [{
                    expand: true,
                    cwd: 'src/html/',
                    src: ['**', '!_minified/**'],
                    dest: 'src/html/_minified/',
                    filter: 'isFile'
                }]
            },
            css_origin: {
                files: [{
                    expand: true,
                    cwd: 'src/css/',
                    src: [
                        '**',
                        '!origin/**',
                        '!**/*.min.css',
                        '!**/*.min.css.map'
                    ],
                    dest: 'src/css/origin/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Copies but doesn't replace existing files
                        var output = dest + src;
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            js_origin: {
                files: [{
                    expand: true,
                    cwd: 'src/js/',
                    src: [
                        '**',
                        '!origin/**',
                        '!**/*.min.js',
                        '!**/*.min.js.map'
                    ],
                    dest: 'src/js/origin/',
                    filter: 'isFile',
                    rename: function (dest, src, cwd) {
                        //Copies but doesn't replace existing files
                        var output = dest + src;
                        if (grunt.file.exists(output)) {
                            console.log('Not replacing existing file: ' + output);
                            return '.DELETE/' + src;
                        } else {
                            return output;
                        }
                    }
                }]
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: 'src/',
                    src: [
                        'css/**',
                        '!css/origin/**',
                        'fonts/**',
                        'html/_minified/**',
                        'images/**',
                        'js/**',
                        '!js/origin/**',
                        '../LICENSE',
                        '../README.md'
                    ],
                    dest: 'dist/',
                    filter: 'isFile',
                    rename: function (dest, src) {
                        return dest + src.replace(/^html\/_minified/, 'html');
                    }
                }]
            }
        },

        // Merges all CSS files, JS files, and polyfill files into single files
        // Allows for fewer HTTP requests, and faster browser load speeds
        concat: {
            css: {
                files: [{
                    'dist/css/master.min.css': [
                        'src/css/bootstrap.min.css',
                        'src/css/font-awesome.min.css'
                    ]
                }]
            },
            css_bootswatch: {
                files: [{
                    'dist/css/master_bootswatch.min.css': [
                        'src/css/bootswatch.min.css',
                        'src/css/font-awesome.min.css'
                    ]
                }]
            },
            js: {
                files: [{
                    'dist/js/master.min.js': [
                        'src/js/jquery.min.js',
                        'src/js/bootstrap.min.js'
                    ]
                }]
            },
            polyfill: {
                files: [{
                    'dist/js/polyfill/master.min.js': [
                        'src/js/polyfill/html5shiv.min.js',
                        'src/js/polyfill/respond.min.js'
                    ]
                }]
            }
        },

        // Cleans directories which only contain minified files
        clean: {
            dot_delete: {src: ['.DELETE']},
            dist: {
                src: ['dist']
            },
            css_minified: {
                src: ['src/css/*', '!src/css/origin/**']
            },
            js_minified: {
                src: ['src/js/*', '!src/js/origin/**']
            },
            html_minified: {
                src: ['src/html/_minified/**']
            }
        },

        // Watches `src` files for changes, and performs appropriate tasks on-the-fly
        watch: {
            configFiles: {
                options: {
                    reload: true
                },
                files: ['gruntfile.js']
            },
            scss: {
                files: ['src/scss/**/*.sass', 'src/scss/**/*.scss'],
                tasks: ['sass:scss']
            },
            css: {
                files: [
                    'src/css/**/*',
                    '!src/css/**/*.min.css',
                    '!src/css/**/*.min.css.map',
                    '!src/css/origin/**'
                ],
                tasks: ['copy:css_origin', 'clean:css_minified']
            },
            css_origin: {
                files: ['src/css/origin/**/*.css'],
                tasks: ['postcss:css_origin', 'cssmin:css']
            },
            js: {
                files: [
                    'src/js/**/*',
                    '!src/js/**/*.min.js',
                    '!src/js/**/*.min.js.map',
                    '!src/js/origin/**'
                ],
                tasks: ['copy:js_origin', 'clean:js_minified']
            },
            js_origin: {
                files: ['src/js/origin/**/*.js'],
                tasks: ['uglify:js']
            }
        },

        // Create directory template
        mkdir: {
            src: {
                options: {
                    create: [
                        'src/js',
                        'src/css',
                        'src/html',
                        'src/image'
                    ]
                }
            },
            dist: {
                options: {
                    create: [
                        'dist/js',
                        'dist/css',
                        'dist/html',
                        'dist/image'
                    ]
                }
            },
            test: {
                options: {
                    create: ['test']
                }
            },
            docs: {
                options: {
                    create: ['docs/image']
                }
            }
        }

    });

    // Load Grunt plugins
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-minify-html');
    grunt.loadNpmTasks('grunt-mkdir');
    grunt.loadNpmTasks('grunt-postcss');
    grunt.loadNpmTasks('grunt-sass');

    // Register Grunt tasks
    grunt.registerTask('default', ['Compilation-Tasks', 'watch']);

    grunt.registerTask('Make-Directories', ['mkdir:docs']);

    grunt.registerTask('Distribute', [
        'clean:dist',
        'concat',
        'copy:dist'
    ]);

    grunt.registerTask('Compilation-Tasks', [
        'Import-Missing-Assets',
        'Pre-Minify-Cleanup',
        'Preprocess-Sass-CSS',
        'Minify-SRC'
    ]);

    grunt.registerTask('Import-Missing-Assets', [
        'copy:process__fontawesome',
        'copy:bower_components',
        'copy:bootstrap_assets',
        'copy:components',
        'clean:dot_delete'
    ]);

    grunt.registerTask('Pre-Minify-Cleanup', [
        'copy:css_origin',
        'clean:css_minified',
        'copy:js_origin',
        'clean:js_minified',
        'clean:html_minified',
        'clean:dot_delete'
    ]);

    grunt.registerTask('Preprocess-Sass-CSS', [
        'sass:scss',
        'postcss:css_origin'
    ]);

    grunt.registerTask('Minify-SRC', [
        'cssmin',
        'uglify',
        'copy:process_html',
        'minifyHtml'
    ]);

};
<|endoftext|>