Serve your rolled up bundle like webpack-dev-server
@param {ServeOptions|string|string[]} options
322404
function serve (options = { contentBase: '' }) {
  if (Array.isArray(options) || typeof options === 'string') {
    options = { contentBase: options }
  }
  options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase]
  options.host = options.host || 'localhost'
  options.port = options.port || 10001
  options.headers = options.headers || {}
  options.https = options.https || false
  options.openPage = options.openPage || ''
  mime.default_type = 'text/plain'

  const requestListener = (request, response) => {
    // Remove querystring
    const urlPath = decodeURI(request.url.split('?')[0])

    Object.keys(options.headers).forEach((key) => {
      response.setHeader(key, options.headers[key])
    })

    readFileFromContentBase(options.contentBase, urlPath, function (error, content, filePath) {
      if (!error) {
        return found(response, filePath, content)
      }
      if (error.code !== 'ENOENT') {
        response.writeHead(500)
        response.end('500 Internal Server Error' +
          '\n\n' + filePath +
          '\n\n' + Object.values(error).join('\n') +
          '\n\n(rollup-plugin-serve)', 'utf-8')
        return
      }
      if (options.historyApiFallback) {
        var fallbackPath = typeof options.historyApiFallback === 'string' ? options.historyApiFallback : '/index.html'
        readFileFromContentBase(options.contentBase, fallbackPath, function (error, content, filePath) {
          if (error) {
            notFound(response, filePath)
          } else {
            found(response, filePath, content)
          }
        })
      } else {
        notFound(response, filePath)
      }
    })
  }

  // release previous server instance if rollup is reloading configuration in watch mode
  if (server) {
    server.close()
  }

  // If HTTPS options are available, create an HTTPS server
  if (options.https) {
    server = createHttpsServer(options.https, requestListener).listen(options.port, options.host)
  } else {
    server = createServer(requestListener).listen(options.port, options.host)
  }

  closeServerOnTermination(server)

  var running = options.verbose === false

  return {
    name: 'serve',
    generateBundle () {
      if (!running) {
        running = true

        // Log which url to visit
        const url = (options.https ? 'https' : 'http') + '://' + options.host + ':' + options.port
        options.contentBase.forEach(base => {
          console.log(green(url) + ' -> ' + resolve(base))
        })

        // Open browser
        if (options.open) {
          opener(url + options.openPage)
        }
      }
    }
  }
}
438441
function (options, callback) {
    var log = this.log;

    if (this.startMockServerFunc) {
      log('manual mock server startup');
      // app specific test runner does most of the work
      this.startMockServerFunc(options, callback);
    } else if (this.mockServerPlugin) {
      log('using mock server plugin');
      // adapter does most of the work
      var mockServer = this.mockServer = new Hapi.Server(this.mockServerOptions);
      mockServer.connection({ port: this.mocksPort });
      mockServer.register(this.mockServerPlugin, function (err) {
        if (err) {
          log('registered mock server plugin: ' + err.message);
          return callback(err);
        }
        log('registered mock server plugin;  starting mock server');
        mockServer.start(callback);
      });
    } else {
      log('no mock server setup/teardown functions provided *and* no plugin provided... not starting mock server');
      callback();
    }
  }
