diff --git a/.gitignore b/.gitignore
index 498f0cf8..97b30e70 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,20 +1,4 @@
-# Build folders to ignore
build
-build.local.*
-release
-
-# Sublime
+local
*.sublime-*
-
-# Numerous always-ignore extensions
-*.diff
-*.err
-*.orig
-*.log
-*.rej
-*.swo
-*.swp
-*.vi
-*~
-*.sass-cache
diff --git a/build.properties b/build.properties
deleted file mode 100644
index 849a0818..00000000
--- a/build.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# project
-project.name = h5ai
-project.version = 0.21-pre
-
-# src
-src.dir = src
-
-# build
-build.dir = build
-release.dir = release
-
-# tools
-tool.wepp = wepp
-tool.jshint = jshint
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 68c8127c..00000000
--- a/build.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
-
-
-
-
-
-
-
- Build: ${build.label}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/jshint.json b/jshint.json
deleted file mode 100644
index 7db98e63..00000000
--- a/jshint.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- // Enforcing Options
- "bitwise": true,
- "curly": true,
- "eqeqeq": true,
- "forin": true,
- "latedef": true,
- "newcap": true,
- "noempty": true,
- "plusplus": true,
- "trailing": true,
- "undef": true,
-
- // Environments
- "browser": true,
-
- // Globals
- "predef": [
- "modulejs"
- ]
-}
\ No newline at end of file
diff --git a/makefile.js b/makefile.js
new file mode 100644
index 00000000..b311df52
--- /dev/null
+++ b/makefile.js
@@ -0,0 +1,174 @@
+/*jshint node: true */
+'use strict';
+
+
+var path = require('path'),
+ child_process = require('child_process'),
+ moment = require('moment');
+
+
+var version = '0.21-dev-30',
+
+ root = path.resolve(__dirname),
+ src = path.join(root, 'src'),
+ build = path.join(root, 'build'),
+
+ jshint = {
+ // Enforcing Options
+ bitwise: true,
+ curly: true,
+ eqeqeq: true,
+ forin: true,
+ latedef: true,
+ newcap: true,
+ noempty: true,
+ plusplus: true,
+ trailing: true,
+ undef: true,
+
+ // Environments
+ browser: true,
+
+ // Globals
+ predef: [
+ 'modulejs'
+ ]
+ },
+
+ mapper = function (blob) {
+
+ return blob.source.replace(src, build).replace(/\.less$/, '.css');
+ },
+
+ mapperRoot = function (blob) {
+
+ return blob.source.replace(root, build + '/_h5ai');
+ };
+
+
+module.exports = function (make, $) {
+
+ var stamp, replacements;
+
+
+ make.defaults('build');
+
+
+ make.before = function () {
+
+ stamp = moment();
+
+ replacements = {
+ version: version,
+ stamp: stamp.format('YYYY-MM-DD HH:mm:ss')
+ };
+
+ $.info({ method: 'before', message: version + ' ' + replacements.stamp.human });
+ };
+
+
+ make.target('inc', [], 'increase build number, if any')
+ .sync(function () {
+
+ var re = /-(\d+)$/;
+ var match = version.match(re);
+
+ if (match) {
+ var number = parseInt(match[1], 10) + 1;
+ var newVersion = version.replace(re, '-' + number);
+
+ $('makefile.js').replace([[version, newVersion]]).write($.OVERWRITE, 'makefile.js');
+
+ version = newVersion;
+ replacements.version = version;
+ $.ok({ method: 'inc', message: 'version is now ' + version });
+ }
+ });
+
+
+ make.target('clean', [], 'delete build folder')
+ .sync(function () {
+
+ $.rmfr($.I_AM_SURE, build);
+ });
+
+
+ make.target('lint', [], 'lint all JavaScript files with JSHint')
+ .sync(function () {
+
+ $(src + '/_h5ai/js: **/*.js, ! *.min.js, ! inc/lib/**')
+ .jshint(jshint);
+ });
+
+
+ make.target('build', [], 'build all updated files')
+ .sync(function () {
+
+ $(src + ': _h5ai/js/*.js')
+ .modified(mapper, $(src + ': _h5ai/js/**'))
+ .includify()
+ .uglifyjs()
+ .write($.OVERWRITE, mapper);
+
+ $(src + ': _h5ai/css/*.less')
+ .modified(mapper, $(src + ': _h5ai/css/**'))
+ .less()
+ .cssmin()
+ .write($.OVERWRITE, mapper);
+
+ $(src + ': **, **/*/.*, ! _h5ai/js/**, ! _h5ai/css/**')
+ .modified(mapper)
+ .mustache(replacements)
+ .write($.OVERWRITE, mapper);
+
+ $(root + ': README*, LICENSE*')
+ .modified(mapperRoot)
+ .write($.OVERWRITE, mapperRoot);
+ });
+
+
+ make.target('build-uncompressed', [], 'build all updated files without compression')
+ .sync(function () {
+
+ $(src + ': _h5ai/js/*.js')
+ .modified(mapper, $(src + ': _h5ai/js/**'))
+ .includify()
+ // .uglifyjs()
+ .write($.OVERWRITE, mapper);
+
+ $(src + ': _h5ai/css/*.less')
+ .modified(mapper, $(src + ': _h5ai/css/**'))
+ .less()
+ // .cssmin()
+ .write($.OVERWRITE, mapper);
+
+ $(src + ': **, **/*/.*, ! _h5ai/js/**, ! _h5ai/css/**')
+ .modified(mapper)
+ .mustache(replacements)
+ .write($.OVERWRITE, mapper);
+
+ $(root + ': README*, LICENSE*')
+ .modified(mapperRoot)
+ .write($.OVERWRITE, mapperRoot);
+ });
+
+
+ make.target('release', ['inc', 'clean', 'build'], 'create a zipball')
+ .async(function (done, fail) {
+
+ var target = path.join(build, 'h5ai-' + version + '.zip'),
+ command = 'zip -ro ' + target + ' _h5ai',
+ options = { cwd: build };
+
+ child_process.exec(command, options, function (error, stdout, stderr) {
+
+ if (error === null) {
+ $.ok({ method: 'zip', message: target });
+ done();
+ } else {
+ $.error({ method: 'zip', message: stderr });
+ fail();
+ }
+ });
+ });
+};
diff --git a/src/_h5ai/apache/autoindex.htaccess b/src/_h5ai/apache/autoindex.htaccess
index ff633dee..99595977 100644
--- a/src/_h5ai/apache/autoindex.htaccess
+++ b/src/_h5ai/apache/autoindex.htaccess
@@ -1,5 +1,5 @@
################################
-# h5ai %BUILD_VERSION%
+# h5ai {{version}}
# customized .htaccess
################################
@@ -19,5 +19,5 @@ IndexOptions NameWidth=*
IndexOptions SuppressDescription
IndexOptions SuppressHTMLPreamble
IndexOptions SuppressRules
-IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
+IndexOptions Type=text/html;h5ai={{version}}
IndexOptions XHTML
diff --git a/src/_h5ai/apache/h5ai-header.html b/src/_h5ai/apache/h5ai-header.html
index 77d8aca1..d0da7cf1 100644
--- a/src/_h5ai/apache/h5ai-header.html
+++ b/src/_h5ai/apache/h5ai-header.html
@@ -24,7 +24,7 @@
- h5ai %BUILD_VERSION%
+ h5ai {{version}}
⚡ JavaScript is disabled! ⚡
⚡ Some features disabled! Works best in modern browsers. ⚡
diff --git a/src/_h5ai/config.js b/src/_h5ai/config.js
index 5006d3e0..096ede71 100644
--- a/src/_h5ai/config.js
+++ b/src/_h5ai/config.js
@@ -1,5 +1,5 @@
/*
- * h5ai %BUILD_VERSION%
+ * h5ai {{version}}
*
* Configuration
* options, types and localization
diff --git a/src/_h5ai/config.php b/src/_h5ai/config.php
index 9c8b2e7d..9670f96c 100644
--- a/src/_h5ai/config.php
+++ b/src/_h5ai/config.php
@@ -1,6 +1,6 @@
-
h5ai %BUILD_VERSION% server details
+
h5ai {{version}} server details
@@ -17,8 +17,8 @@
h5ai
-
version %BUILD_VERSION%
-
%BUILD_STAMP%
+
version {{version}}
+
{{stamp}}
server supports
- php version?
@@ -54,7 +54,7 @@
- h5ai %BUILD_VERSION%
+ h5ai {{version}}
⚡ JavaScript is disabled! ⚡
⚡ Some features disabled! Works best in modern browsers. ⚡
diff --git a/src/_h5ai/php/h5ai-index.php b/src/_h5ai/php/h5ai-index.php
index e96e198d..81606b97 100644
--- a/src/_h5ai/php/h5ai-index.php
+++ b/src/_h5ai/php/h5ai-index.php
@@ -1,4 +1,4 @@
-
+
@@ -25,7 +25,7 @@