diff --git a/.prettierrc b/.prettierrc
index 76c4a67..d306351 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,7 +1,7 @@
 {
   "bracketSpacing": true,
   "printWidth": 120,
-  "tabWidth": 2,
+  "tabWidth": 4,
   "trailingComma": "none",
-  "useTabs": true
+  "useTabs": false
 }
diff --git a/README.md b/README.md
index d8e9289..244afa7 100644
--- a/README.md
+++ b/README.md
@@ -22,26 +22,26 @@ Greenlock Express is a **Web Server** with **Fully Automated HTTPS** and renewal
 "use strict";
 
 function httpsWorker(glx) {
-	// Serves on 80 and 443
-	// Get's SSL certificates magically!
+    // Serves on 80 and 443
+    // Get's SSL certificates magically!
 
-	glx.serveApp(function(req, res) {
-		res.end("Hello, Encrypted World!");
-	});
+    glx.serveApp(function(req, res) {
+        res.end("Hello, Encrypted World!");
+    });
 }
 
 var pkg = require("./package.json");
 require("greenlock-express")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: pkg.name, version: pkg.version },
-			maintainerEmail: pkg.author,
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: pkg.name, version: pkg.version },
+            maintainerEmail: pkg.author,
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
 ```
 
 Manage via API or the config file:
@@ -50,44 +50,44 @@ Manage via API or the config file:
 
 ```json
 {
-	"subscriberEmail": "letsencrypt-test@therootcompany.com",
-	"agreeToTerms": true,
-	"sites": {
-		"example.com": {
-			"subject": "example.com",
-			"altnames": ["example.com", "www.example.com"]
-		}
-	}
+    "subscriberEmail": "letsencrypt-test@therootcompany.com",
+    "agreeToTerms": true,
+    "sites": {
+        "example.com": {
+            "subject": "example.com",
+            "altnames": ["example.com", "www.example.com"]
+        }
+    }
 }
 ```
 
 # Let's Encrypt for...
 
-- IoT
-- Enterprise On-Prem
-- Local Development
-- Home Servers
-- Quitting Heroku
+-   IoT
+-   Enterprise On-Prem
+-   Local Development
+-   Home Servers
+-   Quitting Heroku
 
 # Features
 
-- [x] Let's Encrypt v2 (November 2019)
-  - [x] ACME Protocol (RFC 8555)
-  - [x] HTTP Validation (HTTP-01)
-  - [x] DNS Validation (DNS-01)
-  - [ ] ALPN Validation (TLS-ALPN-01)
-    - Need ALPN validation? [contact us](mailto:greenlock-support@therootcompany.com)
-- [x] Automated HTTPS
-  - [x] Fully Automatic Renewals every 45 days
-  - [x] Free SSL
-  - [x] **Wildcard** SSL
-  - [x] **Localhost** certificates
-  - [x] HTTPS-enabled Secure **WebSockets** (`wss://`)
-- [x] Fully customizable
-  - [x] **Reasonable defaults**
-  - [x] Domain Management
-  - [x] Key and Certificate Management
-  - [x] ACME Challenge Plugins
+-   [x] Let's Encrypt v2 (November 2019)
+    -   [x] ACME Protocol (RFC 8555)
+    -   [x] HTTP Validation (HTTP-01)
+    -   [x] DNS Validation (DNS-01)
+    -   [ ] ALPN Validation (TLS-ALPN-01)
+        -   Need ALPN validation? [contact us](mailto:greenlock-support@therootcompany.com)
+-   [x] Automated HTTPS
+    -   [x] Fully Automatic Renewals every 45 days
+    -   [x] Free SSL
+    -   [x] **Wildcard** SSL
+    -   [x] **Localhost** certificates
+    -   [x] HTTPS-enabled Secure **WebSockets** (`wss://`)
+-   [x] Fully customizable
+    -   [x] **Reasonable defaults**
+    -   [x] Domain Management
+    -   [x] Key and Certificate Management
+    -   [x] ACME Challenge Plugins
 
 # QuickStart Guide
 
@@ -127,7 +127,7 @@ works with everything.
 // A plain, node-style app
 
 function myPlainNodeHttpApp(req, res) {
-	res.end("Hello, Encrypted World!");
+    res.end("Hello, Encrypted World!");
 }
 
 // Wrap that plain app in express,
@@ -152,9 +152,9 @@ module.exports = app;
 
 Greenlock Express is designed with these goals in mind:
 
-- Simplicity and ease-of-use
-- Performance and scalability
-- Configurability and control
+-   Simplicity and ease-of-use
+-   Performance and scalability
+-   Configurability and control
 
 You can start with **near-zero configuration** and
 slowly add options for greater performance and customization
@@ -164,21 +164,21 @@ later, if you need them.
 
 ```js
 require("greenlock-express")
-	.init(getConfig)
-	.serve(worker);
+    .init(getConfig)
+    .serve(worker);
 
 function getConfig() {
-	return {
-		// uses name and version as part of the ACME client user-agent
-		// uses author as the contact for support notices
-		package: require("./package.json")
-	};
+    return {
+        // uses name and version as part of the ACME client user-agent
+        // uses author as the contact for support notices
+        package: require("./package.json")
+    };
 }
 
 function worker(server) {
-	// Works with any Node app (Express, etc)
-	var app = require("my-express-app.js");
-	server.serveApp(app);
+    // Works with any Node app (Express, etc)
+    var app = require("my-express-app.js");
+    server.serveApp(app);
 }
 ```
 