1094293
function init(options) {
    if (options === void 0) { options = {}; }
    if ('debug' in options) {
        diag.debug.enabled = options.debug;
        Q.longStackSupport = options.debug;
    }
    if ('serverUrl' in options) {
        var myURL = url.parse(options.serverUrl);
        if (!myURL.protocol && !myURL.host) {
            return Q.reject(new Error(options.serverUrl + " is not an accepted Url, please add a Host and a Protocol."));
        }
    }
    _.assignWith(exports.initOptions, cloneServerInitOptions(options), function (left, right) { return _.isUndefined(right) ? left : right; });
    if ('push' in options) {
        exports.initOptions.push = _.cloneDeep(options.push);
    }
    return device.ready;
}
20914
function bundler(options) {
        var allFiles = {};
        var bundles = {};
        var dir = options.src;
        var dest = options.dest;
        var resourcesFile = options.resourceJson;
        var indexBundles = options.indexBundles;
        var titleIndexBnudles = {};
        var traversed_bundles = {}, traversed_files = {}, excluded_bundles = {};
        var resourcesJs = {};
        for (var key in options) {
            resourcesJs[key] = options[key];
        }
        resourcesJs.bundles = bundles;

        function getFiles(packageName, files, bundledFile, includedBundles) {
            if (!traversed_bundles[packageName] && !excluded_bundles[packageName]) {
                traversed_bundles[packageName] = true;
                var bundle = resourcesJs.bundles[packageName];
                if (bundle) {
                    bundle.bundled = bundle.bundled || [];
                    bundle.bundled_html = bundle.bundled_html || [];
                    bundle.in = bundle.in || [];
                    for (var i in bundle.on) {
                        files = getFiles(bundle.on[i], files, bundledFile, includedBundles);
                    }
                    for (var j in bundle.js) {
                        var _file2 = cleanURL(dir + "/" + bundle.js[j]);
                        if (!traversed_files[_file2]) {
                            files.js.push(_file2);
                            traversed_files[_file2] = packageName;
                        }
                    }
                    if (files.js.length > 0) {
                        bundle.bundled.push(bundledFile + ".js");
                    }

                    for (var i in bundle.html) {
                        var _file = cleanURL(dir + "/" + bundle.html[i]);
                        if (!traversed_files[_file]) {
                            files.html.push(_file);
                            traversed_files[_file] = packageName;
                        }
                    }
                    if (files.html.length > 0) {
                        bundle.bundled_html.push(bundledFile + ".html");
                    }

                    includedBundles.push(packageName);
                }
            }
            return files;
        }

        if (TASK_BUNDLIFY || TASK_SCAN) {
            grunt.file.recurse(dir, function(abspath, rootdir, subdir, filename) {
                if (filename === "module.json" && abspath.indexOf(dest) !== 0) {
                    var packageInfo = {};
                    if (grunt.file.exists(subdir + "/.bower.json")) {
                        var bowerJson = grunt.file.readJSON(subdir + "/.bower.json");
                        packageInfo.bowerName = bowerJson.name;
                        packageInfo.bowerVersion = bowerJson.version;
                    }
                    if (grunt.file.exists(subdir + "/composer.json")) {
                        var composerJson = grunt.file.readJSON(subdir + "/composer.json");
                        packageInfo.composerName = composerJson.name;
                        packageInfo.composerVersion = composerJson.version;
                    }
                    var _bundles = grunt.file.readJSON(abspath);
                    var packageName = _bundles.name;
                    if (_bundles.exclude) {
                        for (var i in _bundles.exclude) {
                            excluded_bundles[_bundles.exclude[i]] = true;
                        }
                    }
                    if (packageName !== undefined) {
                        titleIndexBnudles[packageName] = [];
                        for (var bundleName in _bundles) {
                            if ((bundleName === packageName || bundleName.indexOf(packageName + "/") === 0) && !excluded_bundles[bundleName]) {
                                if (bundles[bundleName]) {
                                    console.log("====Duplicate Package", bundleName);
                                } else if (!toIgnore(bundleName)) {
                                    titleIndexBnudles[packageName].push(bundleName);
                                }
                                bundles[bundleName] = { js: [], on: [], css: [], html: [], packageInfo: packageInfo};
                                for (var file_i in _bundles[bundleName].js) {
                                    var js_file = subdir + "/" + _bundles[bundleName].js[file_i];
                                    bundles[bundleName].js.push(js_file);
                                    if (!allFiles[js_file]) {
                                        allFiles[js_file] = js_file;
                                    } else {
                                        console.log("====Duplicate File" + js_file);
                                    }
                                }
                                for (var file_j in _bundles[bundleName].css) {
                                    var css_file = subdir + "/" + _bundles[bundleName].css[file_j];
                                    bundles[bundleName].css.push(css_file);
                                    if (!allFiles[css_file]) {
                                        allFiles[css_file] = css_file;
                                    } else {
                                        console.log("====Duplicate File" + css_file);
                                    }
                                }
                                for (var file_k in _bundles[bundleName].html) {
                                    var html_file = subdir + "/" + _bundles[bundleName].html[file_k];
                                    bundles[bundleName].html.push(html_file);
                                    if (!allFiles[html_file]) {
                                        allFiles[html_file] = html_file;
                                    } else {
                                        console.log("====Duplicate File" + html_file);
                                    }
                                }
                                bundles[bundleName].on = _bundles[bundleName].on || [];
                                console.log("╬═╬ Module.json", abspath);
                                //console.log(bundleName, _bundles[bundleName].on);
                            }
                        }
                    }
                }
            });


            var titleIndexBnudlesNames = Object.keys(titleIndexBnudles);

            if (options.modulize) {
                titleIndexBnudlesNames.map(function(bundName) {
                    if (!bundles[bundName] && !toIgnore(bundName)) {
                        bundles[bundName] = { js: [], on: titleIndexBnudles[bundName], css: [], html: [], packageInfo: {}};
                        console.log("New Package ", bundName, bundles[bundName]);
                    }
                });
            }

            for (var packageKey in excluded_bundles) {
                delete bundles[packageKey];
            }

            var firstIndexBundled = null;

            if (!TASK_SKIP_INIT) {
                var myIndexBnudles = indexBundles;
                if (TASK_BUNDLIFY) {

                    var moreBundles = Object.keys(bundles);

                    if (options.sort) {
                        moreBundles = moreBundles.sort();
                    }

                    if (options.projectPrefix !== undefined) {
                        myIndexBnudles = uniqueArray(myIndexBnudles.concat(titleIndexBnudlesNames.concat(moreBundles).filter(function(bundleName) {
                            return bundleName.indexOf(options.projectPrefix) === 0;
                        })));
                    }

                    myIndexBnudles = uniqueArray(myIndexBnudles.concat(titleIndexBnudlesNames.concat(moreBundles))).filter(function(bundleName) {
                        return !toIgnore(bundleName);
                    });

                }
                console.log("Bundles in Order", myIndexBnudles);

                var prevBundle = null;
                myIndexBnudles.forEach(function(bundleName) {
                    var _bundleMap = {};
                    var includedBundles = [];
                    var bundledFile = dest + "/bootloader_bundled/" + bundleName.split("/").join(".");
                    var bundledFile_js = bundledFile + ".js";
                    var files = getFiles(bundleName, {js: [], html: []}, bundledFile, includedBundles);
                    var js_files = uniqueArray(files.js.reverse()).reverse();
                    if (js_files.length > 0) {
                        if (!firstIndexBundled && options.resourcesInline) {
                            firstIndexBundled = bundleName;
                            js_files.unshift(resourcesFile + ".js");
                        }
                        _bundleMap[bundledFile_js] = js_files;
                        //console.log("files",bundleName,files.length,files);
                        setBundleConfig(bundleName, _bundleMap, includedBundles, bundledFile_js);

                        if (prevBundle && options.order) {
                            var bundle = resourcesJs.bundles[bundleName];
                            if (bundle) {
                                bundle.on = [prevBundle].concat(bundle.on);
                            }
                        }
                        prevBundle = bundleName;

                    } else console.log("╬═╬ No File in bundle to bundlify thus skipping ", bundleName);

                    var html_files = uniqueArray(files.html.reverse()).reverse();
                    if (html_files.length) {
                        var html_file_content = "";
                        for (var i in html_files) {
                            html_file_content += '<script type="text/html" src="' + html_files[i] + '">' + grunt.file.read(html_files[i]).split("\t").join("")
                                .split("\n").join(" ")
                                .split(">").map(function(v) {
                                    return v.trim();
                                }).join(">") + '</script>';
                        }
                        grunt.file.write(bundledFile + ".html", html_file_content);
                    }

                });

                resourcesJs.gitinfo = grunt.config().gitinfo;
                if (firstIndexBundled) {
                    var resJsonString = JSON.stringify({
                        RESOURCES_JSON: resourcesJs,
                        RESOURCES_FILE: resourcesFile
                    }).replace(/\r?\n|\r|\\n/g, ' ');

                    var packed = resJsonString;
                    var unpack = "";
                    if(options.jsonpack){
                        var jsonpack = require('jsonpack/main');
                        var fs = require("fs");
                        unpack = grunt.file.read('node_modules/jsonpack/main.js');
                        packed =('(jsonpack.unpack(\''+jsonpack.pack(resJsonString)+'\'))');
                    }

                    grunt.file.write(resourcesFile + ".js", unpack+";var _BOOTLOADER_CONFIG_=" + packed);
                    resourcesJs.bundles[firstIndexBundled].js.unshift(resourcesFile + ".js");
                }

                grunt.task.run("uglify");
            }

            grunt.file.write(resourcesFile, JSON.stringify(resourcesJs));

        }
    }
1332729
function bundle(entry, output, name) {
  rollup.rollup({
    input: path.resolve(process.cwd(), entry),
    plugins: plugins
  }).then((bundle) => {
    return bundle.generate({
      format: format(),
      name: name,
      sourcemap: true
    })
  }).then(({ code, map}) => {
    return write(path.resolve(process.cwd(), output), code)
  }).then(() => {
    var source = fs.readFileSync(path.resolve(process.cwd(), output), 'utf-8', (err) => { throw err })
    var compilerFlags = {
      jsCode: [{ src: source }],
      compilationLevel: 'ADVANCED',
      languageOut: 'ECMASCRIPT5',
      createSourceMap: true
    }
    var result = compiler(compilerFlags)
    var minPath = 'bundle/' + output.split('/').pop().split('.')[0] + '.min.js'
    var sourcePath = minPath + '.map'
    // write min.js and min.js.map
    fs.writeFileSync(minPath, result.compiledCode, 'utf-8', (err) => { throw err })
    fs.writeFileSync(sourcePath, result.sourceMap, 'utf-8', (err) => { throw err })
    console.info(chalk.red(minPath) + ' ' + chalk.green(getSize(result.compiledCode)))
  }).catch((err) => {
    console.error(err)
  })
}
1181231
function serveapp (directory) {
	/* istanbul ignore next */
	return async function serveEmberAPP (ctx, next) {
		await next();
		if (!ctx.body) {
			await ctx.render(directory);
		}
	};
}
457173
function (options, callback) {
    var log = this.log;

    log('starting app server');
    if (this.startAppServerFunc) {
      // manual starting of app server
      this.startAppServerFunc(options, callback);
    } else {
      // let smocks-magellan-nightwatch automatically handle the work
      var appServer = this.appServer = new Hapi.Server();
      appServer.connection({ port: this.appPort });
      appServer.route([{
        method: 'GET',
        path: '/{path*}',
        handler: function (req, reply) {
          log('request made: ' + req.path);
          var requestPath = req.path;
          var artifactPath = Path.join(options.distPath, requestPath);
          if (requestPath.match(/\/[^\.]*$/i)) {
            log('handling response as container html file');
            // it's the main index file.  In order to re-use the transpiled files, we need to
            // ensure that the container html file represents the correct mock port so
            // we will replace that out when returning the file contents
            replyWithIndexFile(options, reply);
          } else {
            log('handling response: ' + requestPath);

            fs.exists(artifactPath, function (exists) {
              if (exists) {
                var mimeType = mimeTypes.lookup(artifactPath);
                fs.readFile(artifactPath, function (err, buffer) {
                  if (err) {
                    log('error loading file: ' + artifactPath + ': ' + e.message);
                    reply(err);
                  } else {
                    log('responding with ' + artifactPath);
                    reply(buffer).type(mimeType);
                  }
                });
              } else {
                log(artifactPath + ' does not exist... 404');
                reply({message: artifactPath + ' does not exist'}).code(404);
              }
            });
          }
        }
      }]);
      appServer.start(callback);
    }
  }