@@ -222,14 +222,14 @@ This will update the config file (assuming the default fs-based management plugi
 
 ```json
 {
-	"subscriberEmail": "letsencrypt-test@therootcompany.com",
-	"agreeToTerms": true,
-	"sites": {
-		"example.com": {
-			"subject": "example.com",
-			"altnames": ["example.com", "www.example.com"]
-		}
-	}
+    "subscriberEmail": "letsencrypt-test@therootcompany.com",
+    "agreeToTerms": true,
+    "sites": {
+        "example.com": {
+            "subject": "example.com",
+            "altnames": ["example.com", "www.example.com"]
+        }
+    }
 }
 ```
 
@@ -269,10 +269,10 @@ npx greenlock add --subject example.com --altnames example.com,www.example.com
 Note: **Localhost**, **Wildcard**, and Certificates for Private Networks require
 [**DNS validation**](https://git.rootprojects.org/root/greenlock-exp).
 
-- DNS Validation
-  - [**Wildcards**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/wildcards/) (coming soon)
-  - [**Localhost**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/localhost/) (coming soon)
-  - [**CI/CD**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/ci-cd/) (coming soon)
+-   DNS Validation
+    -   [**Wildcards**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/wildcards/) (coming soon)
+    -   [**Localhost**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/localhost/) (coming soon)
+    -   [**CI/CD**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/ci-cd/) (coming soon)
 
 
 
@@ -280,17 +280,17 @@ Note: **Localhost**, **Wildcard**, and Certificates for Private Networks require
 
 **These are in-progress** Check back tomorrow (Nov 2nd, 2019).
 
-- [greenlock-express.js/examples/](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples)
-  - [Express](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/express/)
-  - [Node's **http2**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/http2/)
-  - [Node's https](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/https/)
-  - [**WebSockets**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/websockets/)
-  - [Socket.IO](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/socket-io/)
-  - [Cluster](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/cluster/)
-  - [**Wildcards**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/wildcards/) (coming soon)
-  - [**Localhost**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/localhost/) (coming soon)
-  - [**CI/CD**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/ci-cd/) (coming soon)
-  - [HTTP Proxy](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/http-proxy/)
+-   [greenlock-express.js/examples/](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples)
+    -   [Express](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/express/)
+    -   [Node's **http2**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/http2/)
+    -   [Node's https](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/https/)
+    -   [**WebSockets**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/websockets/)
+    -   [Socket.IO](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/socket-io/)
+    -   [Cluster](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/cluster/)
+    -   [**Wildcards**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/wildcards/) (coming soon)
+    -   [**Localhost**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/localhost/) (coming soon)
+    -   [**CI/CD**](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/ci-cd/) (coming soon)
+    -   [HTTP Proxy](https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/http-proxy/)
 
 # Easy to Customize
 
@@ -300,10 +300,10 @@ Note: **Localhost**, **Wildcard**, and Certificates for Private Networks require
 - [greenlock.js/examples/](https://git.rootprojects.org/root/greenlock.js/src/branch/master/examples)
 -->
 
-- [Custom Domain Management](https://git.rootprojects.org/root/greenlock-manager-test.js)
-- [Custom Key & Cert Storage](https://git.rootprojects.org/root/greenlock-store-test.js)
-- [Custom ACME HTTP-01 Challenges](https://git.rootprojects.org/root/acme-http-01-test.js)
-- [Custom ACME DNS-01 Challenges](https://git.rootprojects.org/root/acme-dns-01-test.js)
+-   [Custom Domain Management](https://git.rootprojects.org/root/greenlock-manager-test.js)
+-   [Custom Key & Cert Storage](https://git.rootprojects.org/root/greenlock-store-test.js)
+-   [Custom ACME HTTP-01 Challenges](https://git.rootprojects.org/root/acme-http-01-test.js)
+-   [Custom ACME DNS-01 Challenges](https://git.rootprojects.org/root/acme-dns-01-test.js)
 
 # Ready-made Integrations
 
@@ -345,12 +345,12 @@ We're working on more comprehensive documentation for this newly released versio
 
 Do you need...
 
-- training?
-- specific features?
-- different integrations?
-- bugfixes, on _your_ timeline?
-- custom code, built by experts?
-- commercial support and licensing?
+-   training?
+-   specific features?
+-   different integrations?
+-   bugfixes, on _your_ timeline?
+-   custom code, built by experts?
+-   commercial support and licensing?
 
 You're welcome to [contact us](mailto:aj@therootcompany.com) in regards to IoT, On-Prem,
 Enterprise, and Internal installations, integrations, and deployments.
diff --git a/config.js b/config.js
index 005abd0..3aa97de 100644
--- a/config.js
+++ b/config.js
@@ -2,19 +2,19 @@
 
 var path = require("path");
 module.exports = {
-	email: "jon.doe@example.com",
-	configDir: path.join(__dirname, "acme"),
-	srv: "/srv/www/",
-	api: "/srv/api/",
-	proxy: {
-		"example.com": "http://localhost:4080",
-		"*.example.com": "http://localhost:4080"
-	},
+    email: "jon.doe@example.com",
+    configDir: path.join(__dirname, "acme"),
+    srv: "/srv/www/",
+    api: "/srv/api/",
+    proxy: {
+        "example.com": "http://localhost:4080",
+        "*.example.com": "http://localhost:4080"
+    },
 
-	// DNS-01 challenges only
-	challenges: {
-		"*.example.com": require("acme-dns-01-YOUR_DNS_HOST").create({
-			token: "xxxx"
-		})
-	}
+    // DNS-01 challenges only
+    challenges: {
+        "*.example.com": require("acme-dns-01-YOUR_DNS_HOST").create({
+            token: "xxxx"
+        })
+    }
 };
diff --git a/demo.js b/demo.js
index 9e33bed..6399c85 100644
--- a/demo.js
+++ b/demo.js
@@ -1,35 +1,35 @@
 "use strict";
 
 require("./")
-	.init(initialize)
-	.serve(worker)
-	.master(function() {
-		console.log("Hello from master");
-	});
+    .init(initialize)
+    .serve(worker)
+    .master(function() {
+        console.log("Hello from master");
+    });
 
 function initialize() {
-	var pkg = require("./package.json");
-	var config = {
-		package: {
-			name: "Greenlock_Express_Demo",
-			version: pkg.version,
-			author: pkg.author
-		},
-		staging: true,
-		cluster: true,
+    var pkg = require("./package.json");
+    var config = {
+        package: {
+            name: "Greenlock_Express_Demo",
+            version: pkg.version,
+            author: pkg.author
+        },
+        staging: true,
+        cluster: true,
 
-		notify: function(ev, params) {
-			console.info(ev, params);
-		}
-	};
-	return config;
+        notify: function(ev, params) {
+            console.info(ev, params);
+        }
+    };
+    return config;
 }
 
 function worker(glx) {
-	console.info();
-	console.info("Hello from worker #" + glx.id());
+    console.info();
+    console.info("Hello from worker #" + glx.id());
 
-	glx.serveApp(function(req, res) {
-		res.end("Hello, Encrypted World!");
-	});
+    glx.serveApp(function(req, res) {
+        res.end("Hello, Encrypted World!");
+    });
 }
diff --git a/examples/cluster/server.js b/examples/cluster/server.js
index 03e4eea..ba66dc2 100644
--- a/examples/cluster/server.js
+++ b/examples/cluster/server.js
@@ -3,37 +3,37 @@
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "websocket-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
+        return {
+            package: { name: "websocket-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
 
-			// When you're ready to go full cloud scale, you just change this to true:
-			// Note: in cluster you CANNOT use in-memory state (see below)
-			cluster: true,
+            // When you're ready to go full cloud scale, you just change this to true:
+            // Note: in cluster you CANNOT use in-memory state (see below)
+            cluster: true,
 
-			// This will default to the number of workers being equal to
-			// n-1 cpus, with a minimum of 2
-			workers: 4
-		};
-	})
-	.serve(httpsWorker);
+            // This will default to the number of workers being equal to
+            // n-1 cpus, with a minimum of 2
+            workers: 4
+        };
+    })
+    .serve(httpsWorker);
 
 function httpsWorker(glx) {
-	// WRONG
-	// This won't work like you
-	// think because EACH worker
-	// has ITS OWN `count`.
-	var count = 0;
+    // WRONG
+    // This won't work like you
+    // think because EACH worker
+    // has ITS OWN `count`.
+    var count = 0;
 
-	var app = function(req, res) {
-		res.end("Hello... how many times now? Oh, " + count + " times");
-		count += 1;
-	};
+    var app = function(req, res) {
+        res.end("Hello... how many times now? Oh, " + count + " times");
+        count += 1;
+    };
 
-	// Serves on 80 and 443... for each worker
-	// Get's SSL certificates magically!
-	glx.serveApp(app);
+    // Serves on 80 and 443... for each worker
+    // Get's SSL certificates magically!
+    glx.serveApp(app);
 }
diff --git a/examples/express/my-express-app.js b/examples/express/my-express-app.js
index fada117..aabbb2b 100644
--- a/examples/express/my-express-app.js
+++ b/examples/express/my-express-app.js
@@ -4,13 +4,13 @@ var express = require("express");
 var app = express();
 
 app.use("/", function(req, res) {
-	res.setHeader("Content-Type", "text/html; charset=utf-8");
-	res.end("Hello, World!\n\nš š.js");
+    res.setHeader("Content-Type", "text/html; charset=utf-8");
+    res.end("Hello, World!\n\nš š.js");
 });
 
 // DO NOT DO app.listen() unless we're testing this directly
 if (require.main === module) {
-	app.listen(3000);
+    app.listen(3000);
 }
 
 // Instead do export the app:
diff --git a/examples/express/server.js b/examples/express/server.js
index 97f5752..3242553 100644
--- a/examples/express/server.js
+++ b/examples/express/server.js
@@ -1,27 +1,27 @@
 "use strict";
 
 function httpsWorker(glx) {
-	var app = require("./my-express-app.js");
+    var app = require("./my-express-app.js");
 
-	app.get("/hello", function(req, res) {
-		res.end("Hello, Encrypted World!");
-	});
+    app.get("/hello", function(req, res) {
+        res.end("Hello, Encrypted World!");
+    });
 
-	// Serves on 80 and 443
-	// Get's SSL certificates magically!
-	glx.serveApp(app);
+    // Serves on 80 and 443
+    // Get's SSL certificates magically!
+    glx.serveApp(app);
 }
 
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "http2-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "http2-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/http-proxy/server.js b/examples/http-proxy/server.js
index 3d4cc77..c8bf342 100644
--- a/examples/http-proxy/server.js
+++ b/examples/http-proxy/server.js
@@ -1,44 +1,44 @@
 "use strict";
 
 function httpsWorker(glx) {
-	// we need the raw https server
-	var server = glx.httpsServer();
-	var proxy = require("http-proxy").createProxyServer({ xfwd: true });
+    // we need the raw https server
+    var server = glx.httpsServer();
+    var proxy = require("http-proxy").createProxyServer({ xfwd: true });
 
-	// catches error events during proxying
-	proxy.on("error", function(err, req, res) {
-		console.error(err);
-		res.statusCode = 500;
-		res.end();
-		return;
-	});
+    // catches error events during proxying
+    proxy.on("error", function(err, req, res) {
+        console.error(err);
+        res.statusCode = 500;
+        res.end();
+        return;
+    });
 
-	// We'll proxy websockets too
-	server.on("upgrade", function(req, socket, head) {
-		proxy.ws(req, socket, head, {
-			ws: true,
-			target: "ws://localhost:3000"
-		});
-	});
+    // We'll proxy websockets too
+    server.on("upgrade", function(req, socket, head) {
+        proxy.ws(req, socket, head, {
+            ws: true,
+            target: "ws://localhost:3000"
+        });
+    });
 
-	// servers a node app that proxies requests to a localhost
-	glx.serveApp(function(req, res) {
-		proxy.web(req, res, {
-			target: "http://localhost:3000"
-		});
-	});
+    // servers a node app that proxies requests to a localhost
+    glx.serveApp(function(req, res) {
+        proxy.web(req, res, {
+            target: "http://localhost:3000"
+        });
+    });
 }
 
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "http-proxy-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "http-proxy-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/http/server.js b/examples/http/server.js
index 28b3c47..8aa11bb 100644
--- a/examples/http/server.js
+++ b/examples/http/server.js
@@ -11,32 +11,32 @@ var pkg = require("../../package.json");
 // Use glx.httpServer(redirectToHttps) instead.
 
 function httpsWorker(glx) {
-	//
-	// HTTP can only be used for ACME HTTP-01 Challenges
-	// (and it is not required for DNS-01 challenges)
-	//
+    //
+    // HTTP can only be used for ACME HTTP-01 Challenges
+    // (and it is not required for DNS-01 challenges)
+    //
 
-	// Get the raw http server:
-	var httpServer = glx.httpServer(function(req, res) {
-		res.statusCode = 301;
-		res.setHeader("Location", "https://" + req.headers.host + req.path);
-		res.end("Insecure connections are not allowed. Redirecting...");
-	});
+    // Get the raw http server:
+    var httpServer = glx.httpServer(function(req, res) {
+        res.statusCode = 301;
+        res.setHeader("Location", "https://" + req.headers.host + req.path);
+        res.end("Insecure connections are not allowed. Redirecting...");
+    });
 
-	httpServer.listen(80, "0.0.0.0", function() {
-		console.info("Listening on ", httpServer.address());
-	});
+    httpServer.listen(80, "0.0.0.0", function() {
+        console.info("Listening on ", httpServer.address());
+    });
 }
 
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "plain-http-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "plain-http-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/http2/server.js b/examples/http2/server.js
index 023b3c3..1d663f5 100644
--- a/examples/http2/server.js
+++ b/examples/http2/server.js
@@ -11,38 +11,38 @@ var pkg = require("../../package.json");
 // Use glx.httpsServer(tlsOptions, app) instead.
 
 function httpsWorker(glx) {
-	//
-	// HTTP2 would have been the default httpsServer for node v12+
-	// However... https://github.com/expressjs/express/issues/3388
-	//
+    //
+    // HTTP2 would have been the default httpsServer for node v12+
+    // However... https://github.com/expressjs/express/issues/3388
+    //
 
-	// Get the raw http2 server:
-	var http2Server = glx.http2Server(function(req, res) {
-		res.end("Hello, Encrypted World!");
-	});
+    // Get the raw http2 server:
+    var http2Server = glx.http2Server(function(req, res) {
+        res.end("Hello, Encrypted World!");
+    });
 
-	http2Server.listen(443, "0.0.0.0", function() {
-		console.info("Listening on ", http2Server.address());
-	});
+    http2Server.listen(443, "0.0.0.0", function() {
+        console.info("Listening on ", http2Server.address());
+    });
 
-	// Note:
-	// You must ALSO listen on port 80 for ACME HTTP-01 Challenges
-	// (the ACME and http->https middleware are loaded by glx.httpServer)
-	var httpServer = glx.httpServer();
-	httpServer.listen(80, "0.0.0.0", function() {
-		console.info("Listening on ", httpServer.address());
-	});
+    // Note:
+    // You must ALSO listen on port 80 for ACME HTTP-01 Challenges
+    // (the ACME and http->https middleware are loaded by glx.httpServer)
+    var httpServer = glx.httpServer();
+    httpServer.listen(80, "0.0.0.0", function() {
+        console.info("Listening on ", httpServer.address());
+    });
 }
 
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "http2-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "http2-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/https/server.js b/examples/https/server.js
index ace97bf..9ca89c5 100644
--- a/examples/https/server.js
+++ b/examples/https/server.js
@@ -11,38 +11,38 @@ var pkg = require("../../package.json");
 // Use glx.httpsServer(tlsOptions, app) instead.
 
 function httpsWorker(glx) {
-	//
-	// HTTPS 1.1 is the default
-	// (HTTP2 would be the default but... https://github.com/expressjs/express/issues/3388)
-	//
+    //
+    // HTTPS 1.1 is the default
+    // (HTTP2 would be the default but... https://github.com/expressjs/express/issues/3388)
+    //
 
-	// Get the raw https server:
-	var httpsServer = glx.httpsServer(null, function(req, res) {
-		res.end("Hello, Encrypted World!");
-	});
+    // Get the raw https server:
+    var httpsServer = glx.httpsServer(null, function(req, res) {
+        res.end("Hello, Encrypted World!");
+    });
 
-	httpsServer.listen(443, "0.0.0.0", function() {
-		console.info("Listening on ", httpsServer.address());
-	});
+    httpsServer.listen(443, "0.0.0.0", function() {
+        console.info("Listening on ", httpsServer.address());
+    });
 
-	// Note:
-	// You must ALSO listen on port 80 for ACME HTTP-01 Challenges
-	// (the ACME and http->https middleware are loaded by glx.httpServer)
-	var httpServer = glx.httpServer();
-	httpServer.listen(80, "0.0.0.0", function() {
-		console.info("Listening on ", httpServer.address());
-	});
+    // Note:
+    // You must ALSO listen on port 80 for ACME HTTP-01 Challenges
+    // (the ACME and http->https middleware are loaded by glx.httpServer)
+    var httpServer = glx.httpServer();
+    httpServer.listen(80, "0.0.0.0", function() {
+        console.info("Listening on ", httpServer.address());
+    });
 }
 
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "https1-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "https1-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/old-demo.js b/examples/old-demo.js
new file mode 100644
index 0000000..8000314
--- /dev/null
+++ b/examples/old-demo.js
@@ -0,0 +1,75 @@
+"use strict";
+
+// npm install spdy@3.x
+
+//var Greenlock = require('greenlock-express')
+var Greenlock = require("../");
+
+var greenlock = Greenlock.create({
+    // Let's Encrypt v2 is ACME draft 11
+    version: "draft-11",
+
+    server: "https://acme-v02.api.letsencrypt.org/directory",
+    // Note: If at first you don't succeed, stop and switch to staging
+    // https://acme-staging-v02.api.letsencrypt.org/directory
+
+    // You MUST change this to a valid email address
+    email: "jon@example.com",
+
+    // You MUST NOT build clients that accept the ToS without asking the user
+    agreeTos: true,
+
+    // You MUST change these to valid domains
+    // NOTE: all domains will validated and listed on the certificate
+    approvedDomains: ["example.com", "www.example.com"],
+
+    // You MUST have access to write to directory where certs are saved
+    // ex: /home/foouser/acme/etc
+    configDir: "~/.config/acme/",
+
+    // Get notified of important updates and help me make greenlock better
+    communityMember: true
+
+    //, debug: true
+});
+
+////////////////////////
+// http-01 Challenges //
+////////////////////////
+
+// http-01 challenge happens over http/1.1, not http2
+var redirectHttps = require("redirect-https")();
+var acmeChallengeHandler = greenlock.middleware(function(req, res) {
+    res.setHeader("Content-Type", "text/html; charset=utf-8");
+    res.end(
+        "
Hello, ā ļø Insecure World!
Visit Secure Site" +
+            ''
+    );
+});
+require("http")
+    .createServer(acmeChallengeHandler)
+    .listen(80, function() {
+        console.log("Listening for ACME http-01 challenges on", this.address());
+    });
+
+////////////////////////
+// http2 via SPDY h2  //
+////////////////////////
+
+// spdy is a drop-in replacement for the https API
+var spdyOptions = Object.assign({}, greenlock.tlsOptions);
+spdyOptions.spdy = { protocols: ["h2", "http/1.1"], plain: false };
+var server = require("spdy").createServer(
+    spdyOptions,
+    require("express")().use("/", function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.end("Hello, š Secure World!
");
+    })
+);
+server.on("error", function(err) {
+    console.error(err);
+});
+server.on("listening", function() {
+    console.log("Listening for SPDY/http2/https requests on", this.address());
+});
+server.listen(443);
diff --git a/examples/old-force-renew.js b/examples/old-force-renew.js
new file mode 100644
index 0000000..6869f6f
--- /dev/null
+++ b/examples/old-force-renew.js
@@ -0,0 +1,30 @@
+"use strict";
+
+//require('greenlock-express')
+require("../")
+    .create({
+        // Let's Encrypt v2 is ACME draft 11
+        version: "draft-11",
+
+        server: "https://acme-v02.api.letsencrypt.org/directory",
+        // Note: If at first you don't succeed, stop and switch to staging
+        // https://acme-staging-v02.api.letsencrypt.org/directory
+
+        email: "john.doe@example.com",
+
+        agreeTos: true,
+
+        approvedDomains: ["example.com", "www.example.com"],
+
+        app: require("express")().use("/", function(req, res) {
+            res.end("Hello, World!");
+        }),
+
+        renewWithin: 91 * 24 * 60 * 60 * 1000,
+        renewBy: 90 * 24 * 60 * 60 * 1000,
+
+        // Get notified of important updates and help me make greenlock better
+        communityMember: true,
+        debug: true
+    })
+    .listen(80, 443);
diff --git a/examples/old-remote-access.js b/examples/old-remote-access.js
new file mode 100644
index 0000000..2852aa1
--- /dev/null
+++ b/examples/old-remote-access.js
@@ -0,0 +1,104 @@
+"use strict";
+
+//
+// WARNING: Not for noobs
+// Try the simple example first
+//
+
+//
+// This demo is used with tunnel-server.js and tunnel-client.js
+//
+
+var email = "john.doe@gmail.com";
+var domains = ["example.com"];
+var agreeLeTos = true;
+//var secret = "My Little Brony";
+var secret = require("crypto")
+    .randomBytes(16)
+    .toString("hex");
+
+require("../")
+    .create({
+        version: "draft-11",
+
+        server: "https://acme-v02.api.letsencrypt.org/directory",
+        // Note: If at first you don't succeed, stop and switch to staging
+        // https://acme-staging-v02.api.letsencrypt.org/directory
+
+        email: email,
+        agreeTos: agreeLeTos,
+        approveDomains: domains,
+        configDir: "~/.config/acme/",
+        app: remoteAccess(secret),
+        // Get notified of important updates and help me make greenlock better
+        communityMember: true
+        //, debug: true
+    })
+    .listen(3000, 8443);
+
+function remoteAccess(secret) {
+    var express = require("express");
+    var basicAuth = require("express-basic-auth");
+    var serveIndex = require("serve-index");
+
+    var rootIndex = serveIndex("/", { hidden: true, icons: true, view: "details" });
+    var rootFs = express.static("/", { dotfiles: "allow", redirect: true, index: false });
+
+    var userIndex = serveIndex(require("os").homedir(), { hidden: true, icons: true, view: "details" });
+    var userFs = express.static(require("os").homedir(), { dotfiles: "allow", redirect: true, index: false });
+
+    var app = express();
+    var realm = "Login Required";
+
+    var myAuth = basicAuth({
+        users: { root: secret, user: secret },
+        challenge: true,
+        realm: realm,
+        unauthorizedResponse: function(/*req*/) {
+            return 'Unauthorized Home';
+        }
+    });
+
+    app.get("/", function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.end('View Files' + "  |  " + 'Logout');
+    });
+    app.use("/logout", function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.setHeader("WWW-Authenticate", 'Basic realm="' + realm + '"');
+        res.statusCode = 401;
+        //res.setHeader('Location', '/');
+        res.end('Logged out   |   Home');
+    });
+    app.use("/browse", myAuth);
+    app.use("/browse", function(req, res, next) {
+        if ("root" === req.auth.user) {
+            rootFs(req, res, function() {
+                rootIndex(req, res, next);
+            });
+            return;
+        }
+        if ("user" === req.auth.user) {
+            userFs(req, res, function() {
+                userIndex(req, res, next);
+            });
+            return;
+        }
+        res.end("Sad Panda");
+    });
+
+    console.log("");
+    console.log("");
+    console.log("Usernames are\n");
+    console.log("\troot");
+    console.log("\tuser");
+    console.log("");
+    console.log("Password (for both) is\n");
+    console.log("\t" + secret);
+    console.log("");
+    console.log("Shhhh... It's a secret to everybody!");
+    console.log("");
+    console.log("");
+
+    return app;
+}
diff --git a/examples/old-vhost.js b/examples/old-vhost.js
new file mode 100644
index 0000000..ed93322
--- /dev/null
+++ b/examples/old-vhost.js
@@ -0,0 +1,134 @@
+#!/usr/bin/env node
+"use strict";
+
+///////////////////
+// vhost example //
+///////////////////
+
+//
+// virtual hosting example
+//
+
+// The prefix where sites go by name.
+// For example: whatever.com may live in /srv/www/whatever.com, thus /srv/www is our path
+var srv = process.argv[3] || "/srv/www/";
+
+var path = require("path");
+var fs = require("fs").promises;
+var finalhandler = require("finalhandler");
+var serveStatic = require("serve-static");
+
+//var glx = require('greenlock-express')
+var glx = require("./").create({
+    version: "draft-11", // Let's Encrypt v2 is ACME draft 11
+
+    server: "https://acme-v02.api.letsencrypt.org/directory", // If at first you don't succeed, stop and switch to staging
+    // https://acme-staging-v02.api.letsencrypt.org/directory
+
+    configDir: process.argv[4] || "~/.config/acme/", // You MUST have access to write to directory where certs
+    // are saved. ex: /home/foouser/.config/acme
+
+    approveDomains: myApproveDomains, // Greenlock's wraps around tls.SNICallback. Check the
+    // domain name here and reject invalid ones
+
+    app: myVhostApp, // Any node-style http app (i.e. express, koa, hapi, rill)
+
+    /* CHANGE TO A VALID EMAIL */
+    email: process.argv[2] || "jon.doe@example.com", // Email for Let's Encrypt account and Greenlock Security
+    agreeTos: true // Accept Let's Encrypt ToS
+    //, communityMember: true                                   // Join Greenlock to get important updates, no spam
+
+    //, debug: true
+});
+
+var server = glx.listen(80, 443);
+server.on("listening", function() {
+    console.info(server.type + " listening on", server.address());
+});
+
+function myApproveDomains(opts, certs, cb) {
+    console.log("sni:", opts.domain);
+    // In this example the filesystem is our "database".
+    // We check in /srv/www for whatever.com and if it exists, it's allowed
+
+    // SECURITY Greenlock validates opts.domains ahead-of-time so you don't have to
+    return checkWwws(opts.domains[0])
+        .then(function() {
+            //opts.email = email;
+            opts.agreeTos = true;
+            cb(null, { options: opts, certs: certs });
+        })
+        .catch(cb);
+}
+
+function checkWwws(_hostname) {
+    if (!_hostname) {
+        // SECURITY, don't allow access to the 'srv' root
+        // (greenlock-express uses middleware to check '..', etc)
+        return "";
+    }
+    var hostname = _hostname;
+    var _hostdir = path.join(srv, hostname);
+    var hostdir = _hostdir;
+    // TODO could test for www/no-www both in directory
+    return fs
+        .readdir(hostdir)
+        .then(function() {
+            // TODO check for some sort of htaccess.json and use email in that
+            // NOTE: you can also change other options such as `challengeType` and `challenge`
+            // opts.challengeType = 'http-01';
+            // opts.challenge = require('le-challenge-fs').create({});
+            return hostname;
+        })
+        .catch(function() {
+            if ("www." === hostname.slice(0, 4)) {
+                // Assume we'll redirect to non-www if it's available.
+                hostname = hostname.slice(4);
+                hostdir = path.join(srv, hostname);
+                return fs.readdir(hostdir).then(function() {
+                    // TODO list both domains?
+                    return hostname;
+                });
+            } else {
+                // Or check and see if perhaps we should redirect non-www to www
+                hostname = "www." + hostname;
+                hostdir = path.join(srv, hostname);
+                return fs.readdir(hostdir).then(function() {
+                    // TODO list both domains?
+                    return hostname;
+                });
+            }
+        })
+        .catch(function() {
+            throw new Error("rejecting '" + _hostname + "' because '" + _hostdir + "' could not be read");
+        });
+}
+
+function myVhostApp(req, res) {
+    // SECURITY greenlock pre-sanitizes hostnames to prevent unauthorized fs access so you don't have to
+    // (also: only domains approved above will get here)
+    console.log("vhost:", req.headers.host);
+    if (!req.headers.host) {
+        // SECURITY, don't allow access to the 'srv' root
+        // (greenlock-express uses middleware to check '..', etc)
+        return res.end();
+    }
+
+    // We could cache wether or not a host exists for some amount of time
+    var fin = finalhandler(req, res);
+    return checkWwws(req.headers.host)
+        .then(function(hostname) {
+            if (hostname !== req.headers.host) {
+                res.statusCode = 302;
+                res.setHeader("Location", "https://" + hostname);
+                // SECURITY this is safe only because greenlock disallows invalid hostnames
+                res.end("");
+                return;
+            }
+            var serve = serveStatic(path.join(srv, hostname), { redirect: true });
+            serve(req, res, fin);
+        })
+        .catch(function() {
+            fin();
+        });
+}
diff --git a/examples/old-wildcard.js b/examples/old-wildcard.js
new file mode 100644
index 0000000..349846e
--- /dev/null
+++ b/examples/old-wildcard.js
@@ -0,0 +1,77 @@
+#!/usr/bin/env node
+"use strict";
+/*global Promise*/
+
+///////////////////////
+// wildcard example //
+//////////////////////
+
+//
+// wildcard example
+//
+
+//var glx = require('greenlock-express')
+var glx = require("../").create({
+    version: "draft-11", // Let's Encrypt v2 is ACME draft 11
+
+    server: "https://acme-staging-v02.api.letsencrypt.org/directory",
+    //, server: 'https://acme-v02.api.letsencrypt.org/directory'  // If at first you don't succeed, stop and switch to staging
+    // https://acme-staging-v02.api.letsencrypt.org/directory
+
+    configDir: "~/acme/", // You MUST have access to write to directory where certs
+    // are saved. ex: /home/foouser/.config/acme
+
+    approveDomains: myApproveDomains, // Greenlock's wraps around tls.SNICallback. Check the
+    // domain name here and reject invalid ones
+
+    app: require("./my-express-app.js"), // Any node-style http app (i.e. express, koa, hapi, rill)
+
+    /* CHANGE TO A VALID EMAIL */
+    email: "jon.doe@example.com", // Email for Let's Encrypt account and Greenlock Security
+    agreeTos: true, // Accept Let's Encrypt ToS
+    communityMember: true, // Join Greenlock to (very rarely) get important updates
+
+    //, debug: true
+    store: require("le-store-fs")
+});
+
+var server = glx.listen(80, 443);
+server.on("listening", function() {
+    console.info(server.type + " listening on", server.address());
+});
+
+function myApproveDomains(opts) {
+    console.log("sni:", opts.domain);
+
+    // must be 'example.com' or start with 'example.com'
+    if (
+        "example.com" !== opts.domain &&
+        "example.com" !==
+            opts.domain
+                .split(".")
+                .slice(1)
+                .join(".")
+    ) {
+        return Promise.reject(new Error("we don't serve your kind here: " + opts.domain));
+    }
+
+    // the primary domain for the cert
+    opts.subject = "example.com";
+    // the altnames (including the primary)
+    opts.domains = [opts.subject, "*.example.com"];
+
+    if (!opts.challenges) {
+        opts.challenges = {};
+    }
+    opts.challenges["http-01"] = require("le-challenge-fs").create({});
+    // Note: When implementing a dns-01 plugin you should make it check in a loop
+    // until it can positively confirm that the DNS changes have propagated.
+    // That could take several seconds to a few minutes.
+    opts.challenges["dns-01"] = require("le-challenge-dns").create({});
+
+    // explicitly set account id and certificate.id
+    opts.account = { id: opts.email };
+    opts.certificate = { id: opts.subject };
+
+    return Promise.resolve(opts);
+}
diff --git a/examples/quickstart/README.md b/examples/quickstart/README.md
index 0ebffad..f79371b 100644
--- a/examples/quickstart/README.md
+++ b/examples/quickstart/README.md
@@ -10,13 +10,13 @@ Manage via API or the config file:
 
 ```json
 {
-	"subscriberEmail": "letsencrypt-test@therootcompany.com",
-	"agreeToTerms": true,
-	"sites": {
-		"example.com": {
-			"subject": "example.com",
-			"altnames": ["example.com", "www.example.com"]
-		}
-	}
+    "subscriberEmail": "letsencrypt-test@therootcompany.com",
+    "agreeToTerms": true,
+    "sites": {
+        "example.com": {
+            "subject": "example.com",
+            "altnames": ["example.com", "www.example.com"]
+        }
+    }
 }
 ```
diff --git a/examples/quickstart/server.js b/examples/quickstart/server.js
index 82192f2..a45d6ae 100644
--- a/examples/quickstart/server.js
+++ b/examples/quickstart/server.js
@@ -1,32 +1,32 @@
 "use strict";
 
 function httpsWorker(glx) {
-	// This can be a node http app (shown),
-	// an Express app, or Hapi, Koa, Rill, etc
-	var app = function(req, res) {
-		res.end("Hello, Encrypted World!");
-	};
+    // This can be a node http app (shown),
+    // an Express app, or Hapi, Koa, Rill, etc
+    var app = function(req, res) {
+        res.end("Hello, Encrypted World!");
+    };
 
-	// Serves on 80 and 443
-	// Get's SSL certificates magically!
-	glx.serveApp(app);
+    // Serves on 80 and 443
+    // Get's SSL certificates magically!
+    glx.serveApp(app);
 }
 
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			// Package name+version is used for ACME client user agent
-			package: { name: "websocket-example", version: pkg.version },
+        return {
+            // Package name+version is used for ACME client user agent
+            package: { name: "websocket-example", version: pkg.version },
 
-			// Maintainer email is the contact for critical bug and security notices
-			maintainerEmail: "jon@example.com",
+            // Maintainer email is the contact for critical bug and security notices
+            maintainerEmail: "jon@example.com",
 
-			// Change to true when you're ready to make your app cloud-scale
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+            // Change to true when you're ready to make your app cloud-scale
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/socket.io/server.js b/examples/socket.io/server.js
index fb8be4d..a729dcb 100644
--- a/examples/socket.io/server.js
+++ b/examples/socket.io/server.js
@@ -9,41 +9,41 @@
 //       (see the websocket example)
 
 function httpsWorker(glx) {
-	var socketio = require("socket.io");
-	var io;
+    var socketio = require("socket.io");
+    var io;
 
-	// we need the raw https server
-	var server = glx.httpsServer();
+    // we need the raw https server
+    var server = glx.httpsServer();
 
-	io = socketio(server);
+    io = socketio(server);
 
-	// Then you do your socket.io stuff
-	io.on("connection", function(socket) {
-		console.log("a user connected");
-		socket.emit("Welcome");
+    // Then you do your socket.io stuff
+    io.on("connection", function(socket) {
+        console.log("a user connected");
+        socket.emit("Welcome");
 
-		socket.on("chat message", function(msg) {
-			socket.broadcast.emit("chat message", msg);
-		});
-	});
+        socket.on("chat message", function(msg) {
+            socket.broadcast.emit("chat message", msg);
+        });
+    });
 
-	// servers a node app that proxies requests to a localhost
-	glx.serveApp(function(req, res) {
-		res.setHeader("Content-Type", "text/html; charset=utf-8");
-		res.end("Hello, World!\n\nš š.js");
-	});
+    // servers a node app that proxies requests to a localhost
+    glx.serveApp(function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.end("Hello, World!\n\nš š.js");
+    });
 }
 
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "socket-io-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "socket-io-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/examples/websockets/server.js b/examples/websockets/server.js
index c5694ad..952108f 100644
--- a/examples/websockets/server.js
+++ b/examples/websockets/server.js
@@ -1,42 +1,42 @@
 "use strict";
 
 function httpsWorker(glx) {
-	// we need the raw https server
-	var server = glx.httpsServer();
-	var WebSocket = require("ws");
-	var ws = new WebSocket.Server({ server: server });
-	ws.on("connection", function(ws, req) {
-		// inspect req.headers.authorization (or cookies) for session info
-		ws.send(
-			"[Secure Echo Server] Hello!\nAuth: '" +
-				(req.headers.authorization || "none") +
-				"'\n" +
-				"Cookie: '" +
-				(req.headers.cookie || "none") +
-				"'\n"
-		);
-		ws.on("message", function(data) {
-			ws.send(data);
-		});
-	});
+    // we need the raw https server
+    var server = glx.httpsServer();
+    var WebSocket = require("ws");
+    var ws = new WebSocket.Server({ server: server });
+    ws.on("connection", function(ws, req) {
+        // inspect req.headers.authorization (or cookies) for session info
+        ws.send(
+            "[Secure Echo Server] Hello!\nAuth: '" +
+                (req.headers.authorization || "none") +
+                "'\n" +
+                "Cookie: '" +
+                (req.headers.cookie || "none") +
+                "'\n"
+        );
+        ws.on("message", function(data) {
+            ws.send(data);
+        });
+    });
 
-	// servers a node app that proxies requests to a localhost
-	glx.serveApp(function(req, res) {
-		res.setHeader("Content-Type", "text/html; charset=utf-8");
-		res.end("Hello, World!\n\nš š.js");
-	});
+    // servers a node app that proxies requests to a localhost
+    glx.serveApp(function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.end("Hello, World!\n\nš š.js");
+    });
 }
 
 var pkg = require("../../package.json");
 //require("greenlock-express")
 require("../../")
-	.init(function getConfig() {
-		// Greenlock Config
+    .init(function getConfig() {
+        // Greenlock Config
 
-		return {
-			package: { name: "websocket-example", version: pkg.version },
-			maintainerEmail: "jon@example.com",
-			cluster: false
-		};
-	})
-	.serve(httpsWorker);
+        return {
+            package: { name: "websocket-example", version: pkg.version },
+            maintainerEmail: "jon@example.com",
+            cluster: false
+        };
+    })
+    .serve(httpsWorker);
diff --git a/greenlock-express.js b/greenlock-express.js
index 2000c36..c36d94b 100644
--- a/greenlock-express.js
+++ b/greenlock-express.js
@@ -17,28 +17,28 @@ var GLE = module.exports;
 // under the hood. That's the hope, anyway.
 
 GLE.init = function(fn) {
-	if (cluster.isWorker) {
-		// ignore the init function and launch the worker
-		return require("./worker.js").create();
-	}
+    if (cluster.isWorker) {
+        // ignore the init function and launch the worker
+        return require("./worker.js").create();
+    }
 
-	var opts = fn();
-	if (!opts || "object" !== typeof opts) {
-		throw new Error(
-			"the `Greenlock.init(fn)` function should return an object `{ maintainerEmail, packageAgent, notify }`"
-		);
-	}
+    var opts = fn();
+    if (!opts || "object" !== typeof opts) {
+        throw new Error(
+            "the `Greenlock.init(fn)` function should return an object `{ maintainerEmail, packageAgent, notify }`"
+        );
+    }
 
-	// just for ironic humor
-	["cloudnative", "cloudscale", "webscale", "distributed", "blockchain"].forEach(function(k) {
-		if (opts[k]) {
-			opts.cluster = true;
-		}
-	});
+    // just for ironic humor
+    ["cloudnative", "cloudscale", "webscale", "distributed", "blockchain"].forEach(function(k) {
+        if (opts[k]) {
+            opts.cluster = true;
+        }
+    });
 
-	if (opts.cluster) {
-		return require("./master.js").create(opts);
-	}
+    if (opts.cluster) {
+        return require("./master.js").create(opts);
+    }
 
-	return require("./single.js").create(opts);
+    return require("./single.js").create(opts);
 };
diff --git a/greenlock.js b/greenlock.js
index 6770cbb..c6fff08 100644
--- a/greenlock.js
+++ b/greenlock.js
@@ -1,29 +1,29 @@
 "use strict";
 
 module.exports.create = function(opts) {
-	opts = parsePackage(opts);
-	opts.packageAgent = addGreenlockAgent(opts);
+    opts = parsePackage(opts);
+    opts.packageAgent = addGreenlockAgent(opts);
 
-	var Greenlock = require("@root/greenlock");
-	var greenlock = Greenlock.create(opts);
+    var Greenlock = require("@root/greenlock");
+    var greenlock = Greenlock.create(opts);
 
-	// re-export as top-level function to simplify rpc with workers
-	greenlock.getAcmeHttp01ChallengeResponse = function(opts) {
-		return greenlock.challenges.get(opts);
-	};
+    // re-export as top-level function to simplify rpc with workers
+    greenlock.getAcmeHttp01ChallengeResponse = function(opts) {
+        return greenlock.challenges.get(opts);
+    };
 
-	return greenlock;
+    return greenlock;
 };
 
 function addGreenlockAgent(opts) {
-	// Add greenlock as part of Agent, unless this is greenlock
-	var packageAgent = opts.packageAgent || "";
-	if (!/greenlock(-express|-pro)?/i.test(packageAgent)) {
-		var pkg = require("./package.json");
-		packageAgent += " Greenlock_Express/" + pkg.version;
-	}
+    // Add greenlock as part of Agent, unless this is greenlock
+    var packageAgent = opts.packageAgent || "";
+    if (!/greenlock(-express|-pro)?/i.test(packageAgent)) {
+        var pkg = require("./package.json");
+        packageAgent += " Greenlock_Express/" + pkg.version;
+    }
 
-	return packageAgent.trim();
+    return packageAgent.trim();
 }
 
 // ex: "John Doe  (https://john.doe)"
@@ -32,46 +32,46 @@ function addGreenlockAgent(opts) {
 // ex: "john@example.com"
 var looseEmailRe = /(^|[\s<])([^'" <>:;`]+@[^'" <>:;`]+\.[^'" <>:;`]+)/;
 function parsePackage(opts) {
-	// 'package' is sometimes a reserved word
-	var pkg = opts.package || opts.pkg;
-	if (!pkg) {
-		opts.maintainerEmail = parseMaintainer(opts.maintainerEmail);
-		return opts;
-	}
+    // 'package' is sometimes a reserved word
+    var pkg = opts.package || opts.pkg;
+    if (!pkg) {
+        opts.maintainerEmail = parseMaintainer(opts.maintainerEmail);
+        return opts;
+    }
 
-	if (!opts.packageAgent) {
-		var err = "missing `package.THING`, which is used for the ACME client user agent string";
-		if (!pkg.name) {
-			throw new Error(err.replace("THING", "name"));
-		}
-		if (!pkg.version) {
-			throw new Error(err.replace("THING", "version"));
-		}
-		opts.packageAgent = pkg.name + "/" + pkg.version;
-	}
+    if (!opts.packageAgent) {
+        var err = "missing `package.THING`, which is used for the ACME client user agent string";
+        if (!pkg.name) {
+            throw new Error(err.replace("THING", "name"));
+        }
+        if (!pkg.version) {
+            throw new Error(err.replace("THING", "version"));
+        }
+        opts.packageAgent = pkg.name + "/" + pkg.version;
+    }
 
-	if (!opts.maintainerEmail) {
-		try {
-			opts.maintainerEmail = pkg.author.email || pkg.author.match(looseEmailRe)[2];
-		} catch (e) {}
-	}
-	if (!opts.maintainerEmail) {
-		throw new Error("missing or malformed `package.author`, which is used as the contact for support notices");
-	}
-	opts.package = undefined;
-	opts.maintainerEmail = parseMaintainer(opts.maintainerEmail);
+    if (!opts.maintainerEmail) {
+        try {
+            opts.maintainerEmail = pkg.author.email || pkg.author.match(looseEmailRe)[2];
+        } catch (e) {}
+    }
+    if (!opts.maintainerEmail) {
+        throw new Error("missing or malformed `package.author`, which is used as the contact for support notices");
+    }
+    opts.package = undefined;
+    opts.maintainerEmail = parseMaintainer(opts.maintainerEmail);
 
-	return opts;
+    return opts;
 }
 
 function parseMaintainer(maintainerEmail) {
-	try {
-		maintainerEmail = maintainerEmail.match(looseEmailRe)[2];
-	} catch (e) {
-		maintainerEmail = null;
-	}
-	if (!maintainerEmail) {
-		throw new Error("missing or malformed `maintainerEmail`, which is used as the contact for support notices");
-	}
-	return maintainerEmail;
+    try {
+        maintainerEmail = maintainerEmail.match(looseEmailRe)[2];
+    } catch (e) {
+        maintainerEmail = null;
+    }
+    if (!maintainerEmail) {
+        throw new Error("missing or malformed `maintainerEmail`, which is used as the contact for support notices");
+    }
+    return maintainerEmail;
 }
diff --git a/http-middleware.js b/http-middleware.js
index 2608f67..149081b 100644
--- a/http-middleware.js
+++ b/http-middleware.js
@@ -5,102 +5,102 @@ var servernameRe = /^[a-z0-9\.\-]+$/i;
 var challengePrefix = "/.well-known/acme-challenge/";
 
 HttpMiddleware.create = function(gl, defaultApp) {
-	if (defaultApp && "function" !== typeof defaultApp) {
-		throw new Error("use greenlock.httpMiddleware() or greenlock.httpMiddleware(function (req, res) {})");
-	}
+    if (defaultApp && "function" !== typeof defaultApp) {
+        throw new Error("use greenlock.httpMiddleware() or greenlock.httpMiddleware(function (req, res) {})");
+    }
 
-	return function(req, res, next) {
-		var hostname = HttpMiddleware.sanitizeHostname(req);
+    return function(req, res, next) {
+        var hostname = HttpMiddleware.sanitizeHostname(req);
 
-		req.on("error", function(err) {
-			explainError(gl, err, "http_01_middleware_socket", hostname);
-		});
+        req.on("error", function(err) {
+            explainError(gl, err, "http_01_middleware_socket", hostname);
+        });
 
-		if (skipIfNeedBe(req, res, next, defaultApp, hostname)) {
-			return;
-		}
+        if (skipIfNeedBe(req, res, next, defaultApp, hostname)) {
+            return;
+        }
 
-		var token = req.url.slice(challengePrefix.length);
+        var token = req.url.slice(challengePrefix.length);
 
-		gl.getAcmeHttp01ChallengeResponse({ type: "http-01", servername: hostname, token: token })
-			.catch(function(err) {
-				respondToError(gl, res, err, "http_01_middleware_challenge_response", hostname);
-				return { __done: true };
-			})
-			.then(function(result) {
-				if (result && result.__done) {
-					return;
-				}
-				return respondWithGrace(res, result, hostname, token);
-			});
-	};
+        gl.getAcmeHttp01ChallengeResponse({ type: "http-01", servername: hostname, token: token })
+            .catch(function(err) {
+                respondToError(gl, res, err, "http_01_middleware_challenge_response", hostname);
+                return { __done: true };
+            })
+            .then(function(result) {
+                if (result && result.__done) {
+                    return;
+                }
+                return respondWithGrace(res, result, hostname, token);
+            });
+    };
 };
 
 function skipIfNeedBe(req, res, next, defaultApp, hostname) {
-	if (!hostname || 0 !== req.url.indexOf(challengePrefix)) {
-		if ("function" === typeof defaultApp) {
-			defaultApp(req, res, next);
-		} else if ("function" === typeof next) {
-			next();
-		} else {
-			res.statusCode = 500;
-			res.end("[500] Developer Error: app.use('/', greenlock.httpMiddleware()) or greenlock.httpMiddleware(app)");
-		}
-	}
+    if (!hostname || 0 !== req.url.indexOf(challengePrefix)) {
+        if ("function" === typeof defaultApp) {
+            defaultApp(req, res, next);
+        } else if ("function" === typeof next) {
+            next();
+        } else {
+            res.statusCode = 500;
+            res.end("[500] Developer Error: app.use('/', greenlock.httpMiddleware()) or greenlock.httpMiddleware(app)");
+        }
+    }
 }
 
 function respondWithGrace(res, result, hostname, token) {
-	var keyAuth = result && result.keyAuthorization;
-	if (keyAuth && "string" === typeof keyAuth) {
-		res.setHeader("Content-Type", "text/plain; charset=utf-8");
-		res.end(keyAuth);
-		return;
-	}
+    var keyAuth = result && result.keyAuthorization;
+    if (keyAuth && "string" === typeof keyAuth) {
+        res.setHeader("Content-Type", "text/plain; charset=utf-8");
+        res.end(keyAuth);
+        return;
+    }
 
-	res.statusCode = 404;
-	res.setHeader("Content-Type", "application/json; charset=utf-8");
-	res.end(JSON.stringify({ error: { message: "domain '" + hostname + "' has no token '" + token + "'." } }));
+    res.statusCode = 404;
+    res.setHeader("Content-Type", "application/json; charset=utf-8");
+    res.end(JSON.stringify({ error: { message: "domain '" + hostname + "' has no token '" + token + "'." } }));
 }
 
 function explainError(gl, err, ctx, hostname) {
-	if (!err.servername) {
-		err.servername = hostname;
-	}
-	if (!err.context) {
-		err.context = ctx;
-	}
-	(gl.notify || gl._notify)("error", err);
-	return err;
+    if (!err.servername) {
+        err.servername = hostname;
+    }
+    if (!err.context) {
+        err.context = ctx;
+    }
+    (gl.notify || gl._notify)("error", err);
+    return err;
 }
 
 function respondToError(gl, res, err, ctx, hostname) {
-	err = explainError(gl, err, ctx, hostname);
-	res.statusCode = 500;
-	res.end("Internal Server Error: See logs for details.");
+    err = explainError(gl, err, ctx, hostname);
+    res.statusCode = 500;
+    res.end("Internal Server Error: See logs for details.");
 }
 
 HttpMiddleware.getHostname = function(req) {
-	return req.hostname || req.headers["x-forwarded-host"] || (req.headers.host || "");
+    return req.hostname || req.headers["x-forwarded-host"] || (req.headers.host || "");
 };
 HttpMiddleware.sanitizeHostname = function(req) {
-	// we can trust XFH because spoofing causes no ham in this limited use-case scenario
-	// (and only telebit would be legitimately setting XFH)
-	var servername = HttpMiddleware.getHostname(req)
-		.toLowerCase()
-		.replace(/:.*/, "");
-	try {
-		req.hostname = servername;
-	} catch (e) {
-		// read-only express property
-	}
-	if (req.headers["x-forwarded-host"]) {
-		req.headers["x-forwarded-host"] = servername;
-	}
-	try {
-		req.headers.host = servername;
-	} catch (e) {
-		// TODO is this a possible error?
-	}
+    // we can trust XFH because spoofing causes no ham in this limited use-case scenario
+    // (and only telebit would be legitimately setting XFH)
+    var servername = HttpMiddleware.getHostname(req)
+        .toLowerCase()
+        .replace(/:.*/, "");
+    try {
+        req.hostname = servername;
+    } catch (e) {
+        // read-only express property
+    }
+    if (req.headers["x-forwarded-host"]) {
+        req.headers["x-forwarded-host"] = servername;
+    }
+    try {
+        req.headers.host = servername;
+    } catch (e) {
+        // TODO is this a possible error?
+    }
 
-	return (servernameRe.test(servername) && -1 === servername.indexOf("..") && servername) || "";
+    return (servernameRe.test(servername) && -1 === servername.indexOf("..") && servername) || "";
 };
diff --git a/https-middleware.js b/https-middleware.js
index 80be005..4cd404b 100644
--- a/https-middleware.js
+++ b/https-middleware.js
@@ -4,56 +4,56 @@ var SanitizeHost = module.exports;
 var HttpMiddleware = require("./http-middleware.js");
 
 SanitizeHost.create = function(gl, app) {
-	return function(req, res, next) {
-		function realNext() {
-			if ("function" === typeof app) {
-				app(req, res);
-			} else if ("function" === typeof next) {
-				next();
-			} else {
-				res.statusCode = 500;
-				res.end("Error: no middleware assigned");
-			}
-		}
+    return function(req, res, next) {
+        function realNext() {
+            if ("function" === typeof app) {
+                app(req, res);
+            } else if ("function" === typeof next) {
+                next();
+            } else {
+                res.statusCode = 500;
+                res.end("Error: no middleware assigned");
+            }
+        }
 
-		var hostname = HttpMiddleware.getHostname(req);
-		// Replace the hostname, and get the safe version
-		var safehost = HttpMiddleware.sanitizeHostname(req);
+        var hostname = HttpMiddleware.getHostname(req);
+        // Replace the hostname, and get the safe version
+        var safehost = HttpMiddleware.sanitizeHostname(req);
 
-		// if no hostname, move along
-		if (!hostname) {
-			realNext();
-			return;
-		}
+        // if no hostname, move along
+        if (!hostname) {
+            realNext();
+            return;
+        }
 
-		// if there were unallowed characters, complain
-		if (safehost.length !== hostname.length) {
-			res.statusCode = 400;
-			res.end("Malformed HTTP Header: 'Host: " + hostname + "'");
-			return;
-		}
+        // if there were unallowed characters, complain
+        if (safehost.length !== hostname.length) {
+            res.statusCode = 400;
+            res.end("Malformed HTTP Header: 'Host: " + hostname + "'");
+            return;
+        }
 
-		// Note: This sanitize function is also called on plain sockets, which don't need Domain Fronting checks
-		if (req.socket.encrypted) {
-			if (req.socket && "string" === typeof req.socket.servername) {
-				// Workaround for https://github.com/nodejs/node/issues/22389
-				if (!SanitizeHost._checkServername(safehost, req.socket)) {
-					res.statusCode = 400;
-					res.setHeader("Content-Type", "text/html; charset=utf-8");
-					res.end(
-						"Domain Fronting Error
" +
-							"This connection was secured using TLS/SSL for '" +
-							(req.socket.servername || "").toLowerCase() +
-							"'
" +
-							"The HTTP request specified 'Host: " +
-							safehost +
-							"', which is (obviously) different.
" +
-							"Because this looks like a domain fronting attack, the connection has been terminated.
"
-					);
-					return;
-				}
-			}
-			/*
+        // Note: This sanitize function is also called on plain sockets, which don't need Domain Fronting checks
+        if (req.socket.encrypted) {
+            if (req.socket && "string" === typeof req.socket.servername) {
+                // Workaround for https://github.com/nodejs/node/issues/22389
+                if (!SanitizeHost._checkServername(safehost, req.socket)) {
+                    res.statusCode = 400;
+                    res.setHeader("Content-Type", "text/html; charset=utf-8");
+                    res.end(
+                        "Domain Fronting Error
" +
+                            "This connection was secured using TLS/SSL for '" +
+                            (req.socket.servername || "").toLowerCase() +
+                            "'
" +
+                            "The HTTP request specified 'Host: " +
+                            safehost +
+                            "', which is (obviously) different.
" +
+                            "Because this looks like a domain fronting attack, the connection has been terminated.
"
+                    );
+                    return;
+                }
+            }
+            /*
       else if (safehost && !gl._skip_fronting_check) {
 
 				// We used to print a log message here, but it turns out that it's
@@ -66,74 +66,74 @@ SanitizeHost.create = function(gl, app) {
 				//gl._skip_fronting_check = true;
 			}
       */
-		}
+        }
 
-		// carry on
-		realNext();
-	};
+        // carry on
+        realNext();
+    };
 };
 
 var warnDomainFronting = true;
 var warnUnexpectedError = true;
 SanitizeHost._checkServername = function(safeHost, tlsSocket) {
-	var servername = (tlsSocket.servername || "").toLowerCase();
+    var servername = (tlsSocket.servername || "").toLowerCase();
 
-	// acceptable: older IoT devices may lack SNI support
-	if (!servername) {
-		return true;
-	}
-	// acceptable: odd... but acceptable
-	if (!safeHost) {
-		return true;
-	}
-	if (safeHost === servername) {
-		return true;
-	}
+    // acceptable: older IoT devices may lack SNI support
+    if (!servername) {
+        return true;
+    }
+    // acceptable: odd... but acceptable
+    if (!safeHost) {
+        return true;
+    }
+    if (safeHost === servername) {
+        return true;
+    }
 
-	if ("function" !== typeof tlsSocket.getCertificate) {
-		// domain fronting attacks allowed
-		if (warnDomainFronting) {
-			// https://github.com/nodejs/node/issues/24095
-			console.warn(
-				"Warning: node " +
-					process.version +
-					" is vulnerable to domain fronting attacks. Please use node v11.2.0 or greater."
-			);
-			warnDomainFronting = false;
-		}
-		return true;
-	}
+    if ("function" !== typeof tlsSocket.getCertificate) {
+        // domain fronting attacks allowed
+        if (warnDomainFronting) {
+            // https://github.com/nodejs/node/issues/24095
+            console.warn(
+                "Warning: node " +
+                    process.version +
+                    " is vulnerable to domain fronting attacks. Please use node v11.2.0 or greater."
+            );
+            warnDomainFronting = false;
+        }
+        return true;
+    }
 
-	// connection established with servername and session is re-used for allowed name
-	// See https://github.com/nodejs/node/issues/24095
-	var cert = tlsSocket.getCertificate();
-	try {
-		// TODO optimize / cache?
-		// *should* always have a string, right?
-		// *should* always be lowercase already, right?
-		//console.log(safeHost, cert.subject.CN, cert.subjectaltname);
-		var isSubject = (cert.subject.CN || "").toLowerCase() === safeHost;
-		if (isSubject) {
-			return true;
-		}
+    // connection established with servername and session is re-used for allowed name
+    // See https://github.com/nodejs/node/issues/24095
+    var cert = tlsSocket.getCertificate();
+    try {
+        // TODO optimize / cache?
+        // *should* always have a string, right?
+        // *should* always be lowercase already, right?
+        //console.log(safeHost, cert.subject.CN, cert.subjectaltname);
+        var isSubject = (cert.subject.CN || "").toLowerCase() === safeHost;
+        if (isSubject) {
+            return true;
+        }
 
-		var dnsnames = (cert.subjectaltname || "").split(/,\s+/);
-		var inSanList = dnsnames.some(function(name) {
-			// always prefixed with "DNS:"
-			return safeHost === name.slice(4).toLowerCase();
-		});
+        var dnsnames = (cert.subjectaltname || "").split(/,\s+/);
+        var inSanList = dnsnames.some(function(name) {
+            // always prefixed with "DNS:"
+            return safeHost === name.slice(4).toLowerCase();
+        });
 
-		if (inSanList) {
-			return true;
-		}
-	} catch (e) {
-		// not sure what else to do in this situation...
-		if (warnUnexpectedError) {
-			console.warn("Warning: encoutered error while performing domain fronting check: " + e.message);
-			warnUnexpectedError = false;
-		}
-		return true;
-	}
+        if (inSanList) {
+            return true;
+        }
+    } catch (e) {
+        // not sure what else to do in this situation...
+        if (warnUnexpectedError) {
+            console.warn("Warning: encoutered error while performing domain fronting check: " + e.message);
+            warnUnexpectedError = false;
+        }
+        return true;
+    }
 
-	return false;
+    return false;
 };
diff --git a/lib/compat.js b/lib/compat.js
index 3e5e7bc..59f95dc 100644
--- a/lib/compat.js
+++ b/lib/compat.js
@@ -1,37 +1,37 @@
 "use strict";
 
 function requireBluebird() {
-	try {
-		return require("bluebird");
-	} catch (e) {
-		console.error("");
-		console.error("DON'T PANIC. You're running an old version of node with incomplete Promise support.");
-		console.error("EASY FIX: `npm install --save bluebird`");
-		console.error("");
-		throw e;
-	}
+    try {
+        return require("bluebird");
+    } catch (e) {
+        console.error("");
+        console.error("DON'T PANIC. You're running an old version of node with incomplete Promise support.");
+        console.error("EASY FIX: `npm install --save bluebird`");
+        console.error("");
+        throw e;
+    }
 }
 
 if ("undefined" === typeof Promise) {
-	global.Promise = requireBluebird();
+    global.Promise = requireBluebird();
 }
 
 if ("function" !== typeof require("util").promisify) {
-	require("util").promisify = requireBluebird().promisify;
+    require("util").promisify = requireBluebird().promisify;
 }
 
 if (!console.debug) {
-	console.debug = console.log;
+    console.debug = console.log;
 }
 
 var fs = require("fs");
 var fsAsync = {};
 Object.keys(fs).forEach(function(key) {
-	var fn = fs[key];
-	if ("function" !== typeof fn || !/[a-z]/.test(key[0])) {
-		return;
-	}
-	fsAsync[key] = require("util").promisify(fn);
+    var fn = fs[key];
+    if ("function" !== typeof fn || !/[a-z]/.test(key[0])) {
+        return;
+    }
+    fsAsync[key] = require("util").promisify(fn);
 });
 
 exports.fsAsync = fsAsync;
diff --git a/main.js b/main.js
index 1e3c309..1a15447 100644
--- a/main.js
+++ b/main.js
@@ -13,20 +13,20 @@ _hasSetSecureContext = !!require("https").createServer({}, function() {}).setSec
 
 // TODO document in issues
 if (!_hasSetSecureContext) {
-	// TODO this isn't necessary if greenlock options are set with options.cert
-	console.warn("Warning: node " + process.version + " is missing tlsSocket.setSecureContext().");
-	console.warn("         The default certificate may not be set.");
-	shouldUpgrade = true;
+    // TODO this isn't necessary if greenlock options are set with options.cert
+    console.warn("Warning: node " + process.version + " is missing tlsSocket.setSecureContext().");
+    console.warn("         The default certificate may not be set.");
+    shouldUpgrade = true;
 }
 
 if (major < 11 || (11 === major && minor < 2)) {
-	// https://github.com/nodejs/node/issues/24095
-	console.warn("Warning: node " + process.version + " is missing tlsSocket.getCertificate().");
-	console.warn("         This is necessary to guard against domain fronting attacks.");
-	shouldUpgrade = true;
+    // https://github.com/nodejs/node/issues/24095
+    console.warn("Warning: node " + process.version + " is missing tlsSocket.getCertificate().");
+    console.warn("         This is necessary to guard against domain fronting attacks.");
+    shouldUpgrade = true;
 }
 
 if (shouldUpgrade) {
-	console.warn("Warning: Please upgrade to node v11.2.0 or greater.");
-	console.warn();
+    console.warn("Warning: Please upgrade to node v11.2.0 or greater.");
+    console.warn();
 }
diff --git a/master.js b/master.js
index 261f124..871a9a0 100644
--- a/master.js
+++ b/master.js
@@ -9,152 +9,152 @@ var os = require("os");
 var msgPrefix = "greenlock:";
 
 Master.create = function(opts) {
-	var resolveCb;
-	var _readyCb;
-	var _kicked = false;
+    var resolveCb;
+    var _readyCb;
+    var _kicked = false;
 
-	var greenlock = require("./greenlock.js").create(opts);
+    var greenlock = require("./greenlock.js").create(opts);
 
-	var ready = new Promise(function(resolve) {
-		resolveCb = resolve;
-	}).then(function(fn) {
-		_readyCb = fn;
-		return fn;
-	});
+    var ready = new Promise(function(resolve) {
+        resolveCb = resolve;
+    }).then(function(fn) {
+        _readyCb = fn;
+        return fn;
+    });
 
-	function kickoff() {
-		if (_kicked) {
-			return;
-		}
-		_kicked = true;
+    function kickoff() {
+        if (_kicked) {
+            return;
+        }
+        _kicked = true;
 
-		Master._spawnWorkers(opts, greenlock);
+        Master._spawnWorkers(opts, greenlock);
 
-		ready.then(function(fn) {
-			// not sure what this API should be yet
-			fn();
-		});
-	}
+        ready.then(function(fn) {
+            // not sure what this API should be yet
+            fn();
+        });
+    }
 
-	var master = {
-		serve: function() {
-			kickoff();
-			return master;
-		},
-		master: function(fn) {
-			if (_readyCb) {
-				throw new Error("can't call master twice");
-			}
-			kickoff();
-			resolveCb(fn);
-			return master;
-		}
-	};
-	return master;
+    var master = {
+        serve: function() {
+            kickoff();
+            return master;
+        },
+        master: function(fn) {
+            if (_readyCb) {
+                throw new Error("can't call master twice");
+            }
+            kickoff();
+            resolveCb(fn);
+            return master;
+        }
+    };
+    return master;
 };
 
 function range(n) {
-	n = parseInt(n, 10);
-	if (!n) {
-		return [];
-	}
-	return new Array(n).join(",").split(",");
+    n = parseInt(n, 10);
+    if (!n) {
+        return [];
+    }
+    return new Array(n).join(",").split(",");
 }
 
 Master._spawnWorkers = function(opts, greenlock) {
-	var numCpus = parseInt(process.env.NUMBER_OF_PROCESSORS, 10) || os.cpus().length;
+    var numCpus = parseInt(process.env.NUMBER_OF_PROCESSORS, 10) || os.cpus().length;
 
-	// process rpc messages
-	// start when dead
-	var numWorkers = parseInt(opts.workers || opts.numWorkers, 10);
-	if (!numWorkers) {
-		if (numCpus <= 2) {
-			numWorkers = 2;
-		} else {
-			numWorkers = numCpus - 1;
-		}
-	}
+    // process rpc messages
+    // start when dead
+    var numWorkers = parseInt(opts.workers || opts.numWorkers, 10);
+    if (!numWorkers) {
+        if (numCpus <= 2) {
+            numWorkers = 2;
+        } else {
+            numWorkers = numCpus - 1;
+        }
+    }
 
-	cluster.once("exit", function() {
-		setTimeout(function() {
-			process.exit(3);
-		}, 100);
-	});
+    cluster.once("exit", function() {
+        setTimeout(function() {
+            process.exit(3);
+        }, 100);
+    });
 
-	var workers = range(numWorkers);
-	function next() {
-		if (!workers.length) {
-			return;
-		}
-		workers.pop();
+    var workers = range(numWorkers);
+    function next() {
+        if (!workers.length) {
+            return;
+        }
+        workers.pop();
 
-		// for a nice aesthetic
-		setTimeout(function() {
-			Master._spawnWorker(opts, greenlock);
-			next();
-		}, 250);
-	}
+        // for a nice aesthetic
+        setTimeout(function() {
+            Master._spawnWorker(opts, greenlock);
+            next();
+        }, 250);
+    }
 
-	next();
+    next();
 };
 
 Master._spawnWorker = function(opts, greenlock) {
-	var w = cluster.fork();
-	// automatically added to master's `cluster.workers`
-	w.once("exit", function(code, signal) {
-		// TODO handle failures
-		// Should test if the first starts successfully
-		// Should exit if failures happen too quickly
+    var w = cluster.fork();
+    // automatically added to master's `cluster.workers`
+    w.once("exit", function(code, signal) {
+        // TODO handle failures
+        // Should test if the first starts successfully
+        // Should exit if failures happen too quickly
 
-		// For now just kill all when any die
-		if (signal) {
-			console.error("worker was killed by signal:", signal);
-		} else if (code !== 0) {
-			console.error("worker exited with error code:", code);
-		} else {
-			console.error("worker unexpectedly quit without exit code or signal");
-		}
-		process.exit(2);
+        // For now just kill all when any die
+        if (signal) {
+            console.error("worker was killed by signal:", signal);
+        } else if (code !== 0) {
+            console.error("worker exited with error code:", code);
+        } else {
+            console.error("worker unexpectedly quit without exit code or signal");
+        }
+        process.exit(2);
 
-		//addWorker();
-	});
+        //addWorker();
+    });
 
-	function handleMessage(msg) {
-		if (0 !== (msg._id || "").indexOf(msgPrefix)) {
-			return;
-		}
-		if ("string" !== typeof msg._funcname) {
-			// TODO developer error
-			return;
-		}
+    function handleMessage(msg) {
+        if (0 !== (msg._id || "").indexOf(msgPrefix)) {
+            return;
+        }
+        if ("string" !== typeof msg._funcname) {
+            // TODO developer error
+            return;
+        }
 
-		function rpc() {
-			return greenlock[msg._funcname](msg._input)
-				.then(function(result) {
-					w.send({
-						_id: msg._id,
-						_result: result
-					});
-				})
-				.catch(function(e) {
-					var error = new Error(e.message);
-					Object.getOwnPropertyNames(e).forEach(function(k) {
-						error[k] = e[k];
-					});
-					w.send({
-						_id: msg._id,
-						_error: error
-					});
-				});
-		}
+        function rpc() {
+            return greenlock[msg._funcname](msg._input)
+                .then(function(result) {
+                    w.send({
+                        _id: msg._id,
+                        _result: result
+                    });
+                })
+                .catch(function(e) {
+                    var error = new Error(e.message);
+                    Object.getOwnPropertyNames(e).forEach(function(k) {
+                        error[k] = e[k];
+                    });
+                    w.send({
+                        _id: msg._id,
+                        _error: error
+                    });
+                });
+        }
 
-		try {
-			rpc();
-		} catch (e) {
-			console.error("Unexpected and uncaught greenlock." + msg._funcname + " error:");
-			console.error(e);
-		}
-	}
+        try {
+            rpc();
+        } catch (e) {
+            console.error("Unexpected and uncaught greenlock." + msg._funcname + " error:");
+            console.error(e);
+        }
+    }
 
-	w.on("message", handleMessage);
+    w.on("message", handleMessage);
 };
diff --git a/package-lock.json b/package-lock.json
index 5bc06a1..9c5b852 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,140 +1,140 @@
 {
-	"name": "@root/greenlock-express",
-	"version": "3.0.11",
-	"lockfileVersion": 1,
-	"requires": true,
-	"dependencies": {
-		"@root/acme": {
-			"version": "3.0.8",
-			"resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.8.tgz",
-			"integrity": "sha512-VmBvLvWdCDkolkanI9Dzm1ouSWPaAa2eCCwcDZcVQbWoNiUIOqbbd57fcMA/gZxLyuJPStD2WXFuEuSMPDxcww==",
-			"requires": {
-				"@root/encoding": "^1.0.1",
-				"@root/keypairs": "^0.9.0",
-				"@root/pem": "^1.0.4",
-				"@root/request": "^1.3.11",
-				"@root/x509": "^0.7.2"
-			}
-		},
-		"@root/asn1": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz",
-			"integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==",
-			"requires": {
-				"@root/encoding": "^1.0.1"
-			}
-		},
-		"@root/csr": {
-			"version": "0.8.1",
-			"resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz",
-			"integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==",
-			"requires": {
-				"@root/asn1": "^1.0.0",
-				"@root/pem": "^1.0.4",
-				"@root/x509": "^0.7.2"
-			}
-		},
-		"@root/encoding": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz",
-			"integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ=="
-		},
-		"@root/greenlock": {
-			"version": "3.0.25",
-			"resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-3.0.25.tgz",
-			"integrity": "sha512-VC8H9MTkbqxlB2LGntmcq5cstkE0TdZLvxm25SO5i7c6abJBVMQafhTD415OXwoGimnmWTn6SZ93Fj73d9QX/w==",
-			"requires": {
-				"@root/acme": "^3.0.8",
-				"@root/csr": "^0.8.1",
-				"@root/keypairs": "^0.9.0",
-				"@root/mkdirp": "^1.0.0",
-				"@root/request": "^1.3.10",
-				"acme-http-01-standalone": "^3.0.5",
-				"cert-info": "^1.5.1",
-				"greenlock-manager-fs": "^3.0.1",
-				"greenlock-store-fs": "^3.2.0",
-				"safe-replace": "^1.1.0"
-			}
-		},
-		"@root/keypairs": {
-			"version": "0.9.0",
-			"resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz",
-			"integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==",
-			"requires": {
-				"@root/encoding": "^1.0.1",
-				"@root/pem": "^1.0.4",
-				"@root/x509": "^0.7.2"
-			}
-		},
-		"@root/mkdirp": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
-			"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
-		},
-		"@root/pem": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz",
-			"integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA=="
-		},
-		"@root/request": {
-			"version": "1.4.2",
-			"resolved": "https://registry.npmjs.org/@root/request/-/request-1.4.2.tgz",
-			"integrity": "sha512-J8FM4+SJuc7WRC+Jz17m+VT2lgI7HtatHhxN1F2ck5aIKUAxJEaR4u/gLBsgT60mVHevKCjKN0O8115UtJjwLw=="
-		},
-		"@root/x509": {
-			"version": "0.7.2",
-			"resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz",
-			"integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==",
-			"requires": {
-				"@root/asn1": "^1.0.0",
-				"@root/encoding": "^1.0.1"
-			}
-		},
-		"acme-http-01-standalone": {
-			"version": "3.0.5",
-			"resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz",
-			"integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg=="
-		},
-		"cert-info": {
-			"version": "1.5.1",
-			"resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz",
-			"integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ=="
-		},
-		"escape-html": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-			"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
-		},
-		"greenlock-manager-fs": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.0.1.tgz",
-			"integrity": "sha512-vZfGFq1TTKxaAqdGDUwNservrNzXx0xCwT/ovG/N378GrhS+U5S8B8LUlNtQU7Fdw6RToMiBcm22OOxSrvZ2zw==",
-			"requires": {
-				"@root/mkdirp": "^1.0.0",
-				"safe-replace": "^1.1.0"
-			}
-		},
-		"greenlock-store-fs": {
-			"version": "3.2.0",
-			"resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.0.tgz",
-			"integrity": "sha512-zqcPnF+173oYq5qU7FoGtuqeG8dmmvAiSnz98kEHAHyvgRF9pE1T0MM0AuqDdj45I3kXlCj2gZBwutnRi37J3g==",
-			"requires": {
-				"@root/mkdirp": "^1.0.0",
-				"safe-replace": "^1.1.0"
-			}
-		},
-		"redirect-https": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/redirect-https/-/redirect-https-1.3.0.tgz",
-			"integrity": "sha512-9GzwI/+Cqw3jlSg0CW6TgBQbhiVhkHSDvW8wjgRQ9IK34wtxS71YJiQeazSCSEqbvowHCJuQZgmQFl1xUHKEgg==",
-			"requires": {
-				"escape-html": "^1.0.3"
-			}
-		},
-		"safe-replace": {
-			"version": "1.1.0",
-			"resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz",
-			"integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw=="
-		}
-	}
+    "name": "@root/greenlock-express",
+    "version": "3.0.13",
+    "lockfileVersion": 1,
+    "requires": true,
+    "dependencies": {
+        "@root/acme": {
+            "version": "3.0.8",
+            "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.8.tgz",
+            "integrity": "sha512-VmBvLvWdCDkolkanI9Dzm1ouSWPaAa2eCCwcDZcVQbWoNiUIOqbbd57fcMA/gZxLyuJPStD2WXFuEuSMPDxcww==",
+            "requires": {
+                "@root/encoding": "^1.0.1",
+                "@root/keypairs": "^0.9.0",
+                "@root/pem": "^1.0.4",
+                "@root/request": "^1.3.11",
+                "@root/x509": "^0.7.2"
+            }
+        },
+        "@root/asn1": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz",
+            "integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==",
+            "requires": {
+                "@root/encoding": "^1.0.1"
+            }
+        },
+        "@root/csr": {
+            "version": "0.8.1",
+            "resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz",
+            "integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==",
+            "requires": {
+                "@root/asn1": "^1.0.0",
+                "@root/pem": "^1.0.4",
+                "@root/x509": "^0.7.2"
+            }
+        },
+        "@root/encoding": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz",
+            "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ=="
+        },
+        "@root/greenlock": {
+            "version": "3.0.25",
+            "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-3.0.25.tgz",
+            "integrity": "sha512-VC8H9MTkbqxlB2LGntmcq5cstkE0TdZLvxm25SO5i7c6abJBVMQafhTD415OXwoGimnmWTn6SZ93Fj73d9QX/w==",
+            "requires": {
+                "@root/acme": "^3.0.8",
+                "@root/csr": "^0.8.1",
+                "@root/keypairs": "^0.9.0",
+                "@root/mkdirp": "^1.0.0",
+                "@root/request": "^1.3.10",
+                "acme-http-01-standalone": "^3.0.5",
+                "cert-info": "^1.5.1",
+                "greenlock-manager-fs": "^3.0.1",
+                "greenlock-store-fs": "^3.2.0",
+                "safe-replace": "^1.1.0"
+            }
+        },
+        "@root/keypairs": {
+            "version": "0.9.0",
+            "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz",
+            "integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==",
+            "requires": {
+                "@root/encoding": "^1.0.1",
+                "@root/pem": "^1.0.4",
+                "@root/x509": "^0.7.2"
+            }
+        },
+        "@root/mkdirp": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
+            "integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
+        },
+        "@root/pem": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz",
+            "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA=="
+        },
+        "@root/request": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/@root/request/-/request-1.4.2.tgz",
+            "integrity": "sha512-J8FM4+SJuc7WRC+Jz17m+VT2lgI7HtatHhxN1F2ck5aIKUAxJEaR4u/gLBsgT60mVHevKCjKN0O8115UtJjwLw=="
+        },
+        "@root/x509": {
+            "version": "0.7.2",
+            "resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz",
+            "integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==",
+            "requires": {
+                "@root/asn1": "^1.0.0",
+                "@root/encoding": "^1.0.1"
+            }
+        },
+        "acme-http-01-standalone": {
+            "version": "3.0.5",
+            "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz",
+            "integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg=="
+        },
+        "cert-info": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz",
+            "integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ=="
+        },
+        "escape-html": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+            "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+        },
+        "greenlock-manager-fs": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.0.1.tgz",
+            "integrity": "sha512-vZfGFq1TTKxaAqdGDUwNservrNzXx0xCwT/ovG/N378GrhS+U5S8B8LUlNtQU7Fdw6RToMiBcm22OOxSrvZ2zw==",
+            "requires": {
+                "@root/mkdirp": "^1.0.0",
+                "safe-replace": "^1.1.0"
+            }
+        },
+        "greenlock-store-fs": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.0.tgz",
+            "integrity": "sha512-zqcPnF+173oYq5qU7FoGtuqeG8dmmvAiSnz98kEHAHyvgRF9pE1T0MM0AuqDdj45I3kXlCj2gZBwutnRi37J3g==",
+            "requires": {
+                "@root/mkdirp": "^1.0.0",
+                "safe-replace": "^1.1.0"
+            }
+        },
+        "redirect-https": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/redirect-https/-/redirect-https-1.3.0.tgz",
+            "integrity": "sha512-9GzwI/+Cqw3jlSg0CW6TgBQbhiVhkHSDvW8wjgRQ9IK34wtxS71YJiQeazSCSEqbvowHCJuQZgmQFl1xUHKEgg==",
+            "requires": {
+                "escape-html": "^1.0.3"
+            }
+        },
+        "safe-replace": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz",
+            "integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw=="
+        }
+    }
 }
diff --git a/package.json b/package.json
index ecf89ca..5b00a33 100644
--- a/package.json
+++ b/package.json
@@ -1,51 +1,51 @@
 {
-	"name": "@root/greenlock-express",
-	"version": "3.0.12",
-	"description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.",
-	"main": "greenlock-express.js",
-	"homepage": "https://greenlock.domains",
-	"files": [
-		"*.js",
-		"lib",
-		"scripts"
-	],
-	"scripts": {
-		"start": "node_todo server.js ./config.js",
-		"test": "node_todo test/greenlock.js"
-	},
-	"directories": {
-		"example": "examples"
-	},
-	"dependencies": {
-		"@root/greenlock": "^3.0.25",
-		"redirect-https": "^1.1.5"
-	},
-	"trulyOptionalDependencies": {
-		"http-proxy": "^1.17.0",
-		"express": "^4.16.3",
-		"express-basic-auth": "^1.2.0",
-		"finalhandler": "^1.1.1",
-		"serve-index": "^1.9.1",
-		"serve-static": "^1.13.2",
-		"ws": "^5.2.1"
-	},
-	"devDependencies": {},
-	"repository": {
-		"type": "git",
-		"url": "https://git.rootprojects.org/root/greenlock-express.js.git"
-	},
-	"keywords": [
-		"Let's Encrypt",
-		"ACME",
-		"greenlock",
-		"Free SSL",
-		"Automated HTTPS",
-		"https",
-		"tls"
-	],
-	"author": "AJ ONeal  (https://solderjs.com/)",
-	"license": "MPL-2.0",
-	"bugs": {
-		"url": "https://git.rootprojects.org/root/greenlock-express.js/issues"
-	}
+    "name": "@root/greenlock-express",
+    "version": "3.0.13",
+    "description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.",
+    "main": "greenlock-express.js",
+    "homepage": "https://greenlock.domains",
+    "files": [
+        "*.js",
+        "lib",
+        "scripts"
+    ],
+    "scripts": {
+        "start": "node_todo server.js ./config.js",
+        "test": "node_todo test/greenlock.js"
+    },
+    "directories": {
+        "example": "examples"
+    },
+    "dependencies": {
+        "@root/greenlock": "^3.0.25",
+        "redirect-https": "^1.1.5"
+    },
+    "trulyOptionalDependencies": {
+        "http-proxy": "^1.17.0",
+        "express": "^4.16.3",
+        "express-basic-auth": "^1.2.0",
+        "finalhandler": "^1.1.1",
+        "serve-index": "^1.9.1",
+        "serve-static": "^1.13.2",
+        "ws": "^5.2.1"
+    },
+    "devDependencies": {},
+    "repository": {
+        "type": "git",
+        "url": "https://git.rootprojects.org/root/greenlock-express.js.git"
+    },
+    "keywords": [
+        "Let's Encrypt",
+        "ACME",
+        "greenlock",
+        "Free SSL",
+        "Automated HTTPS",
+        "https",
+        "tls"
+    ],
+    "author": "AJ ONeal  (https://solderjs.com/)",
+    "license": "MPL-2.0",
+    "bugs": {
+        "url": "https://git.rootprojects.org/root/greenlock-express.js/issues"
+    }
 }
diff --git a/servers.js b/servers.js
index fc480e2..e8a06e8 100644
--- a/servers.js
+++ b/servers.js
@@ -9,148 +9,152 @@ var sni = require("./sni.js");
 var cluster = require("cluster");
 
 Servers.create = function(greenlock) {
-	var servers = {};
-	var _httpServer;
-	var _httpsServer;
+    var servers = {};
+    var _httpServer;
+    var _httpsServer;
 
-	function startError(e) {
-		explainError(e);
-		process.exit(1);
-	}
+    function startError(e) {
+        explainError(e);
+        process.exit(1);
+    }
 
-	servers.httpServer = function(defaultApp) {
-		if (_httpServer) {
-			return _httpServer;
-		}
+    servers.httpServer = function(defaultApp) {
+        if (_httpServer) {
+            return _httpServer;
+        }
 
-		_httpServer = http.createServer(HttpMiddleware.create(greenlock, defaultApp));
-		_httpServer.once("error", startError);
+        _httpServer = http.createServer(HttpMiddleware.create(greenlock, defaultApp));
+        _httpServer.once("error", startError);
 
-		return _httpServer;
-	};
+        return _httpServer;
+    };
 
-	var _middlewareApp;
+    var _middlewareApp;
 
-	servers.http2Server = function(secureOpts, defaultApp) {
-		return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
-			secureOpts.allowHTTP1 = true;
-			return require("http2").createSecureServer(secureOpts, fn);
-		});
-	};
-	servers.httpsServer = function(secureOpts, defaultApp) {
-		return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
-			return require("https").createServer(secureOpts, fn);
-		});
-	};
-	servers._httpsServer = function(secureOpts, defaultApp, createSecureServer) {
-		if (defaultApp) {
-			// TODO guard against being set twice?
-			_middlewareApp = defaultApp;
-		}
+    servers.http2Server = function(secureOpts, defaultApp) {
+        return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
+            secureOpts.allowHTTP1 = true;
+            return require("http2").createSecureServer(secureOpts, fn);
+        });
+    };
+    servers.httpsServer = function(secureOpts, defaultApp) {
+        return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
+            return require("https").createServer(secureOpts, fn);
+        });
+    };
+    servers._httpsServer = function(secureOpts, defaultApp, createSecureServer) {
+        if (defaultApp) {
+            // TODO guard against being set twice?
+            _middlewareApp = defaultApp;
+        }
 
-		if (_httpsServer) {
-			if (secureOpts && Object.keys(secureOpts).length) {
-				throw new Error("Call glx.httpsServer(tlsOptions) before calling glx.serveApp(app)");
-			}
-			return _httpsServer;
-		}
+        if (_httpsServer) {
+            if (secureOpts && Object.keys(secureOpts).length) {
+                throw new Error("Call glx.httpsServer(tlsOptions) before calling glx.serveApp(app)");
+            }
+            return _httpsServer;
+        }
 
-		if (!secureOpts) {
-			secureOpts = {};
-		}
+        if (!secureOpts) {
+            secureOpts = {};
+        }
 
-		_httpsServer = createSecureServer(
-			wrapDefaultSniCallback(greenlock, secureOpts),
-			HttpsMiddleware.create(greenlock, function(req, res) {
-				if (!_middlewareApp) {
-					throw new Error("Set app with `glx.serveApp(app)` or `glx.httpsServer(tlsOptions, app)`");
-				}
-				_middlewareApp(req, res);
-			})
-		);
-		_httpsServer.once("error", startError);
+        _httpsServer = createSecureServer(
+            wrapDefaultSniCallback(greenlock, secureOpts),
+            HttpsMiddleware.create(greenlock, function(req, res) {
+                if (!_middlewareApp) {
+                    throw new Error("Set app with `glx.serveApp(app)` or `glx.httpsServer(tlsOptions, app)`");
+                }
+                _middlewareApp(req, res);
+            })
+        );
+        _httpsServer.once("error", startError);
 
-		return _httpsServer;
-	};
+        return _httpsServer;
+    };
 
-	servers.id = function() {
-		return (cluster.isWorker && cluster.worker.id) || "0";
-	};
-	servers.serveApp = function(app) {
-		return new Promise(function(resolve, reject) {
-			if ("function" !== typeof app) {
-				reject(new Error("glx.serveApp(app) expects a node/express app in the format `function (req, res) { ... }`"));
-				return;
-			}
+    servers.id = function() {
+        return (cluster.isWorker && cluster.worker.id) || "0";
+    };
+    servers.serveApp = function(app) {
+        return new Promise(function(resolve, reject) {
+            if ("function" !== typeof app) {
+                reject(
+                    new Error(
+                        "glx.serveApp(app) expects a node/express app in the format `function (req, res) { ... }`"
+                    )
+                );
+                return;
+            }
 
-			var id = cluster.isWorker && cluster.worker.id;
-			var idstr = (id && "#" + id + " ") || "";
-			var plainServer = servers.httpServer(require("redirect-https")());
-			var plainAddr = "0.0.0.0";
-			var plainPort = 80;
-			plainServer.listen(plainPort, plainAddr, function() {
-				console.info(
-					idstr + "Listening on",
-					plainAddr + ":" + plainPort,
-					"for ACME challenges, and redirecting to HTTPS"
-				);
+            var id = cluster.isWorker && cluster.worker.id;
+            var idstr = (id && "#" + id + " ") || "";
+            var plainServer = servers.httpServer(require("redirect-https")());
+            var plainAddr = "0.0.0.0";
+            var plainPort = 80;
+            plainServer.listen(plainPort, plainAddr, function() {
+                console.info(
+                    idstr + "Listening on",
+                    plainAddr + ":" + plainPort,
+                    "for ACME challenges, and redirecting to HTTPS"
+                );
 
-				// TODO fetch greenlock.servername
-				_middlewareApp = app || _middlewareApp;
-				var secureServer = servers.httpsServer(null, app);
-				var secureAddr = "0.0.0.0";
-				var securePort = 443;
-				secureServer.listen(securePort, secureAddr, function() {
-					console.info(idstr + "Listening on", secureAddr + ":" + securePort, "for secure traffic");
+                // TODO fetch greenlock.servername
+                _middlewareApp = app || _middlewareApp;
+                var secureServer = servers.httpsServer(null, app);
+                var secureAddr = "0.0.0.0";
+                var securePort = 443;
+                secureServer.listen(securePort, secureAddr, function() {
+                    console.info(idstr + "Listening on", secureAddr + ":" + securePort, "for secure traffic");
 
-					plainServer.removeListener("error", startError);
-					secureServer.removeListener("error", startError);
-					resolve();
-				});
-			});
-		});
-	};
+                    plainServer.removeListener("error", startError);
+                    secureServer.removeListener("error", startError);
+                    resolve();
+                });
+            });
+        });
+    };
 
-	return servers;
+    return servers;
 };
 
 function explainError(e) {
-	console.error();
-	console.error("Error: " + e.message);
-	if ("EACCES" === e.errno) {
-		console.error("You don't have prmission to access '" + e.address + ":" + e.port + "'.");
-		console.error('You probably need to use "sudo" or "sudo setcap \'cap_net_bind_service=+ep\' $(which node)"');
-	} else if ("EADDRINUSE" === e.errno) {
-		console.error("'" + e.address + ":" + e.port + "' is already being used by some other program.");
-		console.error("You probably need to stop that program or restart your computer.");
-	} else {
-		console.error(e.code + ": '" + e.address + ":" + e.port + "'");
-	}
-	console.error();
+    console.error();
+    console.error("Error: " + e.message);
+    if ("EACCES" === e.errno) {
+        console.error("You don't have prmission to access '" + e.address + ":" + e.port + "'.");
+        console.error('You probably need to use "sudo" or "sudo setcap \'cap_net_bind_service=+ep\' $(which node)"');
+    } else if ("EADDRINUSE" === e.errno) {
+        console.error("'" + e.address + ":" + e.port + "' is already being used by some other program.");
+        console.error("You probably need to stop that program or restart your computer.");
+    } else {
+        console.error(e.code + ": '" + e.address + ":" + e.port + "'");
+    }
+    console.error();
 }
 
 function wrapDefaultSniCallback(greenlock, secureOpts) {
-	// I'm not sure yet if the original SNICallback
-	// should be called before or after, so I'm just
-	// going to delay making that choice until I have the use case
-	/*
+    // I'm not sure yet if the original SNICallback
+    // should be called before or after, so I'm just
+    // going to delay making that choice until I have the use case
+    /*
 		if (!secureOpts.SNICallback) {
 			secureOpts.SNICallback = function(servername, cb) {
 				cb(null, null);
 			};
 		}
   */
-	if (secureOpts.SNICallback) {
-		console.warn();
-		console.warn("[warning] Ignoring the given tlsOptions.SNICallback function.");
-		console.warn();
-		console.warn("          We're very open to implementing support for this,");
-		console.warn("          we just don't understand the use case yet.");
-		console.warn("          Please open an issue to discuss. We'd love to help.");
-		console.warn();
-	}
+    if (secureOpts.SNICallback) {
+        console.warn();
+        console.warn("[warning] Ignoring the given tlsOptions.SNICallback function.");
+        console.warn();
+        console.warn("          We're very open to implementing support for this,");
+        console.warn("          we just don't understand the use case yet.");
+        console.warn("          Please open an issue to discuss. We'd love to help.");
+        console.warn();
+    }
 
-	// TODO greenlock.servername for workers
-	secureOpts.SNICallback = sni.create(greenlock, secureOpts);
-	return secureOpts;
+    // TODO greenlock.servername for workers
+    secureOpts.SNICallback = sni.create(greenlock, secureOpts);
+    return secureOpts;
 }
diff --git a/single.js b/single.js
index 9d529c1..3f7aab9 100644
--- a/single.js
+++ b/single.js
@@ -6,20 +6,20 @@ var Single = module.exports;
 var Servers = require("./servers.js");
 
 Single.create = function(opts) {
-	var greenlock = require("./greenlock.js").create(opts);
+    var greenlock = require("./greenlock.js").create(opts);
 
-	var servers = Servers.create(greenlock);
+    var servers = Servers.create(greenlock);
 
-	var single = {
-		serve: function(fn) {
-			fn(servers);
-			return single;
-		},
-		master: function(/*fn*/) {
-			// ignore
-			//fn(master);
-			return single;
-		}
-	};
-	return single;
+    var single = {
+        serve: function(fn) {
+            fn(servers);
+            return single;
+        },
+        master: function(/*fn*/) {
+            // ignore
+            //fn(master);
+            return single;
+        }
+    };
+    return single;
 };
diff --git a/sni.js b/sni.js
index 069882c..ea79728 100644
--- a/sni.js
+++ b/sni.js
@@ -13,182 +13,182 @@ var smallStagger = Math.round(Math.PI * (30 * 1000));
 
 //secureOpts.SNICallback = sni.create(greenlock, secureOpts);
 sni.create = function(greenlock, secureOpts) {
-	var _cache = {};
-	var defaultServername = greenlock.servername || "";
+    var _cache = {};
+    var defaultServername = greenlock.servername || "";
 
-	if (secureOpts.cert) {
-		// Note: it's fine if greenlock.servername is undefined,
-		// but if the caller wants this to auto-renew, they should define it
-		_cache[defaultServername] = {
-			refreshAt: 0,
-			secureContext: tls.createSecureContext(secureOpts)
-		};
-	}
+    if (secureOpts.cert) {
+        // Note: it's fine if greenlock.servername is undefined,
+        // but if the caller wants this to auto-renew, they should define it
+        _cache[defaultServername] = {
+            refreshAt: 0,
+            secureContext: tls.createSecureContext(secureOpts)
+        };
+    }
 
-	return getSecureContext;
+    return getSecureContext;
 
-	function notify(ev, args) {
-		try {
-			// TODO _notify() or notify()?
-			(greenlock.notify || greenlock._notify)(ev, args);
-		} catch (e) {
-			console.error(e);
-			console.error(ev, args);
-		}
-	}
+    function notify(ev, args) {
+        try {
+            // TODO _notify() or notify()?
+            (greenlock.notify || greenlock._notify)(ev, args);
+        } catch (e) {
+            console.error(e);
+            console.error(ev, args);
+        }
+    }
 
-	function getSecureContext(servername, cb) {
-		//console.log("debug sni", servername);
-		if ("string" !== typeof servername) {
-			// this will never happen... right? but stranger things have...
-			console.error("[sanity fail] non-string servername:", servername);
-			cb(new Error("invalid servername"), null);
-			return;
-		}
+    function getSecureContext(servername, cb) {
+        //console.log("debug sni", servername);
+        if ("string" !== typeof servername) {
+            // this will never happen... right? but stranger things have...
+            console.error("[sanity fail] non-string servername:", servername);
+            cb(new Error("invalid servername"), null);
+            return;
+        }
 
-		var secureContext = getCachedContext(servername);
-		if (secureContext) {
-			//console.log("debug sni got cached context", servername, getCachedMeta(servername));
-			cb(null, secureContext);
-			return;
-		}
+        var secureContext = getCachedContext(servername);
+        if (secureContext) {
+            //console.log("debug sni got cached context", servername, getCachedMeta(servername));
+            cb(null, secureContext);
+            return;
+        }
 
-		getFreshContext(servername)
-			.then(function(secureContext) {
-				if (secureContext) {
-					//console.log("debug sni got fresh context", servername, getCachedMeta(servername));
-					cb(null, secureContext);
-					return;
-				}
-				// Note: this does not replace tlsSocket.setSecureContext()
-				// as it only works when SNI has been sent
-				//console.log("debug sni got default context", servername, getCachedMeta(servername));
-				cb(null, getDefaultContext());
-			})
-			.catch(function(err) {
-				if (!err.context) {
-					err.context = "sni_callback";
-				}
-				notify("error", err);
-				//console.log("debug sni error", servername, err);
-				cb(err);
-			});
-	}
+        getFreshContext(servername)
+            .then(function(secureContext) {
+                if (secureContext) {
+                    //console.log("debug sni got fresh context", servername, getCachedMeta(servername));
+                    cb(null, secureContext);
+                    return;
+                }
+                // Note: this does not replace tlsSocket.setSecureContext()
+                // as it only works when SNI has been sent
+                //console.log("debug sni got default context", servername, getCachedMeta(servername));
+                cb(null, getDefaultContext());
+            })
+            .catch(function(err) {
+                if (!err.context) {
+                    err.context = "sni_callback";
+                }
+                notify("error", err);
+                //console.log("debug sni error", servername, err);
+                cb(err);
+            });
+    }
 
-	function getCachedMeta(servername) {
-		var meta = _cache[servername];
-		if (!meta) {
-			if (!_cache[wildname(servername)]) {
-				return null;
-			}
-		}
-		return meta;
-	}
+    function getCachedMeta(servername) {
+        var meta = _cache[servername];
+        if (!meta) {
+            if (!_cache[wildname(servername)]) {
+                return null;
+            }
+        }
+        return meta;
+    }
 
-	function getCachedContext(servername) {
-		var meta = getCachedMeta(servername);
-		if (!meta) {
-			return null;
-		}
+    function getCachedContext(servername) {
+        var meta = getCachedMeta(servername);
+        if (!meta) {
+            return null;
+        }
 
-		// always renew in background
-		if (!meta.refreshAt || Date.now() >= meta.refreshAt) {
-			getFreshContext(servername).catch(function(e) {
-				if (!e.context) {
-					e.context = "sni_background_refresh";
-				}
-				notify("error", e);
-			});
-		}
+        // always renew in background
+        if (!meta.refreshAt || Date.now() >= meta.refreshAt) {
+            getFreshContext(servername).catch(function(e) {
+                if (!e.context) {
+                    e.context = "sni_background_refresh";
+                }
+                notify("error", e);
+            });
+        }
 
-		// under normal circumstances this would never be expired
-		// and, if it is expired, something is so wrong it's probably
-		// not worth wating for the renewal - it has probably failed
-		return meta.secureContext;
-	}
+        // under normal circumstances this would never be expired
+        // and, if it is expired, something is so wrong it's probably
+        // not worth wating for the renewal - it has probably failed
+        return meta.secureContext;
+    }
 
-	function getFreshContext(servername) {
-		var meta = getCachedMeta(servername);
-		if (!meta && !validServername(servername)) {
-			return Promise.resolve(null);
-		}
+    function getFreshContext(servername) {
+        var meta = getCachedMeta(servername);
+        if (!meta && !validServername(servername)) {
+            return Promise.resolve(null);
+        }
 
-		if (meta) {
-			// prevent stampedes
-			meta.refreshAt = Date.now() + randomRefreshOffset();
-		}
+        if (meta) {
+            // prevent stampedes
+            meta.refreshAt = Date.now() + randomRefreshOffset();
+        }
 
-		// TODO don't get unknown certs at all, rely on auto-updates from greenlock
-		// Note: greenlock.get() will return an existing fresh cert or issue a new one
-		return greenlock.get({ servername: servername }).then(function(result) {
-			var meta = getCachedMeta(servername);
-			if (!meta) {
-				meta = _cache[servername] = { secureContext: { _valid: false } };
-			}
-			// prevent from being punked by bot trolls
-			meta.refreshAt = Date.now() + smallStagger;
+        // TODO don't get unknown certs at all, rely on auto-updates from greenlock
+        // Note: greenlock.get() will return an existing fresh cert or issue a new one
+        return greenlock.get({ servername: servername }).then(function(result) {
+            var meta = getCachedMeta(servername);
+            if (!meta) {
+                meta = _cache[servername] = { secureContext: { _valid: false } };
+            }
+            // prevent from being punked by bot trolls
+            meta.refreshAt = Date.now() + smallStagger;
 
-			// nothing to do
-			if (!result) {
-				return null;
-			}
+            // nothing to do
+            if (!result) {
+                return null;
+            }
 
-			// we only care about the first one
-			var pems = result.pems;
-			var site = result.site;
-			if (!pems || !pems.cert) {
-				// nothing to do
-				// (and the error should have been reported already)
-				return null;
-			}
+            // we only care about the first one
+            var pems = result.pems;
+            var site = result.site;
+            if (!pems || !pems.cert) {
+                // nothing to do
+                // (and the error should have been reported already)
+                return null;
+            }
 
-			meta = {
-				refreshAt: Date.now() + randomRefreshOffset(),
-				secureContext: tls.createSecureContext({
-					// TODO support passphrase-protected privkeys
-					key: pems.privkey,
-					cert: pems.cert + "\n" + pems.chain + "\n"
-				})
-			};
-			meta.secureContext._valid = true;
+            meta = {
+                refreshAt: Date.now() + randomRefreshOffset(),
+                secureContext: tls.createSecureContext({
+                    // TODO support passphrase-protected privkeys
+                    key: pems.privkey,
+                    cert: pems.cert + "\n" + pems.chain + "\n"
+                })
+            };
+            meta.secureContext._valid = true;
 
-			// copy this same object into every place
-			(result.altnames || site.altnames || [result.subject || site.subject]).forEach(function(altname) {
-				_cache[altname] = meta;
-			});
+            // copy this same object into every place
+            (result.altnames || site.altnames || [result.subject || site.subject]).forEach(function(altname) {
+                _cache[altname] = meta;
+            });
 
-			return meta.secureContext;
-		});
-	}
+            return meta.secureContext;
+        });
+    }
 
-	function getDefaultContext() {
-		return getCachedContext(defaultServername);
-	}
+    function getDefaultContext() {
+        return getCachedContext(defaultServername);
+    }
 };
 
 // whenever we need to know when to refresh next
 function randomRefreshOffset() {
-	var stagger = Math.round(refreshStagger / 2) - Math.round(Math.random() * refreshStagger);
-	return refreshOffset + stagger;
+    var stagger = Math.round(refreshStagger / 2) - Math.round(Math.random() * refreshStagger);
+    return refreshOffset + stagger;
 }
 
 function validServername(servername) {
-	// format and (lightly) sanitize sni so that users can be naive
-	// and not have to worry about SQL injection or fs discovery
+    // format and (lightly) sanitize sni so that users can be naive
+    // and not have to worry about SQL injection or fs discovery
 
-	servername = (servername || "").toLowerCase();
-	// hostname labels allow a-z, 0-9, -, and are separated by dots
-	// _ is sometimes allowed, but not as a "hostname", and not by Let's Encrypt ACME
-	// REGEX // https://www.codeproject.com/Questions/1063023/alphanumeric-validation-javascript-without-regex
-	return servernameRe.test(servername) && -1 === servername.indexOf("..");
+    servername = (servername || "").toLowerCase();
+    // hostname labels allow a-z, 0-9, -, and are separated by dots
+    // _ is sometimes allowed, but not as a "hostname", and not by Let's Encrypt ACME
+    // REGEX // https://www.codeproject.com/Questions/1063023/alphanumeric-validation-javascript-without-regex
+    return servernameRe.test(servername) && -1 === servername.indexOf("..");
 }
 
 function wildname(servername) {
-	return (
-		"*." +
-		servername
-			.split(".")
-			.slice(1)
-			.join(".")
-	);
+    return (
+        "*." +
+        servername
+            .split(".")
+            .slice(1)
+            .join(".")
+    );
 }
diff --git a/test/greenlock.js b/test/greenlock.js
index b2908ee..1f4861c 100644
--- a/test/greenlock.js
+++ b/test/greenlock.js
@@ -1,83 +1,83 @@
 #!/usr/bin/env node
 var Greenlock = require("../");
 var greenlock = Greenlock.create({
-	version: "draft-11",
-	server: "https://acme-staging-v02.api.letsencrypt.org/directory",
-	agreeTos: true,
-	approvedDomains: ["example.com", "www.example.com"],
-	configDir: require("path").join(require("os").tmpdir(), "acme"),
+    version: "draft-11",
+    server: "https://acme-staging-v02.api.letsencrypt.org/directory",
+    agreeTos: true,
+    approvedDomains: ["example.com", "www.example.com"],
+    configDir: require("path").join(require("os").tmpdir(), "acme"),
 
-	app: require("express")().use("/", function(req, res) {
-		res.setHeader("Content-Type", "text/html; charset=utf-8");
-		res.end("Hello, World!\n\nš š.js");
-	})
+    app: require("express")().use("/", function(req, res) {
+        res.setHeader("Content-Type", "text/html; charset=utf-8");
+        res.end("Hello, World!\n\nš š.js");
+    })
 });
 
 var server1 = greenlock.listen(5080, 5443);
 server1.on("listening", function() {
-	console.log("### THREE 3333 - All is well server1", this.address());
-	setTimeout(function() {
-		// so that the address() object doesn't disappear
-		server1.close();
-		server1.unencrypted.close();
-	}, 10);
+    console.log("### THREE 3333 - All is well server1", this.address());
+    setTimeout(function() {
+        // so that the address() object doesn't disappear
+        server1.close();
+        server1.unencrypted.close();
+    }, 10);
 });
 setTimeout(function() {
-	var server2 = greenlock.listen(6080, 6443, function() {
-		console.log("### FIVE 55555 - Started server 2!");
-		setTimeout(function() {
-			server2.close();
-			server2.unencrypted.close();
-			server6.close();
-			server6.unencrypted.close();
-			server7.close();
-			server7.unencrypted.close();
-			setTimeout(function() {
-				// TODO greenlock needs a close event (and to listen to its server's close event)
-				process.exit(0);
-			}, 1000);
-		}, 1000);
-	});
-	server2.on("listening", function() {
-		console.log("### FOUR 44444 - All is well server2", server2.address());
-	});
+    var server2 = greenlock.listen(6080, 6443, function() {
+        console.log("### FIVE 55555 - Started server 2!");
+        setTimeout(function() {
+            server2.close();
+            server2.unencrypted.close();
+            server6.close();
+            server6.unencrypted.close();
+            server7.close();
+            server7.unencrypted.close();
+            setTimeout(function() {
+                // TODO greenlock needs a close event (and to listen to its server's close event)
+                process.exit(0);
+            }, 1000);
+        }, 1000);
+    });
+    server2.on("listening", function() {
+        console.log("### FOUR 44444 - All is well server2", server2.address());
+    });
 }, 1000);
 
 var server3 = greenlock.listen(
-	22,
-	22,
-	function() {
-		console.error("Error: expected to get an error when launching plain server on port 22");
-	},
-	function() {
-		console.error("Error: expected to get an error when launching " + server3.type + " server on port 22");
-	}
+    22,
+    22,
+    function() {
+        console.error("Error: expected to get an error when launching plain server on port 22");
+    },
+    function() {
+        console.error("Error: expected to get an error when launching " + server3.type + " server on port 22");
+    }
 );
 server3.unencrypted.on("error", function() {
-	console.log("Success: caught expected (plain) error");
+    console.log("Success: caught expected (plain) error");
 });
 server3.on("error", function() {
-	console.log("Success: caught expected " + server3.type + " error");
-	//server3.close();
+    console.log("Success: caught expected " + server3.type + " error");
+    //server3.close();
 });
 
 var server4 = greenlock.listen(
-	7080,
-	7443,
-	function() {
-		console.log("Success: server4: plain");
-		server4.unencrypted.close();
-	},
-	function() {
-		console.log("Success: server4: " + server4.type);
-		server4.close();
-	}
+    7080,
+    7443,
+    function() {
+        console.log("Success: server4: plain");
+        server4.unencrypted.close();
+    },
+    function() {
+        console.log("Success: server4: " + server4.type);
+        server4.close();
+    }
 );
 
 var server5 = greenlock.listen(10080, 10443, function() {
-	console.log("Server 5 with one fn", this.address());
-	server5.close();
-	server5.unencrypted.close();
+    console.log("Server 5 with one fn", this.address());
+    server5.close();
+    server5.unencrypted.close();
 });
 
 var server6 = greenlock.listen("[::]:11080", "[::1]:11443");
diff --git a/worker.js b/worker.js
index 5f6a8fa..1c44bea 100644
--- a/worker.js
+++ b/worker.js
@@ -6,57 +6,57 @@ var messageTimeout = 30 * 1000;
 var msgPrefix = "greenlock:";
 
 Worker.create = function() {
-	var greenlock = {};
-	["getAcmeHttp01ChallengeResponse", "get", "notify"].forEach(function(k) {
-		greenlock[k] = function(args) {
-			return rpc(k, args);
-		};
-	});
+    var greenlock = {};
+    ["getAcmeHttp01ChallengeResponse", "get", "notify"].forEach(function(k) {
+        greenlock[k] = function(args) {
+            return rpc(k, args);
+        };
+    });
 
-	var worker = {
-		serve: function(fn) {
-			var servers = require("./servers.js").create(greenlock);
-			fn(servers);
-			return worker;
-		},
-		master: function() {
-			// ignore
-			return worker;
-		}
-	};
-	return worker;
+    var worker = {
+        serve: function(fn) {
+            var servers = require("./servers.js").create(greenlock);
+            fn(servers);
+            return worker;
+        },
+        master: function() {
+            // ignore
+            return worker;
+        }
+    };
+    return worker;
 };
 
 function rpc(funcname, msg) {
-	return new Promise(function(resolve, reject) {
-		var rnd = Math.random()
-			.toString()
-			.slice(2)
-			.toString(16);
-		var id = msgPrefix + rnd;
-		var timeout;
+    return new Promise(function(resolve, reject) {
+        var rnd = Math.random()
+            .toString()
+            .slice(2)
+            .toString(16);
+        var id = msgPrefix + rnd;
+        var timeout;
 
-		function getResponse(msg) {
-			if (msg._id !== id) {
-				return;
-			}
-			process.removeListener("message", getResponse);
-			clearTimeout(timeout);
-			resolve(msg._result);
-		}
+        function getResponse(msg) {
+            if (msg._id !== id) {
+                return;
+            }
+            process.removeListener("message", getResponse);
+            clearTimeout(timeout);
+            resolve(msg._result);
+        }
 
-		// TODO keep a single listener than just responds
-		// via a collection of callbacks? or leave as is?
-		process.on("message", getResponse);
-		process.send({
-			_id: id,
-			_funcname: funcname,
-			_input: msg
-		});
+        // TODO keep a single listener than just responds
+        // via a collection of callbacks? or leave as is?
+        process.on("message", getResponse);
+        process.send({
+            _id: id,
+            _funcname: funcname,
+            _input: msg
+        });
 
-		timeout = setTimeout(function() {
-			process.removeListener("message", getResponse);
-			reject(new Error("worker rpc request timeout"));
-		}, messageTimeout);
-	});
+        timeout = setTimeout(function() {
+            process.removeListener("message", getResponse);
+            reject(new Error("worker rpc request timeout"));
+        }, messageTimeout);
+    });
 }