1053444
function bundlerFactory(loader, options) {
  function bundlerDelegate(modules) {
    return bundler(loader, options || {}, modules);
  }

  bundlerDelegate.bundle = function(names) {
    return loader.fetch(names).then(bundlerDelegate);
  };

  return bundlerDelegate;
}
94268
function createMiddleware(options) {
  /**
   * Express middleware handling Git API Blob requests
   *
   * Only a small subset will be implemented
   *
   * @param {Request} req Request object
   * @param {Response} res Response object
   * @param {callback} next next middleware in chain
   *
   * @see https://developer.github.com/v3/git/blobs/#get-a-blob
   */
  return (req, res, next) => {
    // GET /repos/:owner/:repo/git/blobs/:file_sha
    const { owner } = req.params;
    const repoName = req.params.repo;
    const sha = req.params.file_sha;
    const host = req.mappedSubDomain ? `localhost:${options.listen[req.protocol].port}` : req.headers.host;

    const repPath = resolveRepositoryPath(options, owner, repoName);

    if (sha.match(/[0-9a-f]/g).length !== 40) {
      // invalid sha format
      res.status(422).json({
        message: 'The sha parameter must be exactly 40 characters and contain only [0-9a-f].',
        documentation_url: 'https://developer.github.com/v3/git/blobs/#get-a-blob',
      });
      return;
    }
    getObject(repPath, sha)
      .then(({ object: content }) => {
        res.json({
          sha,
          size: content.length,
          url: `${req.protocol}://${host}${req.path}`,
          content: `${content.toString('base64')}\n`,
          encoding: 'base64',
        });
      })
      .catch((err) => {
        // TODO: use generic errors
        if (err.code === 'ReadObjectFail') {
          options.logger.debug(`[blobHandler] resource not found: ${err.message}`);
          res.status(404).json({
            message: 'Not Found',
            documentation_url: 'https://developer.github.com/v3/git/blobs/#get-a-blob',
          });
        } else {
          options.logger.debug(`[blobHandler] code: ${err.code} message: ${err.message} stack: ${err.stack}`);
          next(err);
        }
      });
  };
}
1360996
function runRollupTask(entry, filename) {

    // CommonJS build.
    // this is used as the "main" field in package.json
    // and used by bundlers like Webpack and Browserify.
    rollup.rollup({
            entry: entry,
            plugins: [
                babel({
                    loose: 'all'
                })
            ]
        })
        .then(function(bundle) {
            return write('dist/' + filename + '.common.js', bundle.generate({
                format: 'cjs',
                banner: banner
            }).code)
        })
        // Standalone Dev Build
        .then(function() {
            return rollup.rollup({
                    entry: entry,
                    plugins: [
                        replace({
                            'process.env.NODE_ENV': "'development'"
                        }),
                        babel({
                            loose: 'all'
                        })
                    ]
                })
                .then(function(bundle) {
                    return write('dist/' + filename + '.js', bundle.generate({
                        format: 'umd',
                        banner: banner,
                        moduleName: 'React'
                    }).code)
                })
        })
        .then(function() {
            // Standalone Production Build
            return rollup.rollup({
                    entry: entry,
                    plugins: [
                        replace({
                            'process.env.NODE_ENV': "'production'"
                        }),
                        babel({
                            loose: 'all'
                        })
                    ]
                })
                .then(function(bundle) {
                    var code = bundle.generate({
                        format: 'umd',
                        moduleName: 'React'
                    }).code
                    var minified = banner + '\n' + uglify.minify(code, {
                        fromString: true
                    }).code
                    return write('dist/' + filename + '.min.js', minified)
                })
                .then(zip)
        })
        .catch(logError)

    function zip() {
        return new Promise(function(resolve, reject) {
            fs.readFile('dist/' + filename + '.min.js', function(err, buf) {
                if (err) return reject(err)
                zlib.gzip(buf, function(err, buf) {
                    if (err) return reject(err)
                    write('dist/' + filename + '.min.js.gz', buf).then(resolve)
                })
            })
        })
    }
}
248864
function bundle () {
    var didError = false
    const outStream = fs.createWriteStream(outFile)
    const bStream = w.bundle()

    bStream.on('error', function (err) {
      console.error('[bundle]', String(err))
      didError = true
      outStream.end('console.error(' + JSON.stringify(String(err)) + ')')
    })

    // if we're not splitting vendor files, include them in the bundle
    if (!shouldSplitVendor && vendorFiles.length) {
      multistream(vendorFiles.map(createReadStream).concat(bStream))
        .pipe(outStream)
    } else {
      bStream.pipe(outStream)
    }

    outStream.on('error', function (err) {
      console.error('[bundle]', err)
    })

    outStream.on('close', function () {
      if (verbose && !didError) {
        // TODO: also display size of vendor files
        console.error(
          '[bundle] %d bytes written to %s (%s seconds)',
          bytes, outFile, (time / 1000).toFixed(2)
        )
      }
    })
  }
798770
function run(options) {
    // If the server is already available use it.
    var site = options.server ? options.server() : express();
    var protocol = options.ssl ? "https" : "http";

    // Allow compression to be disabled.
    if (options.gzip !== false) {
      site.use(compression());
    }

    // Go through each compiler and provide an identical serving experience.
    _.each(options.middleware, function(callback, extension) {
      // Investigate if there is a better way of writing this.
      site.get(new RegExp(extension), function(req, res, next) {
        var url = req.url;

        // If there are query parameters, remove them.
        url = url.split("?")[0];

        // Determine the correct asset path.
        var path = options.map[url.slice(1)] || "." + url;

        // Read in the file contents.
        fs.readFile(path, function(err, buffer) {
          // File wasn't found.
          if (err) {
            return next();
          }

          callback(buffer, req, res, next);
        });
      });
    });

    // Map static folders to take precedence over redirection.
    Object.keys(options.map).sort().reverse().forEach(function(name) {
      var normalizePath = path.join(options.prefix, options.map[name]);
      var dirMatch = grunt.file.isDir(normalizePath) ? "/*" : "";
      site.get(options.root + name + dirMatch, function(req, res, next) {
        // Find filename.
        var filename = req.url.slice((options.root + name).length);
        // If there are query parameters, remove them.
        filename = filename.split("?")[0];

        res.sendFile(path.join(normalizePath, filename), { root: './' });
      });
    });

    // Very similar to map, except that the mapped path is another server.
    Object.keys(options.proxy).sort().reverse().forEach(function(name) {
      var target = options.proxy[name];
      var protocol = target.https ? "https" : "http";

      var proxyOptions = {
        // This can be a string or an object.
        target: target,

        // Do not change the origin, this can affect how servers respond.
        changeOrigin: false,

        // Remove the forwarded headers, make it feel seamless.
        enable : {
          xforward: false
        }
      };

      // Ensure the https proxy settings are configured here as well.
      if (_.isBoolean(target.https) && target.https) {
        proxyOptions.https = {
          key: fs.readFileSync(__dirname + "/ssl/server.key", "utf8"),
          cert: fs.readFileSync(__dirname + "/ssl/server.crt", "utf8")
        };
      }

      // Initialize the actual proxy object.
      var proxy = new httpProxy.createProxy(proxyOptions);

      // Same thing for these, if you have https boolean set to true, default
      // to internal keys/certs.
      if (_.isBoolean(target.https) && target.https) {
        // Load the SSL certificates, in case they are needed.
        target.https = {
          key: fs.readFileSync(__dirname + "/ssl/server.key", "utf8"),
          cert: fs.readFileSync(__dirname + "/ssl/server.crt", "utf8")
        };
      }

      // Listen on all HTTP verbs for seamless proxying.
      site.all(options.root + name, function(req, res, next) {
        var referer = protocol + "://" + options.host;
        var origin = protocol + "://" + proxyOptions.target.host;

        if (options.port !== "80") {
          referer += ":" + options.port;
        }

        // Transparently set the referer, origin, and host headers.
        _.extend(req.headers, {
          referer: origin,
          origin: origin,
          host: proxyOptions.target.host,
          accept: req.headers.accept || "*/*"
        }, target.headers);

        if (String(req.headers.accept) === "undefined") {
          req.headers.accept = "*/*";
        }

        // Make the proxy request.
        proxy.proxyRequest(req, res);
      });
    });

    // Compression middleware.
    site.all("*", function(content, req, res, next) {
      if (content) {
        return res.send(content);
      }

      next();
    });

    // Attempt to laod from the prefixed directory first.
    //site.use(express.static(path.join(CWD, options.prefix)));
    site.all("*", function(req, res, next) {
      // If there are query parameters, remove them.
      var filename = path.join(options.prefix, req.url.split("?")[0]);

      // Detect if the file requested exists in the current prefixed path.
      fs.exists(filename, function(exists) {
        // If the file doesn't exist or if it's a folder, let another handler
        // take care of serving.
        if (!exists || filename.slice(-1) === path.sep) {
          next();
        } else {
          res.sendFile(filename, {root: './'});
        }
      });
    });

    // Ensure all routes go home, client side app..
    if (options.pushState) {
      site.all("*", function(req, res) {
        fs.createReadStream(path.join(options.prefix, options.index)).pipe(res);
      });
    }

    // Echo out a message alerting the user that the server is running.
    console.log("Listening on", protocol + "://" + options.host + ":" +
      options.port);

    // Start listening.
    if (!options.ssl) {
      return site.listen(options.port, options.host);
    }

    // Create the SSL server instead...
    https.createServer(options.ssl, site).listen(options.port, options.host);
  }
651980
function hooks(compiler, options) {
  return Promise.resolve()
    .then(() => require('./HmrServer'))
    .then(({ default: HmrServer }) =>
      new HmrServer({
        ...options,
        compiler, // webpack compiler
      }).run()
    );
}
1301141
function createMiddleware(options, urlType) {
  /**
   * Express middleware handling html requests
   *
   * @param {Request} req Request object
   * @param {Response} res Response object
   * @param {callback} next next middleware in chain
   */
  return async (req, res, next) => {
    const { owner } = req.params;
    const repoName = req.params.repo;
    let refName = req.params.ref || 'master';
    let fpath = req.params[0] || '';

    const repPath = resolveRepositoryPath(options, owner, repoName);

    // issue: #53: handle branch names containing '/' (e.g. 'foo/bar')
    const parsed = await determineRefPathName(repPath, `${req.params.ref}/${req.params[0]}`);
    if (parsed) {
      refName = parsed.ref;
      fpath = parsed.pathName;
    }

    // issue #247: lenient handling of redundant leading slashes in path
    while (fpath.length && fpath[0] === '/') {
      // trim leading slash
      fpath = fpath.substr(1);
    }

    // set response content type
    res.header('Content-Type', 'text/html');

    resolveCommit(repPath, refName)
      .then(commitOid => git.readObject({ dir: repPath, oid: commitOid, filepath: fpath })
        .catch(() => null))
      .then((blobOrTree) => {
        if (!blobOrTree) {
          if (!fpath.length && urlType === 'tree') {
            // 'tree' view
            res.send(`<!DOCTYPE html><html><body>owner: ${escape(owner)}<br>repo: ${escape(repoName)}<br>ref: ${escape(refName)}<p>tree view not implemented yet.</body></html>`);
          } else {
            res.status(404).send(`not found: ${escape(fpath)}`);
          }
          return;
        }

        const { type } = blobOrTree;
        if (!fpath.length && type === 'tree' && urlType === 'root') {
          // 'root' view
          res.send(`<!DOCTYPE html><html><body>owner: ${escape(owner)}<br>repo: ${escape(repoName)}<br>ref: ${escape(refName)}<p>root view not implemented yet.</body></html>`);
        } else if (type === 'tree' && urlType === 'tree') {
          // directory view
          res.send(`<!DOCTYPE html><html><body>owner: ${escape(owner)}<br>repo: ${escape(repoName)}<br>ref: ${escape(refName)}<br>path: ${escape(fpath)}<p>directory view not implemented yet.</body></html>`);
        } else if (type === 'blob' && urlType === 'blob') {
          // single file view
          res.send(`<!DOCTYPE html><html><body>owner: ${escape(owner)}<br>repo: ${escape(repoName)}<br>ref: ${escape(refName)}<br>path: ${escape(fpath)}<p>file view not implemented yet.</body></html>`);
        } else {
          res.status(404).send(`not found: ${escape(fpath)}`);
        }
      })
      .catch((err) => {
        options.logger.debug(`[htmlHandler] code: ${err.code} message: ${err.message} stack: ${err.stack}`);
        next(err);
      });
  };
}
353433
function HttpServer(options) {
  options = options || {};

  if (options.root) {
    this.root = options.root;
  }
  else {
    try {
      fs.lstatSync('./public');
      this.root = './public';
    }
    catch (err) {
      this.root = './';
    }
  }

  this.headers = options.headers || {};

  this.cache = (
    options.cache === undefined ? 3600 :
    // -1 is a special case to turn off caching.
    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching
    options.cache === -1 ? 'no-cache, no-store, must-revalidate' :
    options.cache // in seconds.
  );
  this.showDir = options.showDir !== 'false';
  this.autoIndex = options.autoIndex !== 'false';
  this.showDotfiles = options.showDotfiles;
  this.gzip = options.gzip === true;
  this.brotli = options.brotli === true;
  this.contentType = options.contentType || 'application/octet-stream';

  if (options.ext) {
    this.ext = options.ext === true
      ? 'html'
      : options.ext;
  }

  var before = options.before ? options.before.slice() : [];

  before.push(function (req, res) {
    if (options.logFn) {
      options.logFn(req, res);
    }

    res.emit('next');
  });

  if (options.username || options.password) {
    before.push(function (req, res) {
      var credentials = auth(req);

      // We perform these outside the if to avoid short-circuiting and giving
      // an attacker knowledge of whether the username is correct via a timing
      // attack.
      if (credentials) {
        var usernameEqual = secureCompare(options.username, credentials.name);
        var passwordEqual = secureCompare(options.password, credentials.pass);
        if (usernameEqual && passwordEqual) {
          return res.emit('next');
        }
      }

      res.statusCode = 401;
      res.setHeader('WWW-Authenticate', 'Basic realm=""');
      res.end('Access denied');
    });
  }

  if (options.cors) {
    this.headers['Access-Control-Allow-Origin'] = '*';
    this.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Range';
    if (options.corsHeaders) {
      options.corsHeaders.split(/\s*,\s*/)
          .forEach(function (h) { this.headers['Access-Control-Allow-Headers'] += ', ' + h; }, this);
    }
    before.push(corser.create(options.corsHeaders ? {
      requestHeaders: this.headers['Access-Control-Allow-Headers'].split(/\s*,\s*/)
    } : null));
  }

  if (options.robots) {
    before.push(function (req, res) {
      if (req.url === '/robots.txt') {
        res.setHeader('Content-Type', 'text/plain');
        var robots = options.robots === true
          ? 'User-agent: *\nDisallow: /'
          : options.robots.replace(/\\n/, '\n');

        return res.end(robots);
      }

      res.emit('next');
    });
  }

  before.push(ecstatic({
    root: this.root,
    cache: this.cache,
    showDir: this.showDir,
    showDotfiles: this.showDotfiles,
    autoIndex: this.autoIndex,
    defaultExt: this.ext,
    gzip: this.gzip,
    brotli: this.brotli,
    contentType: this.contentType,
    handleError: typeof options.proxy !== 'string'
  }));

  if (typeof options.proxy === 'string') {
    var proxy = httpProxy.createProxyServer({});
    before.push(function (req, res) {
      proxy.web(req, res, {
        target: options.proxy,
        changeOrigin: true
      }, function (err, req, res, target) {
        if (options.logFn) {
          options.logFn(req, res, {
            message: err.message,
            status: res.statusCode });
        }
        res.emit('next');
      });
    });
  }

  var serverOptions = {
    before: before,
    headers: this.headers,
    onError: function (err, req, res) {
      if (options.logFn) {
        options.logFn(req, res, err);
      }

      res.end();
    }
  };

  if (options.https) {
    serverOptions.https = options.https;
  }

  this.server = union.createServer(serverOptions);
}
497695
function( options ) {
  this.options = options;
  this.wpt = new WPT( this.options.wpt.server );

  this.data  = [];
  this.queue = new Queue();
}
819087
function server(options) {
  status = 'server.started'
  config = _.extend(defaultServerOptions, options)

  open(config.datafile)

  if (config.logToConsole)
    console.log("✔ log to stdout")

  // ws [
  var ServerMessageLog = {}
  var queueMessages = []
  var timer

  function flushMessages(n) {
    queueMessages = _.sortBy(queueMessages, 'time')
    var messages = queueMessages.slice(0, n)
    queueMessages = queueMessages.slice(n)
//    console.log(messages);
    _.each(messages, function (m) {
//      var filename = options.logpath+'/1.log'
//      logString(filename, m.text)
      logMessage(new Date(m.time), m.path, m.data, m.type == 'log' ? '' : m.type)
    })
  }

  console.log("✔ ws server listening on port %d", config.port)

  var wss = new WebSocketServer({port: config.port});

  wss.on('connection', function(ws) {
    ws.on('message', function(m) {
      var message = JSON.parse(m)
      queueMessages.push(message)
      if (queueMessages.length > config.queueMessagesMax)
        flushMessages(config.flushMessagesCount)

      if (timer)
        clearTimeout(timer)
      timer = setTimeout(function () {
        timer = null
        flushMessages(queueMessages.length)
      }, config.serverFlushTimeout)
    })
  })
  // ws ]
}