Full Code of BrowserSync/browser-sync for AI

master dc74bc0a6bcb cached
682 files
3.2 MB
867.3k tokens
1288 symbols
1 requests
Download .txt
Showing preview only (3,451K chars total). Download the full file or copy to clipboard to get everything.
Repository: BrowserSync/browser-sync
Branch: master
Commit: dc74bc0a6bcb
Files: 682
Total size: 3.2 MB

Directory structure:
gitextract_5fuwfm2s/

├── .editorconfig
├── .gitattributes
├── .github/
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── changelog.js
├── examples/
│   ├── 404.js
│   ├── basic/
│   │   └── run.js
│   ├── callback.js
│   ├── express.js
│   ├── less.js
│   ├── middleware.css.injection.js
│   ├── notify-styles.js
│   ├── options.snippetOptions.js
│   ├── proxy.gzip.js
│   ├── proxy.headers.js
│   ├── proxy.localhost.js
│   ├── proxy.middleware.js
│   ├── proxy.middleware.multi.js
│   ├── proxy.proxyRes.js
│   ├── proxy.rewriteRules.advanced.js
│   ├── proxy.rewriteRules.simple.js
│   ├── proxy.secure.js
│   ├── proxy.vhost.js
│   ├── server.basedir.js
│   ├── server.basedir.mulitple.js
│   ├── server.default.js
│   ├── server.gzip.js
│   ├── server.http2.js
│   ├── server.latency.js
│   ├── server.middleware.js
│   ├── server.middleware.multiple.js
│   ├── server.proxy.js
│   ├── server.secure.js
│   ├── server.secure.pfx.js
│   ├── server.watch.js
│   └── snippet/
│       ├── index.html
│       └── run.js
├── lerna.json
├── nx.json
├── package.json
├── packages/
│   ├── browser-sync/
│   │   ├── .gitignore
│   │   ├── .prettierignore
│   │   ├── certs/
│   │   │   ├── browsersync.pfx
│   │   │   ├── gen.sh
│   │   │   ├── server.crt
│   │   │   ├── server.csr
│   │   │   └── server.key
│   │   ├── cli-options/
│   │   │   ├── opts.init.json
│   │   │   ├── opts.recipe.json
│   │   │   ├── opts.reload.json
│   │   │   └── opts.start.json
│   │   ├── lib/
│   │   │   ├── args.js
│   │   │   ├── async-tasks.js
│   │   │   ├── async.js
│   │   │   ├── bin.ts
│   │   │   ├── browser-sync.js
│   │   │   ├── cli/
│   │   │   │   ├── cli-info.js
│   │   │   │   ├── cli-options.ts
│   │   │   │   ├── command.init.js
│   │   │   │   ├── command.recipe.js
│   │   │   │   ├── command.reload.js
│   │   │   │   ├── command.start.ts
│   │   │   │   └── transforms/
│   │   │   │       ├── addCwdToWatchOptions.ts
│   │   │   │       ├── addDefaultIgnorePatterns.ts
│   │   │   │       ├── addToFilesOption.ts
│   │   │   │       ├── appendServerDirectoryOption.ts
│   │   │   │       ├── appendServerIndexOption.ts
│   │   │   │       ├── copyCLIIgnoreToWatchOptions.ts
│   │   │   │       ├── handleExtensionsOption.ts
│   │   │   │       ├── handleFilesOption.ts
│   │   │   │       ├── handleGhostModeOption.ts
│   │   │   │       ├── handleHostOption.ts
│   │   │   │       ├── handlePortsOption.ts
│   │   │   │       ├── handleProxyOption.ts
│   │   │   │       └── handleServerOption.ts
│   │   │   ├── config.js
│   │   │   ├── connect-utils.js
│   │   │   ├── default-config.js
│   │   │   ├── file-event-handler.js
│   │   │   ├── file-utils.js
│   │   │   ├── file-watcher.js
│   │   │   ├── hooks.js
│   │   │   ├── http-protocol.js
│   │   │   ├── index.js
│   │   │   ├── internal-events.js
│   │   │   ├── lodash.custom.js
│   │   │   ├── logger.js
│   │   │   ├── options.ts
│   │   │   ├── plugins.js
│   │   │   ├── public/
│   │   │   │   ├── exit.js
│   │   │   │   ├── init.ts
│   │   │   │   ├── notify.js
│   │   │   │   ├── pause.js
│   │   │   │   ├── public-utils.js
│   │   │   │   ├── reload.js
│   │   │   │   ├── resume.js
│   │   │   │   └── stream.js
│   │   │   ├── server/
│   │   │   │   ├── index.js
│   │   │   │   ├── proxy-server.js
│   │   │   │   ├── proxy-utils.js
│   │   │   │   ├── serve-static-wrapper.ts
│   │   │   │   ├── snippet-server.js
│   │   │   │   ├── static-server.js
│   │   │   │   └── utils.js
│   │   │   ├── snippet.js
│   │   │   ├── sockets.ts
│   │   │   ├── tunnel.js
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── templates/
│   │   │   ├── cli-template.js
│   │   │   ├── connector.tmpl
│   │   │   ├── script-tags-simple.html
│   │   │   └── script-tags.html
│   │   ├── test/
│   │   │   ├── env.js
│   │   │   ├── fixtures/
│   │   │   │   ├── .tmp/
│   │   │   │   │   └── temp.css
│   │   │   │   ├── alt/
│   │   │   │   │   └── index.htm
│   │   │   │   ├── assets/
│   │   │   │   │   ├── import.css
│   │   │   │   │   ├── import2.css
│   │   │   │   │   ├── print.css
│   │   │   │   │   └── style.css
│   │   │   │   ├── base.html
│   │   │   │   ├── bootstrap/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   ├── bootstrap-grid.css
│   │   │   │   │   │   ├── bootstrap-reboot.css
│   │   │   │   │   │   ├── bootstrap.css
│   │   │   │   │   │   └── justified-nav.css
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── js/
│   │   │   │   │       ├── bootstrap.bundle.js
│   │   │   │   │       └── bootstrap.js
│   │   │   │   ├── bootstrap.html
│   │   │   │   ├── bower.html
│   │   │   │   ├── bower_components/
│   │   │   │   │   └── app.css
│   │   │   │   ├── config/
│   │   │   │   │   ├── config.js
│   │   │   │   │   ├── si-config-partial.js
│   │   │   │   │   ├── si-config-ports.js
│   │   │   │   │   ├── si-config-proxy.js
│   │   │   │   │   ├── si-config.js
│   │   │   │   │   └── si-default-config.js
│   │   │   │   ├── css/
│   │   │   │   │   ├── bootstrap-less.css
│   │   │   │   │   ├── bootstrap-scss.css
│   │   │   │   │   └── bootstrap.css
│   │   │   │   ├── fonts/
│   │   │   │   │   └── roboto/
│   │   │   │   │       ├── Roboto-Regular-demo.html
│   │   │   │   │       └── stylesheet.css
│   │   │   │   ├── forms.html
│   │   │   │   ├── iframe.html
│   │   │   │   ├── images.html
│   │   │   │   ├── import-link.html
│   │   │   │   ├── import.html
│   │   │   │   ├── index-amd.html
│   │   │   │   ├── index-large.html
│   │   │   │   ├── index-urls.html
│   │   │   │   ├── index.html
│   │   │   │   ├── inputs.html
│   │   │   │   ├── js/
│   │   │   │   │   ├── default.js
│   │   │   │   │   └── main.js
│   │   │   │   ├── less/
│   │   │   │   │   └── bootstrap.less
│   │   │   │   ├── less.html
│   │   │   │   ├── links.html
│   │   │   │   ├── plugin.js
│   │   │   │   ├── proxy-headers.html
│   │   │   │   ├── proxy-ip.html
│   │   │   │   ├── proxy-vhost.html
│   │   │   │   ├── rewrites/
│   │   │   │   │   ├── comment.expected.html
│   │   │   │   │   ├── comment.html
│   │   │   │   │   ├── escaped.1.expected.html
│   │   │   │   │   ├── escaped.1.html
│   │   │   │   │   ├── hashes.expected.html
│   │   │   │   │   └── hashes.input.html
│   │   │   │   ├── sass.html
│   │   │   │   ├── scrolling.html
│   │   │   │   ├── scss/
│   │   │   │   │   └── bootstrap-scss.scss
│   │   │   │   ├── socket.io.html
│   │   │   │   ├── stylus/
│   │   │   │   │   └── bootstrap.styl
│   │   │   │   ├── svg.html
│   │   │   │   ├── tailwind/
│   │   │   │   │   └── index.html
│   │   │   │   ├── test.txt
│   │   │   │   ├── test2.txt
│   │   │   │   ├── username.github.io/
│   │   │   │   │   └── index.html
│   │   │   │   └── watch-func.txt
│   │   │   ├── fixtures2/
│   │   │   │   └── style-alt.css
│   │   │   ├── protractor/
│   │   │   │   ├── _run.js
│   │   │   │   ├── bs.init.js
│   │   │   │   ├── config.multi.js
│   │   │   │   ├── config.single.js
│   │   │   │   ├── logger.js
│   │   │   │   ├── runProtractor.js
│   │   │   │   ├── setup.js
│   │   │   │   ├── setup.single.js
│   │   │   │   ├── tests/
│   │   │   │   │   ├── actions.clicks.js
│   │   │   │   │   ├── actions.scroll.js
│   │   │   │   │   ├── proxy.interactions.js
│   │   │   │   │   ├── proxy.rewrites.js
│   │   │   │   │   ├── server.interactions.js
│   │   │   │   │   ├── snippet.injection.js
│   │   │   │   │   ├── with.baseurl.https.js
│   │   │   │   │   ├── with.baseurl.js
│   │   │   │   │   └── with.socket.io.js
│   │   │   │   ├── tests.multi.js
│   │   │   │   ├── tests.single.js
│   │   │   │   └── utils.js
│   │   │   ├── specs/
│   │   │   │   ├── api/
│   │   │   │   │   ├── init.active.js
│   │   │   │   │   ├── init.exit.js
│   │   │   │   │   ├── init.js
│   │   │   │   │   ├── init.notify.js
│   │   │   │   │   ├── init.pause.js
│   │   │   │   │   ├── init.reload.deprecated.js
│   │   │   │   │   ├── init.reload.js
│   │   │   │   │   ├── init.reload.multi.js
│   │   │   │   │   ├── init.reload.stream.js
│   │   │   │   │   ├── init.reload.stream.noop.js
│   │   │   │   │   ├── init.returns.js
│   │   │   │   │   ├── init.sockets.js
│   │   │   │   │   └── watch.js
│   │   │   │   ├── cli/
│   │   │   │   │   ├── cli.exec.js
│   │   │   │   │   ├── cli.get.config.js
│   │   │   │   │   ├── cli.help.js
│   │   │   │   │   ├── cli.info.js
│   │   │   │   │   ├── cli.options.files.js
│   │   │   │   │   ├── cli.options.ghost.js
│   │   │   │   │   ├── cli.options.ignore.js
│   │   │   │   │   ├── cli.options.ports.js
│   │   │   │   │   ├── cli.options.proxy.js
│   │   │   │   │   ├── cli.options.server.js
│   │   │   │   │   ├── cli.options.watch.js
│   │   │   │   │   └── cli.options.watchOptions.cwd.js
│   │   │   │   ├── commands/
│   │   │   │   │   ├── recipes.js
│   │   │   │   │   └── reload.js
│   │   │   │   ├── e2e/
│   │   │   │   │   ├── cli/
│   │   │   │   │   │   ├── e2e.cli.conf.js
│   │   │   │   │   │   ├── e2e.cli.error.js
│   │   │   │   │   │   ├── e2e.cli.files.js
│   │   │   │   │   │   ├── e2e.cli.init.js
│   │   │   │   │   │   ├── e2e.cli.plugins.js
│   │   │   │   │   │   ├── e2e.cli.proxy.js
│   │   │   │   │   │   ├── e2e.cli.proxy.ws.js
│   │   │   │   │   │   ├── e2e.cli.server.js
│   │   │   │   │   │   ├── e2e.cli.snippet.js
│   │   │   │   │   │   └── e2e.cli.ui.js
│   │   │   │   │   ├── commands.server.json
│   │   │   │   │   ├── e2e.events.js
│   │   │   │   │   ├── e2e.fail.js
│   │   │   │   │   ├── e2e.online.js
│   │   │   │   │   ├── e2e.options.callbacks.js
│   │   │   │   │   ├── e2e.options.cors.js
│   │   │   │   │   ├── e2e.options.js
│   │   │   │   │   ├── e2e.options.logPrefix.js
│   │   │   │   │   ├── e2e.options.logSnippet.js
│   │   │   │   │   ├── e2e.options.open.browsers.js
│   │   │   │   │   ├── e2e.options.open.js
│   │   │   │   │   ├── e2e.options.port.js
│   │   │   │   │   ├── e2e.options.script.async.js
│   │   │   │   │   ├── e2e.options.scriptpath.js
│   │   │   │   │   ├── e2e.options.serveStatic.js
│   │   │   │   │   ├── e2e.options.single.js
│   │   │   │   │   ├── e2e.options.snippet.js
│   │   │   │   │   ├── e2e.options.sockets.js
│   │   │   │   │   ├── e2e.options.startPath.js
│   │   │   │   │   ├── e2e.snippet.js
│   │   │   │   │   ├── files/
│   │   │   │   │   │   ├── e2e.file.changed.js
│   │   │   │   │   │   ├── e2e.file.options.js
│   │   │   │   │   │   └── e2e.file.watching.js
│   │   │   │   │   ├── middleware/
│   │   │   │   │   │   ├── middleware.option.js
│   │   │   │   │   │   ├── middleware.proxy.option.js
│   │   │   │   │   │   └── middleware.server.option.js
│   │   │   │   │   ├── proxy/
│   │   │   │   │   │   ├── e2e.proxy.cookies.js
│   │   │   │   │   │   ├── e2e.proxy.error.js
│   │   │   │   │   │   ├── e2e.proxy.external.js
│   │   │   │   │   │   ├── e2e.proxy.js
│   │   │   │   │   │   ├── e2e.proxy.proxy.options.js
│   │   │   │   │   │   ├── e2e.proxy.req.headers.js
│   │   │   │   │   │   ├── e2e.proxy.req.headers.obj.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.add.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.remove.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.replace.js
│   │   │   │   │   │   ├── e2e.proxy.secure.js
│   │   │   │   │   │   ├── e2e.proxy.snippet.js
│   │   │   │   │   │   └── e2e.proxy.ws.js
│   │   │   │   │   └── server/
│   │   │   │   │       ├── e2e.server.404.js
│   │   │   │   │       ├── e2e.server.dirs.js
│   │   │   │   │       ├── e2e.server.httpModule.js
│   │   │   │   │       ├── e2e.server.js
│   │   │   │   │       ├── e2e.server.middleware.js
│   │   │   │   │       ├── e2e.server.newapi.js
│   │   │   │   │       ├── e2e.server.newapi2.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.add.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.remove.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.replace.js
│   │   │   │   │       ├── e2e.server.routes.js
│   │   │   │   │       ├── e2e.server.secure.custom.js
│   │   │   │   │       ├── e2e.server.secure.js
│   │   │   │   │       ├── e2e.server.secure.pfx.js
│   │   │   │   │       ├── e2e.server.serveStatic.extensions.js
│   │   │   │   │       ├── e2e.server.serveStatic.js
│   │   │   │   │       └── e2e.server.tunnel.js
│   │   │   │   ├── files/
│   │   │   │   │   ├── files.event-handler.js
│   │   │   │   │   ├── files.watching.debounce.js
│   │   │   │   │   ├── files.watching.delay.js
│   │   │   │   │   └── files.watching.js
│   │   │   │   ├── hooks/
│   │   │   │   │   └── files.watch.hook.js
│   │   │   │   ├── http-protocol/
│   │   │   │   │   └── http.reload.js
│   │   │   │   ├── instances/
│   │   │   │   │   ├── multi.emitter.js
│   │   │   │   │   ├── multi.get.js
│   │   │   │   │   ├── multi.has.js
│   │   │   │   │   ├── multi.init.js
│   │   │   │   │   ├── multi.js
│   │   │   │   │   ├── multi.plugins.js
│   │   │   │   │   ├── multi.proxy.js
│   │   │   │   │   └── single.js
│   │   │   │   ├── logger/
│   │   │   │   │   ├── logger.baseDir.js
│   │   │   │   │   └── logger.files.changed.js
│   │   │   │   ├── options/
│   │   │   │   │   └── options.set.js
│   │   │   │   ├── plugins/
│   │   │   │   │   ├── bs.options.js
│   │   │   │   │   ├── connector.js
│   │   │   │   │   ├── files.js
│   │   │   │   │   ├── hooks.js
│   │   │   │   │   ├── logger.js
│   │   │   │   │   ├── options.js
│   │   │   │   │   ├── ui.error.js
│   │   │   │   │   ├── ui.js
│   │   │   │   │   ├── user.plugins.add.middleware.js
│   │   │   │   │   ├── user.plugins.cleanup.js
│   │   │   │   │   ├── user.plugins.error.js
│   │   │   │   │   ├── user.plugins.inline.enabled.js
│   │   │   │   │   ├── user.plugins.inline.error.js
│   │   │   │   │   ├── user.plugins.inline.js
│   │   │   │   │   ├── user.plugins.inline.obj.js
│   │   │   │   │   ├── user.plugins.inline.obj.reference.js
│   │   │   │   │   ├── user.plugins.inline.options.js
│   │   │   │   │   ├── user.plugins.js
│   │   │   │   │   ├── user.plugins.proxy.js
│   │   │   │   │   └── user.plugins.serve.files.js
│   │   │   │   ├── resp-mod/
│   │   │   │   │   └── rewrite-links.js
│   │   │   │   ├── server/
│   │   │   │   │   └── server.snippet.js
│   │   │   │   └── utils/
│   │   │   │       ├── utils.connect.js
│   │   │   │       ├── utils.default.callback.js
│   │   │   │       ├── utils.fail.js
│   │   │   │       ├── utils.getHostIp.js
│   │   │   │       ├── utils.getUrl.js
│   │   │   │       ├── utils.getUrls.js
│   │   │   │       ├── utils.js
│   │   │   │       ├── utils.setUrlOptions.js
│   │   │   │       └── utils.verifyOptions.js
│   │   │   └── utils.js
│   │   └── tsconfig.json
│   ├── browser-sync-client/
│   │   ├── .gitignore
│   │   ├── .travis.yml
│   │   ├── LICENSE-MIT
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── lib/
│   │   │   ├── browser.utils.ts
│   │   │   ├── dom-effects/
│   │   │   │   ├── link-replace.dom-effect.ts
│   │   │   │   ├── prop-set.dom-effect.ts
│   │   │   │   ├── set-scroll.dom-effect.ts
│   │   │   │   ├── set-window-name.dom-effect.ts
│   │   │   │   └── style-set.dom-effect.ts
│   │   │   ├── dom-effects.ts
│   │   │   ├── effects/
│   │   │   │   ├── browser-reload.effect.ts
│   │   │   │   ├── browser-set-location.effect.ts
│   │   │   │   ├── file-reload.effect.ts
│   │   │   │   ├── set-element-toggle-value.effect.ts
│   │   │   │   ├── set-element-value.effect.ts
│   │   │   │   ├── set-options.effect.ts
│   │   │   │   ├── set-scroll.ts
│   │   │   │   └── simulate-click.effect.ts
│   │   │   ├── effects.ts
│   │   │   ├── index.ts
│   │   │   ├── listeners/
│   │   │   │   ├── clicks.listener.ts
│   │   │   │   ├── form-inputs.listener.ts
│   │   │   │   ├── form-toggles.listener.ts
│   │   │   │   └── scroll.listener.ts
│   │   │   ├── listeners.ts
│   │   │   ├── log.ts
│   │   │   ├── messages/
│   │   │   │   ├── BrowserLocation.ts
│   │   │   │   ├── BrowserNotify.ts
│   │   │   │   ├── BrowserReload.ts
│   │   │   │   ├── ClickEvent.ts
│   │   │   │   ├── Connection.ts
│   │   │   │   ├── Disconnect.ts
│   │   │   │   ├── FileReload.ts
│   │   │   │   ├── FormToggleEvent.ts
│   │   │   │   ├── KeyupEvent.ts
│   │   │   │   ├── OptionsSet.ts
│   │   │   │   └── ScrollEvent.ts
│   │   │   ├── notify.ts
│   │   │   ├── scroll-restore.ts
│   │   │   ├── socket-messages.ts
│   │   │   ├── socket.ts
│   │   │   ├── types/
│   │   │   │   ├── socket.ts
│   │   │   │   └── types.d.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.ts
│   │   │   └── vendor/
│   │   │       ├── Reloader.ts
│   │   │       ├── Timer.ts
│   │   │       └── logger.ts
│   │   ├── package.json
│   │   ├── test/
│   │   │   ├── .jshintrc
│   │   │   ├── client-new/
│   │   │   │   ├── bs.options.js
│   │   │   │   ├── code-sync.js
│   │   │   │   ├── emitter.js
│   │   │   │   ├── ghostmode.click.js
│   │   │   │   ├── ghostmode.forms.inputs.js
│   │   │   │   ├── ghostmode.forms.js
│   │   │   │   ├── ghostmode.forms.submit.js
│   │   │   │   ├── ghostmode.forms.toggles.js
│   │   │   │   ├── ghostmode.js
│   │   │   │   ├── ghostmode.location.js
│   │   │   │   ├── ghostmode.scroll.js
│   │   │   │   ├── index.js
│   │   │   │   ├── libs/
│   │   │   │   │   └── assert.js
│   │   │   │   ├── notify.js
│   │   │   │   ├── socket.js
│   │   │   │   ├── stubs/
│   │   │   │   │   └── bs.js
│   │   │   │   └── utils.js
│   │   │   ├── fixtures/
│   │   │   │   ├── css/
│   │   │   │   │   └── style.css
│   │   │   │   ├── forms.html
│   │   │   │   ├── index-large.html
│   │   │   │   ├── index-urls.html
│   │   │   │   ├── index.html
│   │   │   │   ├── inputs.html
│   │   │   │   ├── less.html
│   │   │   │   ├── links.html
│   │   │   │   ├── proxy-headers.html
│   │   │   │   ├── proxy-ip.html
│   │   │   │   ├── proxy-vhost.html
│   │   │   │   ├── sass.html
│   │   │   │   └── scrolling.html
│   │   │   ├── karma.conf.ci.js
│   │   │   ├── karma.conf.js
│   │   │   ├── middleware/
│   │   │   │   ├── file.js
│   │   │   │   └── middleware.js
│   │   │   └── test.conf.js
│   │   ├── tsconfig.json
│   │   └── webpack.config.js
│   └── browser-sync-ui/
│       ├── .editorconfig
│       ├── .gitignore
│       ├── .jshintrc
│       ├── LICENSE
│       ├── README.md
│       ├── crossbow.yaml
│       ├── example.stream.js
│       ├── index.js
│       ├── lib/
│       │   ├── UI.js
│       │   ├── async-tasks.js
│       │   ├── async.js
│       │   ├── client-elements.js
│       │   ├── client-js.js
│       │   ├── config.js
│       │   ├── directive-stripper.js
│       │   ├── hooks.js
│       │   ├── opts.js
│       │   ├── plugins/
│       │   │   ├── connections/
│       │   │   │   ├── connections.client.js
│       │   │   │   ├── connections.directive.html
│       │   │   │   ├── connections.html
│       │   │   │   ├── connections.plugin.js
│       │   │   │   └── lib/
│       │   │   │       └── connections.js
│       │   │   ├── help/
│       │   │   │   ├── help.client.js
│       │   │   │   ├── help.directive.html
│       │   │   │   ├── help.html
│       │   │   │   └── help.plugin.js
│       │   │   ├── history/
│       │   │   │   ├── history.client.js
│       │   │   │   ├── history.directive.html
│       │   │   │   ├── history.html
│       │   │   │   ├── history.js
│       │   │   │   └── history.plugin.js
│       │   │   ├── network-throttle/
│       │   │   │   ├── network-throttle.client.js
│       │   │   │   ├── network-throttle.directive.html
│       │   │   │   ├── network-throttle.html
│       │   │   │   ├── network-throttle.js
│       │   │   │   ├── network-throttle.plugin.js
│       │   │   │   ├── targets.js
│       │   │   │   └── throttle-server.js
│       │   │   ├── overview/
│       │   │   │   ├── overview.client.js
│       │   │   │   ├── overview.html
│       │   │   │   ├── overview.plugin.js
│       │   │   │   ├── snippet-info.html
│       │   │   │   └── url-info.html
│       │   │   ├── plugins/
│       │   │   │   ├── plugins.client.js
│       │   │   │   ├── plugins.html
│       │   │   │   └── plugins.plugin.js
│       │   │   ├── remote-debug/
│       │   │   │   ├── client-files.js
│       │   │   │   ├── compression.html
│       │   │   │   ├── compression.js
│       │   │   │   ├── css/
│       │   │   │   │   ├── pesticide-depth.css
│       │   │   │   │   └── pesticide.css
│       │   │   │   ├── latency/
│       │   │   │   │   ├── latency.client.js
│       │   │   │   │   ├── latency.html
│       │   │   │   │   └── latency.js
│       │   │   │   ├── no-cache.html
│       │   │   │   ├── no-cache.js
│       │   │   │   ├── overlay-grid/
│       │   │   │   │   ├── css/
│       │   │   │   │   │   ├── grid-overlay-horizontal.css
│       │   │   │   │   │   └── grid-overlay-vertical.css
│       │   │   │   │   ├── js/
│       │   │   │   │   │   └── grid-overlay.js
│       │   │   │   │   ├── overlay-grid.client.js
│       │   │   │   │   ├── overlay-grid.html
│       │   │   │   │   └── overlay-grid.js
│       │   │   │   ├── remote-debug.client.js
│       │   │   │   ├── remote-debug.html
│       │   │   │   └── remote-debug.plugin.js
│       │   │   └── sync-options/
│       │   │       ├── sync-options.client.js
│       │   │       ├── sync-options.html
│       │   │       └── sync-options.plugin.js
│       │   ├── resolve-plugins.js
│       │   ├── server.js
│       │   ├── transform.options.js
│       │   ├── transforms.js
│       │   ├── urls.js
│       │   └── utils.js
│       ├── package.json
│       ├── public/
│       │   ├── css/
│       │   │   ├── components.css
│       │   │   └── core.css
│       │   ├── img/
│       │   │   └── icons/
│       │   │       └── preview.html
│       │   ├── index.html
│       │   └── js/
│       │       └── app.js
│       ├── src/
│       │   ├── crossbow/
│       │   │   ├── _config.yml
│       │   │   ├── _includes/
│       │   │   │   ├── enable.disable.hbs
│       │   │   │   ├── form.input.checkbox.hbs
│       │   │   │   ├── form.input.text.hbs
│       │   │   │   ├── header.hbs
│       │   │   │   ├── icon.hbs
│       │   │   │   └── nav.hbs
│       │   │   ├── _layouts/
│       │   │   │   ├── components.hbs
│       │   │   │   ├── main.hbs
│       │   │   │   └── parent.hbs
│       │   │   ├── components/
│       │   │   │   ├── button-bars.hbs
│       │   │   │   ├── buttons.hbs
│       │   │   │   ├── footer.hbs
│       │   │   │   ├── forms.hbs
│       │   │   │   ├── header.hbs
│       │   │   │   ├── heading.hbs
│       │   │   │   ├── help-content.hbs
│       │   │   │   ├── lists.hbs
│       │   │   │   ├── panels.hbs
│       │   │   │   ├── switches.hbs
│       │   │   │   └── type.hbs
│       │   │   ├── components.hbs
│       │   │   ├── content/
│       │   │   │   └── help.content.hbs
│       │   │   ├── help.hbs
│       │   │   ├── history.hbs
│       │   │   ├── network-throttle.hbs
│       │   │   ├── plugins.hbs
│       │   │   ├── remote-debug.hbs
│       │   │   ├── server-info-snippet.hbs
│       │   │   ├── server-info.hbs
│       │   │   └── sync-options.hbs
│       │   ├── scripts/
│       │   │   ├── angular.js
│       │   │   ├── app.js
│       │   │   ├── directives/
│       │   │   │   ├── icon.js
│       │   │   │   ├── link-to.js
│       │   │   │   ├── new-tab.js
│       │   │   │   └── switch.js
│       │   │   ├── directives.js
│       │   │   ├── editor.js
│       │   │   ├── filters.js
│       │   │   ├── main/
│       │   │   │   └── controller.js
│       │   │   ├── module.js
│       │   │   ├── modules/
│       │   │   │   ├── bsClients.js
│       │   │   │   ├── bsDisconnect.js
│       │   │   │   ├── bsHistory.js
│       │   │   │   ├── bsNotify.js
│       │   │   │   ├── bsSocket.js
│       │   │   │   └── bsStore.js
│       │   │   ├── services/
│       │   │   │   ├── Options.js
│       │   │   │   └── Pages.js
│       │   │   └── utils.js
│       │   ├── scss/
│       │   │   ├── _vars.scss
│       │   │   ├── components.scss
│       │   │   ├── core.scss
│       │   │   ├── modules/
│       │   │   │   ├── _mixins.scss
│       │   │   │   └── _reset.scss
│       │   │   ├── theme/
│       │   │   │   ├── _animations.scss
│       │   │   │   ├── _base.scss
│       │   │   │   ├── _buttons.scss
│       │   │   │   ├── _cloak.scss
│       │   │   │   ├── _code.scss
│       │   │   │   ├── _custom-icons.scss
│       │   │   │   ├── _disconnect.scss
│       │   │   │   ├── _footer.scss
│       │   │   │   ├── _forms.scss
│       │   │   │   ├── _grid.scss
│       │   │   │   ├── _header.scss
│       │   │   │   ├── _headings.scss
│       │   │   │   ├── _helpers.scss
│       │   │   │   ├── _links.scss
│       │   │   │   ├── _lists.scss
│       │   │   │   ├── _main-content.scss
│       │   │   │   ├── _misc.scss
│       │   │   │   ├── _msgs.scss
│       │   │   │   ├── _notifications.scss
│       │   │   │   ├── _panel.scss
│       │   │   │   ├── _paragraphs.scss
│       │   │   │   ├── _section-nav.scss
│       │   │   │   ├── _sidebar.scss
│       │   │   │   ├── _spinner.scss
│       │   │   │   ├── _state.scss
│       │   │   │   ├── _svg.scss
│       │   │   │   ├── _switch.scss
│       │   │   │   └── _top-bar.scss
│       │   │   └── vendor/
│       │   │       ├── _fonts.scss
│       │   │       └── _normalize.scss
│       │   └── svg-template.tmpl
│       ├── static/
│       │   ├── components/
│       │   │   ├── button-bars.html
│       │   │   ├── buttons.html
│       │   │   ├── footer.html
│       │   │   ├── forms.html
│       │   │   ├── header.html
│       │   │   ├── heading.html
│       │   │   ├── help-content.html
│       │   │   ├── lists.html
│       │   │   ├── panels.html
│       │   │   ├── switches.html
│       │   │   └── type.html
│       │   └── content/
│       │       └── help.content.html
│       ├── tasks/
│       │   ├── crossbow.js
│       │   └── icons.js
│       ├── templates/
│       │   ├── config.item.tmpl
│       │   ├── config.tmpl
│       │   ├── directives/
│       │   │   └── bs-switch.html
│       │   ├── inline.template.tmpl
│       │   ├── plugin.item.tmpl
│       │   └── plugin.tmpl
│       ├── test/
│       │   ├── .jshintrc
│       │   ├── client/
│       │   │   └── e2e/
│       │   │       ├── bs-init.js
│       │   │       ├── config.js
│       │   │       ├── e2e.plugins.js
│       │   │       ├── e2e.server-info.js
│       │   │       ├── e2e.sync-options.js
│       │   │       ├── test-utils.js
│       │   │       └── tests/
│       │   │           ├── history.js
│       │   │           ├── history.newtabs.js
│       │   │           ├── home.js
│       │   │           ├── network-throttle.auto.js
│       │   │           ├── network-throttle.js
│       │   │           ├── network-throttle.manual.js
│       │   │           ├── network-throttle.remove.js
│       │   │           ├── plugins.inline.js
│       │   │           ├── plugins.js
│       │   │           └── remote-debug.js
│       │   ├── fixtures/
│       │   │   ├── content.html
│       │   │   ├── css/
│       │   │   │   ├── blog.css
│       │   │   │   └── bootstrap.css
│       │   │   ├── forms.html
│       │   │   ├── index.html
│       │   │   ├── plugin/
│       │   │   │   ├── index.plugin.js
│       │   │   │   ├── package.json
│       │   │   │   └── ui/
│       │   │   │       ├── client.js
│       │   │   │       ├── test.directive.html
│       │   │   │       └── test.html
│       │   │   ├── plugin-multi-templates/
│       │   │   │   ├── index.plugin.js
│       │   │   │   ├── package.json
│       │   │   │   └── ui/
│       │   │   │       ├── client.js
│       │   │   │       ├── client2.js
│       │   │   │       ├── test.directive.html
│       │   │   │       ├── test.html
│       │   │   │       └── test.list.html
│       │   │   ├── plugin-noui/
│       │   │   │   ├── index.plugin.js
│       │   │   │   └── package.json
│       │   │   └── scrolling.html
│       │   ├── opts.server.json
│       │   ├── protractor.sh
│       │   └── server/
│       │       ├── history/
│       │       │   └── history.js
│       │       ├── init.js
│       │       ├── plugins.js
│       │       ├── plugins.templates.js
│       │       └── remote-debug/
│       │           ├── client.files.js
│       │           ├── latency.js
│       │           ├── no-cache.js
│       │           ├── throttle.https.js
│       │           └── throttle.js
│       └── webpack.config.js
├── playwright.config.ts
└── tests/
    ├── examples/
    │   ├── basic/
    │   │   └── basic.spec.ts
    │   ├── html-inject/
    │   │   └── html-inject.spec.ts
    │   ├── snippet/
    │   │   └── snippet.spec.ts
    │   └── tailwind/
    │       └── tailwind.spec.ts
    └── utils.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.{css,js}]
indent_size = 4

[*.md]
trim_trailing_whitespace = false


================================================
FILE: .gitattributes
================================================
* text=auto


================================================
FILE: .github/workflows/main.yml
================================================
name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  pull_request:
    branches: [ master ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16, 18, 20]

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Setup Node.js environment
        uses: actions/setup-node@v2.5.0
        with:
          node-version: ${{ matrix.node-version }}
          cache: npm
          cache-dependency-path: package-lock.json

      # Runs a single command using the runners shell
      - name: Install
        run: npm ci
      - name: Test
        run: npm test
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run Playwright tests
        run: npm run test:e2e
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30


================================================
FILE: .gitignore
================================================
node_modules
.idea
npm-debug.log
.sass-cache
test/fixtures/files/*
test/fixtures/js/*
example.server.js
example.proxy.js
example.snippet.js
example.js
.DS_store
doc/
.coveralls.yml
coverage/
/screenshots
test/fixtures/multi/
before.json
after.json
bs-config.js
/lodash.custom.min.js
/dist
/cypress/videos
/cypress/screenshots/*
client/dist/index.js
client/dist/index.js.map
client/dist/index.min.js
client/dist/index.min.js.map
node_modules/
/test-results/
/playwright-report/
/playwright/.cache/


================================================
FILE: .travis.yml
================================================
git:
  depth: 2
language: node_js
node_js:
  - "14"
  - "12"
  - "10"


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Browsersync

We'd love for you to contribute to Browsersync and help make it even better than it is
today! Here are the guidelines we'd like you to follow:

 - [Question or Problem?](#question)
 - [Issues and Bugs](#issue)
 - [Tips for a creating a great issue report](#tips)
 - [Feature Requests](#feature)
 - [Pull Requests](#pull)
 - [Coding Rules](#rules)
 - [Thank you](#thanks)

## <a name="question"></a> Got a Question or Problem?

If you have questions about how to *use* Browsersync, or about your particular setup, please
ask on [Stack Overflow](http://stackoverflow.com/). We're trying to keep the Issues thread
for actual bugs with code & implementation.

## <a name="issue"></a> Found an Issue?
On that note, if you think you *have* found a bug in Browsersync, please report
it via [Github Issues](https://github.com/BrowserSync/browser-sync/issues).

## <a name="tips"></a> Tips for a creating a great issue report

Whilst we do try to look at each and every issue as soon as possible, there are certain
aspects about your report that will determine how quickly/deeply we'll delve into it. A great
issue will contain at least the following:

* Operating System + Version
* Use case for Browsersync - are you using the built-in server, proxying your own server, or just using the snippet mode?
* Example configuration - show us your full `gulpfile.js`, `Gruntfile.js`, `bs-config.js` or any other code related to how you're using
Browsersync. If we have to respond to your very first issue report with "please provide information about how you're using Browsersync"
then it's very likely to fall to the bottom of the heap. Help us out by providing as much detail as possible!
* Provide a reduced test case. "Browsersync is not working with my app" is far less helpful than "Here's a example project showing the problem".
An example project might contain a single `index.html` file with some JS/CSS from CDNs & a short description of the issue. If we
 can just pull a repo/gist and see the problem for ourselves, your issue will jump straight to the top of the stack.
* Screencast or GIF - not always appropriate, but can be very helpful where possible. (non-issue related gifs are always welcome, we'll often
respond with something from giphy :p)

## <a name="feature"></a> Want a Feature?
You can request a new feature by submitting an issue to our [Github Issues](https://github.com/BrowserSync/browser-sync/issues) page.
Prefix the title of your issue with "Feature Request:".

## <a name="docs"></a> Want a Doc Fix?
Head over to the [Browsersync Website Repo](https://github.com/BrowserSync/browsersync.github.io) & submit issues there.

## <a name="pull"></a> Submitting a Pull Request
Pull requests should always be branched off the main **Master** branch. (There's no guarantee that what lives on the develop
branch will ever make it back to master, I do a **lot** of experimentation).

**Never** commit directly to the master branch, instead create a new branch and submit a PR. This applies to users who have write access also.

**Note:** If your first PR is merged, you'll get write access to all Browsersync repos.

## <a name="rules"></a> Coding Advice
To ensure consistency throughout the source code, keep these rules in mind as you are working. 

* If you're not sure how to provide tests for a feature or bug fix, you should still submit it and we'll help you complete the PR in one of the following ways:
  * we can advise you how to go about it
  * we can write the test, and then explain them to you.
* This project has a [.editorconfig](.editorconfig) file to help with code style; go to [EditorConfig.org](http://editorconfig.org) and download the plugin for your IDE.
* Don't introduce any extra 3rd party libraries unless you're creating a brand new feature that requires it.
* Try to keep your code simple and readable.
* Improve my code! Browsersync has a lot of moving parts and I don't pretend to be skilled in any particular area.
If *you* have particular experience though, then feel free to rip my code apart and tell me a better way to do something - I'll be extremely grateful (as will the growing number of users!).

## <a name="thanks"></a> Thank you!
If you contribute to Browsersync, or any other Open Source project, you're awesome! This project has been vastly improved
 by community input & contributions and we look forward to continuing that trend.


================================================
FILE: ISSUE_TEMPLATE.md
================================================
### Issue details

_Please provide issue details here_.

### Steps to reproduce/test case

_Please provide necessary steps for reproduction of this issue, or better the
reduced test case (without any external dependencies)_.

### Please specify which version of Browsersync, node and npm you're running

- Browsersync [    ]
- Node        [    ]
- Npm         [    ]

### Affected platforms

- [ ] linux
- [ ] windows
- [ ] OS X
- [ ] freebsd
- [ ] solaris
- [ ] other _(please specify which)_

### Browsersync use-case

- [ ] API
- [ ] Gulp
- [ ] Grunt
- [ ] CLI

### If CLI, please paste the entire command below

{cli command here}

### for all other use-cases, (gulp, grunt etc), please show us exactly how you're using Browsersync

{Browsersync init code here}


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [2015] [Shane Osbourne]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
<p align="center">
<a href="https://www.npmjs.com/package/browser-sync" title="NPM version">
 <img src="https://img.shields.io/npm/v/browser-sync.svg?style=flat-square" />
</a>
<a href="https://www.npmjs.com/package/browser-sync">
 <img src="https://img.shields.io/npm/dm/browser-sync.svg?style=flat-square" />
</a>
</p>
<p align="center"><a href="https://www.browsersync.io"><img src="https://raw.githubusercontent.com/BrowserSync/browsersync.github.io/master/public/img/logo-gh.png" /></a></p>
<p align="center">Keep multiple browsers & devices in sync when building websites.</p>
<p align="center">Follow <a href="https://twitter.com/browsersync">@Browsersync</a> on twitter for news & updates.</p>
<p align="center">Ask questions on <a href="https://discord.gg/2d2xUThp">Discord</a></p>

## Features

Please visit [browsersync.io](https://browsersync.io) for a full run-down of features

## Requirements

Browsersync works by injecting an asynchronous script tag (`<script async>...</script>`) right after the `<body>` tag
during initial request. In order for this to work properly the `<body>` tag must be present. Alternatively you
can provide a custom rule for the snippet using [snippetOptions](https://www.browsersync.io/docs/options/#option-snippetOptions)

## Upgrading from 1.x to 2.x ?
Providing you haven't accessed any internal properties, everything will just work as
there are no breaking changes to the public API. Internally however, we now use an
immutable data structure for storing/retrieving options. So whereas before you could access urls like this...

```js
browserSync({server: true}, function(err, bs) {
  console.log(bs.options.urls.local);
});
```

... you now access them in the following way:

```js
browserSync({server: true}, function(err, bs) {
  console.log(bs.options.getIn(["urls", "local"]));
});
```

## Install and trouble shooting

[browsersync.io docs](https://browsersync.io)

## Integrations / recipes

[Browsersync recipes](https://github.com/Browsersync/recipes)


## Support

If you've found Browser-sync useful and would like to contribute to its continued development & support, please feel free to send a donation of any size - it would be greatly appreciated!

[Support via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=shakyshane%40gmail%2ecom&lc=US&item_name=browser%2dsync)

## Supported by

Originally supported by [JH](https://www.wearejh.com) - they provided financial support as well as access to a professional designer to help with Branding.

Apache 2
Copyright (c) 2021 Shane Osbourne


================================================
FILE: changelog.js
================================================
const {execSync} = require('child_process');
let [start, end] = process.argv.slice(2);
if (!start || !end)  {
    console.error('Must provide start and end tags');
    console.error('  eg: v1.0 HEAD');
    console.error('  eg: v1.0 v2.0');
    process.exit(1);
}
const separator = `===END===`;
const res = execSync(`git log -E --format=%H%n%s%b===END=== ${start}..${end}`);
const sep = res.toString().split(separator);
const output = sep
    .map((item, i) => {
        const [hash, ...body] = getParts(item, i);
        const bodyJoined = body.join('\n');
        return [hash, bodyJoined];
    })
    // .filter(([, body]) => )
    .map(([hash, bodyJoined]) => {
        const hasSection = /^[\w]+: [^ ]/.test(bodyJoined);
        if (hasSection) {
            const [section, body] = bodyJoined.split(/: /);
            return [hash, section, body];
        }
        return [hash, 'misc', bodyJoined];
    })
    .reduce((acc, item) => {
        const [, section] = item;
        if (!acc[section]) {
            acc[section] = [item];
        } else {
            acc[section].push(item);
        }
        return acc;
    }, {});

if (process.argv.indexOf('--json') > -1) {
    console.log(JSON.stringify(output, null, 2));
} else {
    Object.keys(output)
        .map(x => [x, output[x]])
        .forEach(([section, items]) => {
            const header = `**${section}**`;
            console.log(header);
            items.forEach(([hash, section, body]) => {
                console.log(`- ${body} ${hash}`)
            });
            console.log('')
        });
}



function getParts(item, index) {
    const segs = item.split('\n');
    if (index === 0) return segs;
    return segs.slice(1);
}

================================================
FILE: examples/404.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will redirect all 404 requests to a
 * custom 404.html page
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init(
    {
        files: ["app/css/*.css"],
        server: {
            baseDir: "app"
        }
    },
    function(err, bs) {
        bs.addMiddleware("*", function(req, res) {
            res.writeHead(302, {
                location: "404.html"
            });
            res.end("Redirecting!");
        });
    }
);


================================================
FILE: examples/basic/run.js
================================================
const bs = require("../../packages/browser-sync/dist/index").create();
const path = require("path");
const serverDir = path.join(__dirname, "..", "..", "packages/browser-sync/test/fixtures");

bs.init(
    {
        server: serverDir,
        open: false,
        watch: true,
        online: false
    },
    (err, bs) => {
        const message = {
            kind: "ready",
            urls: bs.options.get("urls").toJS(),
            cwd: serverDir
        };
        if (process.send) {
            process.send(message);
        } else {
            console.log(message);
        }
    }
);


================================================
FILE: examples/callback.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example shows how you can access information about Browsersync when it's running
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

var config = {
    proxy: "localhost:8000",
    files: ["app/css/*.css"]
};

browserSync.init(config, function(err, bs) {
    // Full access to Browsersync object here
    console.log(bs.getOption("urls"));
});


================================================
FILE: examples/express.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync express
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` directory as the root
 *  + use any custom routes you have registered with Express
 *
 */

"use strict";

var bs = require("browser-sync").create();
var express = require("express");
var router = express.Router();
var app = express();

/**
 * Catch a route like /user/2324
 * and send a JSON response
 */
router.get("/user/:id", function(req, res) {
    res.send({
        name: "shane",
        pets: ["cat", "hippo"],
        id: req.params.id
    });
});

/**
 * Register the route with Express
 */
app.use(router);

/**
 * Start the Browsersync server and
 * load the express app as middleware
 */
bs.init({
    server: "./app",
    middleware: [app]
});


================================================
FILE: examples/less.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will serve .less files
 * and allow them to be injected as a css file would be.
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    server: ["test/fixtures"],
    open: false,
    watch: true,
    injectFileTypes: ["css", "less"],
    middleware: [
        (req, res, next) => {
            if (req.url.indexOf("bootstrap.less") > -1) {
                res.setHeader("content-type", "text/css");
            }
            next();
        }
    ]
});


================================================
FILE: examples/middleware.css.injection.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync less
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will process less files on the file and auto-inject them into
 * all browsers.
 *
 * Instead of .css, use <link rel='stylesheet' href='main.less'> with the following
 * Configuration to enable a super-fast development workflow.
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    /**
     * Which files to watch for changes
     */
    files: "src/*.less",
    /**
     * Base directory
     */
    server: "app",
    /**
     * Add .less to the list of files that will cause injection (instead of reload)
     */
    injectFileTypes: ["less"],
    /**
     * Catch all requests, if any are for .less files, recompile on the fly and
     * send back a CSS response
     */
    middleware: function(req, res, next) {
        var parsed = require("url").parse(req.url);
        if (parsed.pathname.match(/\.less$/)) {
            return less(parsed.pathname).then(function(o) {
                res.setHeader("Content-Type", "text/css");
                res.end(o.css);
            });
        }
        next();
    }
});

function less(src) {
    var f = require("fs")
        .readFileSync("src/" + src)
        .toString();
    return require("less").render(f);
}


================================================
FILE: examples/notify-styles.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 */

"use strict";

var browserSync = require("../").create();

browserSync.init({
    open: false, // Stop auto open browser
    notify: {
        styles: [
            "display: none;",
            "padding: 6px 15px 3px;",
            "position: fixed;",
            "font-size: 40px;",
            "z-index: 9999;",
            "left: 0px;",
            "bottom: 0px;",
            "color: rgb(74, 74, 74);",
            "background-color: rgb(17, 17, 17);",
            "color: rgb(229, 229, 229);"
        ]
    },
    server: {
        baseDir: "test/fixtures"
    }
});


================================================
FILE: examples/options.snippetOptions.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example shows how you can place the snippet anywhere.
 */

"use strict";

var path = require("path");
var browserSync = require("../packages/browser-sync").create();
var cwd = path.join(__dirname, "..");
var fixtures_dir = path.join(cwd, "packages/browser-sync/test/fixtures");

browserSync.init({
    files: [path.join(fixtures_dir, "css/*.css")],
    server: fixtures_dir,
    snippetOptions: {
        rule: {
            match: /<\/head>/i,
            fn: function (snippet, match) {
                return snippet + match;
            },
        },
    },
});


================================================
FILE: examples/proxy.gzip.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync compression
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will proxy to your existing vhost
 * and serve gzipped responses
 *
 */

"use strict";

var browserSync = require("browser-sync").create();
var compression = require("compression");

browserSync.init({
    files: ["app/css/*.css"],
    proxy: {
        target: "http://yourlocal.dev",
        middleware: compression()
    }
});


================================================
FILE: examples/proxy.headers.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example shows how to specify the proxy headers for each request
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    proxy: {
        target: "localhost:8000",
        reqHeaders: function(config) {
            /**
             * These are the default headers as a guide for you.
             * You can set whatever you want here.
             */
            return {
                host: config.urlObj.host,
                "accept-encoding": "identity",
                agent: false
            };
        }
    }
});


================================================
FILE: examples/proxy.localhost.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will wrap your existing server in a proxy url.
 * Use the new Proxy url to access your site.
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    proxy: "localhost:8000"
});


================================================
FILE: examples/proxy.middleware.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a proxy server and run middlewares
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    proxy: {
        target: "http://yourlocal.dev",
        middleware: function(req, res, next) {
            console.log(req.url);
            next();
        }
    },
    https: true
});


================================================
FILE: examples/proxy.middleware.multi.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a proxy server and run middlewares
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

var fn1 = function(req, res, next) {
    console.log(req.url);
    next();
};

var fn2 = function(req, res, next) {
    console.log(req.headers);
    next();
};

browserSync.init({
    files: ["app/css/*.css"],
    proxy: {
        target: "http://yourlocal.dev",
        middleware: [fn1, fn2]
    },
    https: true
});


================================================
FILE: examples/proxy.proxyRes.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will proxy http://www.bbc.co.uk and
 * add headers to the response *after* it's returned from
 * the server.
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    proxy: {
        target: "http://www.bbc.co.uk",
        proxyRes: [
            function(res) {
                res.headers["cache-control"] = "private";
            }
        ]
    }
});


================================================
FILE: examples/proxy.rewriteRules.advanced.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync serve-static
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will
 *  1. create a proxy server for a live magento website
 *  2. serve static assets from your local `assets` directory
 *  3. rewrite HTML on the fly to make the live site use your local assets
 *
 *      eg:      <link rel="stylesheet" href="http://www.magento-site.com/skin/frontend/rwd/assets/css/core.min.css"></link>
 *      becomes: <link rel="stylesheet" href="//localhost:3000/assets/css/core.css"></link>
 *
 *      eg:      <script src="http://www.magento-site.com/skin/frontend/rwd/assets/js/dist.js"></script>
 *      becomes: <script src="//localhost:3000/assets/js/dist.js"></script>
 *
 *  4. watch files in the assets directory and reload/inject when anything changes
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    proxy: "http://www.magento-site.com",
    files: ["assets"],
    middleware: require("serve-static")("."),
    rewriteRules: [
        {
            match: new RegExp("skin/frontend/rwd/(.+?)(?=['\"])", "g"),
            replace: "assets/$1"
        }
    ]
});


================================================
FILE: examples/proxy.rewriteRules.simple.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync serve-static
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will
 *  1. create a proxy server for a live magento website
 *  2. serve static assets from your local `assets` directory
 *  3. rewrite HTML on the fly to make the live site use your local assets/css/core.css file
 *
 *      eg:      <link rel="stylesheet" href="http://www.magento-site.com/skin/frontend/rwd/assets/css/core.min.css"></link>
 *      becomes: <link rel="stylesheet" href="//localhost:3000/assets/css/core.css"></link>
 *
 *  4. watch files in the assets directory and reload/inject when anything changes
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    proxy: "http://www.magento-site.com",
    files: ["assets"],
    middleware: require("serve-static")("."),
    rewriteRules: [
        {
            match: "skin/frontend/rwd/assets/css/core.min.css",
            replace: "assets/css/core.css"
        }
    ]
});


================================================
FILE: examples/proxy.secure.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a proxy server using https
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    proxy: "https://yourlocal.dev"
});


================================================
FILE: examples/proxy.vhost.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will wrap your existing server in a proxy url.
 * Use the new Proxy url to access your site.
 *
 */

var browserSync = require("browser-sync").create();

browserSync.init({
    files: "app/css/*.css",
    proxy: "yourvhost.dev"
});


================================================
FILE: examples/server.basedir.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` directory as the root
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app"
    }
});


================================================
FILE: examples/server.basedir.mulitple.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` & `dist` directories for serving files
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: ["app", "dist"]
    }
});


================================================
FILE: examples/server.default.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server in the cwd.
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: true
});


================================================
FILE: examples/server.gzip.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync compression
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server with gzip enabled
 *
 */

"use strict";

var browserSync = require("browser-sync").create();
var compression = require("compression");

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app",
        middleware: compression()
    }
});


================================================
FILE: examples/server.http2.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync http2
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server using http2 using the default information & use the `app` directory as the root
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app"
    },
    https: true,
    httpModule: "http2"
});


================================================
FILE: examples/server.latency.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` directory as the root
 *  - any requests beginning with /json will have fake latency applied
 *  - for 3 seconds
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

function fakeLatency(req, res, next) {
    if (req.url.match(/^\/json/)) {
        setTimeout(next, 3000);
    } else {
        next();
    }
}

browserSync.init({
    files: ["app/css/*.css"],
    server: "app",
    middleware: [fakeLatency]
});


================================================
FILE: examples/server.middleware.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` directory as the root
 *  + use your custom middleware. Note: middleware will be added before
 *  any Browsersync middlewares
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app",
        middleware: function(req, res, next) {
            console.log("hi from the middleware");
            next();
        }
    }
});


================================================
FILE: examples/server.middleware.multiple.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server & use the `app` directory as the root
 *  + use your custom middleware. Note: middleware will be added before
 *  any Browsersync middlewares
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app",
        middleware: [
            function(req, res, next) {
                console.log("hi from the first middleware");
                next();
            },
            function(req, res, next) {
                console.log("hi from the second middleware");
                next();
            }
        ]
    }
});


================================================
FILE: examples/server.proxy.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync express http-proxy-middleware
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server in the cwd whilst proxying requests
 * to /api to a backend
 *
 */

"use strict";

var browserSync = require("browser-sync").create();
var express = require('express');
var proxy = require('http-proxy-middleware');

var app = express();

app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));

browserSync.init({
    server: ".",
    watch: true,
    middleware: [app]
});


================================================
FILE: examples/server.secure.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server using https using the default information & use the `app` directory as the root
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app"
    },
    https: true
});


================================================
FILE: examples/server.secure.pfx.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server using https using a PFX certificate & use the `app` directory as the root
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    files: ["app/css/*.css"],
    server: {
        baseDir: "app"
    },
    https: {
        pfx: "certs/browsersync.pfx"
    }
});


================================================
FILE: examples/server.watch.js
================================================
/**
 *
 * Install:
 *      npm install browser-sync
 *
 * Run:
 *      node <yourfile.js>
 *
 * This example will create a server using https using the default information & use the `app` directory as the root
 *
 */

"use strict";

var browserSync = require("browser-sync").create();

browserSync.init({
    server: "test/fixtures",
    watch: true
});


================================================
FILE: examples/snippet/index.html
================================================
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta
            name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
        />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
    </head>
    <body>
        <h1>Hello world</h1>
    </body>
</html>


================================================
FILE: examples/snippet/run.js
================================================
const bs = require("../../packages/browser-sync/dist/index").create();
bs.init(
    {
        server: ".",
        open: false,
        notify: false,
        watch: true,
        snippetOptions: {
            rule: {
                match: /<\/head>/i,
                fn: function(snippet, match) {
                    return snippet + match;
                }
            }
        }
    },
    (err, bs) => {
        const message = {
            kind: "ready",
            urls: bs.options.get("urls").toJS(),
            cwd: __dirname
        };
        if (process.send) {
            process.send(message);
        } else {
            console.log(message);
        }
    }
);


================================================
FILE: lerna.json
================================================
{
  "packages": [
    "packages/*"
  ],
  "version": "3.0.4"
}


================================================
FILE: nx.json
================================================
{
  "tasksRunnerOptions": {
    "default": {
      "runner": "nx/tasks-runners/default",
      "options": {
        "cacheableOperations": [
          "build"
        ]
      }
    }
  },
  "targetDefaults": {
    "build": {
      "dependsOn": [
        "^build"
      ]
    }
  }
}


================================================
FILE: package.json
================================================
{
	"private": true,
	"name": "browser-sync-mono",
	"scripts": {
		"bootstrap": "lerna bootstrap",
		"postinstall": "npm run bootstrap",
		"test": "lerna run build && lerna run test --scope browser-sync",
		"test:e2e": "echo skipping cypress",
		"test:playwright": "playwright test"
	},
	"devDependencies": {
		"lerna": "^6.1.0"
	},
	"dependencies": {
		"@playwright/test": "^1.43.0",
		"rxjs": "^7.5.4",
		"zod": "^3.22.2"
	},
	"nx": {}
}


================================================
FILE: packages/browser-sync/.gitignore
================================================
/dist/*


================================================
FILE: packages/browser-sync/.prettierignore
================================================


================================================
FILE: packages/browser-sync/certs/gen.sh
================================================
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
cp server.key server.key.copy
openssl rsa -in server.key.copy -out server.key
rm server.key.copy


================================================
FILE: packages/browser-sync/certs/server.crt
================================================
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQCir/8eGDIE/jANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJH
QjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE3MDQxMDExNDcyNloXDTI3MDQwODExNDcyNlowRTELMAkG
A1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AMRLR2crKB4X/9pM3gR641iDscZWW3aqo70nUDxzo5Bhk8uupqz0EfdRoCLCUeQi
xVp3HJ1HqnilMW7dETGGkDHKdxJRjrkBrYHhE3Kw/LCC4tEb400F6Ikm6OudVPIB
P+CuwfNAw70KHSx/CtIrbTz0HhDC6XN0azp39pDLRBnWWluz3iU+rFLMx7YT2Q8k
1nQAwcXkzLjeU7txAt2pYGQUgvBQETO5RI7QQ0CmwaV4gfHWGABBTX34WQun7g1Q
YukrG3/4fVeNLzGW787FKCvL07BTymJTwXXbTTPXg4chw9p+YkLLPrr+AOVe/PF1
MJppDT3gKdKMHFo3vMycUf0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAEVmUYRrT
fCQmBDox3evqj4n8dJVStjgdw/7BPkm49SmGtaxsST/eUSGwT7dTvZBLov6BK/OW
+arhHZIvUY/DXlsV4NfCM4TK8KVefrwgd8ZsfQJW73L+FB0IOAY/6s+YKHm/wQGF
ptSOycJvEltsqfIegtYcvvD6c6SkSOvqApaF+Ai10+yiLe20KyOvM3PefZLV7mFE
0zCNyglZ75HftvHHV0wh82T2Et/R+txH+6dTwh065Dd6rrDzljtcAd2HC7B26ERK
dA2zJd9Y4eMz8osacmG/afVuR9rqtFGwdyZ1Kb5xQRzGWlrjvSmAFUx9W9iA4Ilv
3+56a5njSTFYKw==
-----END CERTIFICATE-----


================================================
FILE: packages/browser-sync/certs/server.csr
================================================
-----BEGIN CERTIFICATE REQUEST-----
MIICoTCCAYkCAQAwRTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMRLR2crKB4X/9pM3gR641iDscZWW3aqo70nUDxz
o5Bhk8uupqz0EfdRoCLCUeQixVp3HJ1HqnilMW7dETGGkDHKdxJRjrkBrYHhE3Kw
/LCC4tEb400F6Ikm6OudVPIBP+CuwfNAw70KHSx/CtIrbTz0HhDC6XN0azp39pDL
RBnWWluz3iU+rFLMx7YT2Q8k1nQAwcXkzLjeU7txAt2pYGQUgvBQETO5RI7QQ0Cm
waV4gfHWGABBTX34WQun7g1QYukrG3/4fVeNLzGW787FKCvL07BTymJTwXXbTTPX
g4chw9p+YkLLPrr+AOVe/PF1MJppDT3gKdKMHFo3vMycUf0CAwEAAaAXMBUGCSqG
SIb3DQEJBzEIDAYxMjM0NTYwDQYJKoZIhvcNAQELBQADggEBABlVUaWK/UUovgPZ
+rqNG8/j6aggSCCye9CkauLB/WqhQFfLl9lWTYdUVmWweNU0SJwDU9lWF/TngipF
RZs6501DkXKxaDT9/3JYg4lRz6zHLy+a77pavJOeN0+cFAPZZuGyxZvYHFYPVSVH
EeJL6bO/nZ/ARgIp0YNkQblDarxq1ARj7YT1Z24D5KgO1kQ55+fCY/wtct8TLGk9
ujvWBbFEBSrJCDjRQeSctlP5qG8yfeJqZwZzo4PQMUwABhNLGUz0z0ceK8W1QnOm
T+nCN5Fni04wO4dAZvYPp6wmU0Gpi2XBihbFl9CT3B5AmJmM8hQVpuQlmXeXT0FO
pOZFpko=
-----END CERTIFICATE REQUEST-----


================================================
FILE: packages/browser-sync/certs/server.key
================================================
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAxEtHZysoHhf/2kzeBHrjWIOxxlZbdqqjvSdQPHOjkGGTy66m
rPQR91GgIsJR5CLFWnccnUeqeKUxbt0RMYaQMcp3ElGOuQGtgeETcrD8sILi0Rvj
TQXoiSbo651U8gE/4K7B80DDvQodLH8K0ittPPQeEMLpc3RrOnf2kMtEGdZaW7Pe
JT6sUszHthPZDyTWdADBxeTMuN5Tu3EC3algZBSC8FARM7lEjtBDQKbBpXiB8dYY
AEFNffhZC6fuDVBi6Ssbf/h9V40vMZbvzsUoK8vTsFPKYlPBddtNM9eDhyHD2n5i
Qss+uv4A5V788XUwmmkNPeAp0owcWje8zJxR/QIDAQABAoIBADbeT/wvnQwkazkL
CXg5HXltfnDRTMmz0wcZiR0MueiuzdA+ZoqrwqXeJCPzK07YxU+PQelY0fbdPh8e
HiM42O+CB5yQPZPLO0O1tWj2vftc6qfG4tdx0lkcDjlmBguLe96DGuWy8cPSousA
K/cpemRyXEEVKopCPYLfa4V3u/Z4be2U/39KNjVkHFhSdSYQl6ferhEfUPwTPi7O
7l1/QUBabqN5FzNc2TeMVhhcJkXtYqF3RxGsaRfT0lK/j2hpbX7Bn2T0CfA/40jY
2OCERqFPfZWx/ShTT52b3fyX/FEua7Nukq/MZdYZou63dDIjCQQyTJSflX6lVojO
SuUoumECgYEA6CSkLiKcRLlTfec3LkjqkWtXR5ibL33g/H1fsZEQKFOyMbIXpUkX
Hybpku8NGeetjKynO3yRirp+NiBHGPn3cHc9WJ5GGG1ew9hRQ9QzyC3Tit15TDbu
J8i50/MaQHZSiUCnPQ/ceIZCNz8STcsEz87o/7utRLJKOvIIAPj+/8kCgYEA2Hd/
v5oUroMRbtzPtMJDMHiGEQyNxEGDNqcuxgXSmiEEqPLfk2qR3yLffzA9UQOg4wkX
/dSXsyomPriKWTvADXu1lNdkPGmW/1tk+onnHu6qgOalva30ZKhtteVjUqxEJEke
mHhNHyIVuj6lExLw9LZhVvzoOi+aj4AD+DRS4pUCgYBEtuveOCJ3eUAMiY9c5PqB
9vsL11FAOouJUXcs8VqOBVA+w4+aPktYzkTfWGFRZLGLbWPHCPVv0gof7Wf+Laef
o7wF6junaWBeqj5LzJlTTLVMaohIFg5iuli/Mzt3D08ZD4kxWuuQxXT+M24wlsKi
3IU9hYkhR4EPd6sE1q9seQKBgEpQRBAgModywbJgpgH1SyHBzqzdtXGx1/0USg97
gkCdoz7pGm4+gNOs4jOE+Rft+fbXcWAX8vh0OOsBaaWWyKkYVk9B3syKp2cFFlaY
rzrETs6v4CiNJsDDvd5bYMzKDR6z54gKjNdqWTE2Pm+c6hHo5uP5MTSAkTxAg5xb
QjU9AoGAaYPXlm3IKVO12FgNg/ffduooi0PKa1yRNJGnhpQKNvBQXs8eV+CQ83aK
kQHUExuJDrOfsC2iwF/2ZywXhEfbhL7ar0aw5zrhV+r7qvYFWxu/YoLoNVMDByw5
wAN0oIbsGWYmtIIti8+b9IcacTbAZ79ctlTLb1HCyPMosHxDkv8=
-----END RSA PRIVATE KEY-----


================================================
FILE: packages/browser-sync/cli-options/opts.init.json
================================================
{}

================================================
FILE: packages/browser-sync/cli-options/opts.recipe.json
================================================
{
  "output": {
    "alias": "o",
    "desc": "Specify an output directory"
  }
}


================================================
FILE: packages/browser-sync/cli-options/opts.reload.json
================================================
{
  "files": {
    "desc": "File paths to reload",
    "type": "array",
    "alias": "f"
  },
  "port": {
    "alias": "p",
    "type": "number",
    "desc": "Target a running instance by port number"
  },
  "url": {
    "alias": "u",
    "desc": "Provide the full the url to the running Browsersync instance"
  }
}


================================================
FILE: packages/browser-sync/cli-options/opts.start.json
================================================
{
  "server": {
    "alias": "s",
    "desc": "Run a Local server (uses your cwd as the web root)"
  },
  "cwd": {
    "type": "string",
    "desc": "Working directory"
  },
  "json": {
    "type": "boolean",
    "desc": "If true, certain logs will output as json only"
  },
  "serveStatic": {
    "type": "array",
    "alias": "ss",
    "desc": "Directories to serve static files from"
  },
  "port": {
    "type": "number",
    "desc": "Specify a port to use"
  },
  "proxy": {
    "alias": "p",
    "desc": "Proxy an existing server",
    "example": "$0 shane is cool"
  },
  "ws": {
    "type": "boolean",
    "desc": "Proxy mode only - enable websocket proxying"
  },
  "browser": {
    "type": "array",
    "alias": "b",
    "desc": "Choose which browser should be auto-opened"
  },
  "watch": {
    "type": "boolean",
    "alias": "w",
    "desc": "Watch files"
  },
  "ignore": {
    "type": "array",
    "desc": "Ignore patterns for file watchers"
  },
  "files": {
    "type": "array",
    "alias": "f",
    "desc": "File paths to watch"
  },
  "index": {
    "type": "string",
    "desc": "Specify which file should be used as the index page"
  },
  "plugins": {
    "type": "array",
    "desc": "Load Browsersync plugins"
  },
  "extensions": {
    "type": "array",
    "desc": "Specify file extension fallbacks"
  },
  "startPath": {
    "type": "string",
    "desc": "Specify the start path for the opened browser"
  },
  "single": {
    "type": "boolean",
    "desc": "If true, the connect-history-api-fallback middleware will be added"
  },
  "https": {
    "desc": "Enable SSL for local development"
  },
  "directory": {
    "type": "boolean",
    "desc": "Show a directory listing for the server"
  },
  "tunnel": {
    "desc": "Use a public URL"
  },
  "open": {
    "type": "string",
    "desc": "Choose which URL is auto-opened (local, external or tunnel), or provide a url"
  },
  "cors": {
    "type": "boolean",
    "desc": "Add Access Control headers to every request"
  },
  "config": {
    "type": "string",
    "alias": "c",
    "desc": "Specify a path to a configuration file"
  },
  "host": {
    "desc": "Specify a hostname to use"
  },
  "listen": {
    "desc": "Specify a hostname bind to (this will prevent binding to all interfaces)"
  },
  "logLevel": {
    "desc": "Set the logger output level (silent, info or debug)"
  },
  "reload-delay": {
    "type": "number",
    "desc": "Time in milliseconds to delay the reload event following file changes"
  },
  "reload-debounce": {
    "type": "number",
    "desc": "Restrict the frequency in which browser:reload events can be emitted to connected clients"
  },
  "ui-port": {
    "type": "number",
    "desc": "Specify a port for the UI to use"
  },
  "watchEvents": {
    "type": "array",
    "desc": "Specify which file events to respond to"
  },
  "no-notify": {
    "desc": "Disable the notify element in browsers"
  },
  "no-open": {
    "desc": "Don't open a new browser window"
  },
  "no-snippet": {
    "desc": "Disable the snippet injection"
  },
  "no-online": {
    "desc": "Force offline usage"
  },
  "no-ui": {
    "desc": "Don't start the user interface"
  },
  "no-ghost-mode": {
    "desc": "Disable Ghost Mode"
  },
  "no-inject-changes": {
    "desc": "Reload on every file change"
  },
  "no-reload-on-restart": {
    "desc": "Don't auto-reload all browsers following a restart"
  }
}


================================================
FILE: packages/browser-sync/lib/args.js
================================================
"use strict";

/**
 * The purpose of this function is
 * to handle back-backwards compatibility
 * @param {Object} args
 * @returns {{config: {}, cb: *}}
 */
module.exports = function(args) {
    var config = {};
    var cb;

    switch (args.length) {
        case 1:
            if (isFilesArg(args[0])) {
                config.files = args[0];
            } else if (typeof args[0] === "function") {
                cb = args[0];
            } else {
                config = args[0];
            }

            break;

        case 2:
            // if second is a function, first MUST be config
            if (typeof args[1] === "function") {
                config = args[0] || {};
                cb = args[1];
            } else {
                if (args[1] === null || args[1] === undefined) {
                    config = args[0];
                } else {
                    // finally, second arg could be a plain object for config
                    config = args[1] || {};

                    if (!config.files) {
                        config.files = args[0];
                    }
                }
            }

            break;

        case 3:
            config = args[1] || {};

            if (!config.files) {
                config.files = args[0];
            }

            cb = args[2];
    }

    return {
        config: config,
        cb: cb
    };
};

/**
 * Files args were only ever strings or arrays
 * @param arg
 * @returns {*|boolean}
 */
function isFilesArg(arg) {
    return Array.isArray(arg) || typeof arg === "string";
}


================================================
FILE: packages/browser-sync/lib/async-tasks.js
================================================
var async = require("./async");

module.exports = [
    {
        step: "Finding an empty port",
        fn: async.getEmptyPort
    },
    {
        step: "Getting an extra port for Proxy",
        fn: async.getExtraPortForProxy
    },
    {
        step: "Checking online status",
        fn: async.getOnlineStatus
    },
    {
        step: "Resolve user plugins from options",
        fn: async.resolveInlineUserPlugins
    },
    {
        step: "Set Urls and other options that rely on port/online status",
        fn: async.setOptions
    },
    {
        step: "Setting Internal Events",
        fn: async.setInternalEvents
    },
    {
        step: "Setting file watchers",
        fn: async.setFileWatchers
    },
    {
        step: "Merging middlewares from core + plugins",
        fn: async.mergeMiddlewares
    },
    {
        step: "Starting the Server",
        fn: async.startServer
    },
    {
        step: "Starting the HTTPS Tunnel",
        fn: async.startTunnel
    },
    {
        step: "Starting the web-socket server",
        fn: async.startSockets
    },
    {
        step: "Starting the UI",
        fn: async.startUi
    },
    {
        step: "Merge UI settings",
        fn: async.mergeUiSettings
    },
    {
        step: "Init user plugins",
        fn: async.initUserPlugins
    }
];


================================================
FILE: packages/browser-sync/lib/async.js
================================================
"use strict";

var _ = require("./lodash.custom");
var Immutable = require("immutable");

var utils = require("./utils");
var pluginUtils = require("./plugins");
var connectUtils = require("./connect-utils");
var chalk       = require("chalk");

module.exports = {
    /**
     * BrowserSync needs at least 1 free port.
     * It will check the one provided in config
     * and keep incrementing until an available one is found.
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    getEmptyPort: function(bs, done) {
        utils.getPorts(bs.options, function(err, port) {
            if (err) {
                return utils.fail(true, err, bs.cb);
            }
            bs.debug("Found a free port: %s", chalk.magenta(port));
            done(null, {
                options: {
                    port: port
                }
            });
        });
    },
    /**
     * If the running mode is proxy, we'll use a separate port
     * for the Browsersync web-socket server. This is to eliminate any issues
     * with trying to proxy web sockets through to the users server.
     * @param bs
     * @param done
     */
    getExtraPortForProxy: function(bs, done) {
        /**
         * An extra port is not needed in snippet/server mode
         */
        if (bs.options.get("mode") !== "proxy") {
            return done();
        }

        /**
         * Web socket support is disabled by default
         */
        if (!bs.options.getIn(["proxy", "ws"])) {
            return done();
        }

        /**
         * Use 1 higher than server port by default...
         */
        var socketPort = bs.options.get("port") + 1;

        /**
         * Or use the user-defined socket.port option instead
         */
        if (bs.options.hasIn(["socket", "port"])) {
            socketPort = bs.options.getIn(["socket", "port"]);
        }

        utils.getPort(
            bs.options.get("listen", "localhost"),
            socketPort,
            null,
            function(err, port) {
                if (err) {
                    return utils.fail(true, err, bs.cb);
                }
                done(null, {
                    optionsIn: [
                        {
                            path: ["socket", "port"],
                            value: port
                        }
                    ]
                });
            }
        );
    },
    /**
     * Some features require an internet connection.
     * If the user did not provide either `true` or `false`
     * for the online option, we will attempt to resolve www.google.com
     * as a way of determining network connectivity
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    getOnlineStatus: function(bs, done) {
        if (
            _.isUndefined(bs.options.get("online")) &&
            _.isUndefined(process.env.TESTING)
        ) {
            require("dns").resolve("www.google.com", function(err) {
                var online = false;
                if (err) {
                    bs.debug(
                        "Could not resolve www.google.com, setting %s",
                        chalk.magenta("online: false")
                    );
                } else {
                    bs.debug(
                        "Resolved www.google.com, setting %s",
                        chalk.magenta("online: true")
                    );
                    online = true;
                }
                done(null, {
                    options: {
                        online: online
                    }
                });
            });
        } else {
            done();
        }
    },
    /**
     * Try to load plugins that were given in options
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    resolveInlineUserPlugins: function(bs, done) {
        var plugins = bs.options
            .get("plugins")
            .map(pluginUtils.resolvePlugin)
            .map(pluginUtils.requirePlugin);

        plugins.forEach(function(plugin) {
            if (plugin.get("errors").size) {
                return logPluginError(plugin);
            }
            var jsPlugin = plugin.toJS();
            jsPlugin.options = jsPlugin.options || {};
            jsPlugin.options.moduleName = jsPlugin.moduleName;
            bs.registerPlugin(jsPlugin.module, jsPlugin.options);
        });

        function logPluginError(plugin) {
            utils.fail(true, plugin.getIn(["errors", 0]), bs.cb);
        }

        done();
    },
    /**
     *
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    setOptions: function(bs, done) {
        done(null, {
            options: {
                urls: utils.getUrlOptions(bs.options),
                snippet: connectUtils.enabled(bs.options)
                    ? connectUtils.scriptTags(bs.options)
                    : false,
                scriptPaths: Immutable.fromJS(
                    connectUtils.clientScript(bs.options, true)
                ),
                files: bs.pluginManager.hook(
                    "files:watch",
                    bs.options.get("files"),
                    bs.pluginManager.pluginOptions
                )
            }
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    setInternalEvents: function(bs, done) {
        require("./internal-events")(bs);
        done();
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    setFileWatchers: function(bs, done) {
        done(null, {
            instance: {
                watchers: bs.pluginManager.get("file:watcher")(bs)
            }
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    mergeMiddlewares: function(bs, done) {
        done(null, {
            options: {
                middleware: bs.pluginManager.hook(
                    "server:middleware",
                    bs.options.get("middleware")
                )
            }
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    startServer: function(bs, done) {
        var server = bs.pluginManager.get("server")(bs);

        done(null, {
            instance: {
                server: server.server,
                app: server.app
            }
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    startTunnel: function(bs, done) {
        if (bs.options.get("tunnel") && bs.options.get("online")) {
            var localTunnel = require("./tunnel");
            localTunnel(bs, function(err, tunnel) {
                if (err) {
                    if (err.code === "MODULE_NOT_FOUND") {
                        return utils.fail(true, err, bs.cb);
                    }
                    return done(err);
                } else {
                    return done(null, {
                        optionsIn: [
                            {
                                path: ["urls", "tunnel"],
                                value: tunnel.url
                            }
                        ],
                        instance: {
                            tunnel: tunnel
                        }
                    });
                }
            });
        } else {
            done();
        }
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    startSockets: function(bs, done) {
        var clientEvents = bs.pluginManager.hook(
            "client:events",
            bs.options.get("clientEvents").toJS()
        );

        // Start the socket, needs an existing server.
        var io = bs.pluginManager.get("socket")(bs.server, clientEvents, bs);

        done(null, {
            instance: {
                io: io
            },
            options: {
                clientEvents: Immutable.fromJS(clientEvents)
            }
        });
    },
    /**
     *
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    startUi: function(bs, done) {
        var PLUGIN_NAME = "UI";
        var userPlugins = bs.getUserPlugins();
        var ui = bs.pluginManager.get(PLUGIN_NAME);
        var uiOpts = bs.options.get("ui");

        if (!uiOpts || uiOpts.get("enabled") === false) {
            return done();
        }

        // if user provided a UI, use it instead
        if (
            userPlugins.some(function(item) {
                return item.name === PLUGIN_NAME;
            })
        ) {
            uiOpts = bs.options
                .get("ui")
                .mergeDeep(
                    Immutable.fromJS(
                        bs.pluginManager.pluginOptions[PLUGIN_NAME]
                    )
                );
        }

        /**
         * Append the 'listen' option
         */
        const opts = uiOpts.update(uiOpts => {
            const listen = bs.options.get("listen");
            if (listen) {
                return uiOpts.set("listen", listen);
            }
            return uiOpts;
        });

        return ui(opts.toJS(), bs, function(err, ui) {
            if (err) {
                return done(err);
            }
            done(null, {
                instance: {
                    ui: ui
                }
            });
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    mergeUiSettings: function(bs, done) {
        if (!bs.ui) {
            return done();
        }

        done(null, {
            options: {
                urls: bs.options.get("urls").merge(bs.ui.options.get("urls"))
            }
        });
    },
    /**
     * @param {BrowserSync} bs
     * @param {Function} done
     */
    initUserPlugins: function(bs, done) {
        bs.pluginManager.initUserPlugins(bs);

        done(null, {
            options: {
                userPlugins: bs.getUserPlugins()
            }
        });
    }
};


================================================
FILE: packages/browser-sync/lib/bin.ts
================================================
#!/usr/bin/env node
const startOpts = require("../cli-options/opts.start.json");
const reloadOpts = require("../cli-options/opts.reload.json");
const recipeOpts = require("../cli-options/opts.recipe.json");
const chalk      = require("chalk");
const pkg = require("../package.json");
import * as utils from "./utils";
import { resolve } from "path";
import { existsSync } from "fs";
import { logger } from "./logger";
import { printErrors } from "./cli/cli-options";

export enum BsErrorLevels {
    Fatal = "Fatal"
}

export enum BsErrorTypes {
    PathNotFound = "PathNotFound",
    HostAndListenIncompatible = "HostAndListenIncompatible"
}

export type BsErrors = BsError[];
export interface BsError {
    type: BsErrorTypes;
    level: BsErrorLevels;
    errors: BsErrorItem[];
}
export interface BsErrorItem {
    error: Error;
    meta?(...args): string[];
}

/**
 * Handle cli input
 */
if (!module.parent) {
    runFromCli();
}

function freshYargs() {
  return require("yargs")(process.argv.slice(2));
}

function runFromCli() {
    const yargs = freshYargs()
        .command("start", "Start the server")
        .command("init", "Create a configuration file")
        .command("reload", "Send a reload event over HTTP protocol")
        .command("recipe", "Generate the files for a recipe")
        .version(pkg.version)
        .help(false)
        .epilogue(
            [
                "For help running a certain command, type <command> --help",
                "  $0 start --help",
                "",
                "You can run a static server by providing a path(s) directly",
                "  $0 app/src app/tmp",
                "",
                "If the directory contains a 'index.html' file, you can omit any input",
                "  $0",
                "",
                "You can run the proxy in this manner too",
                "  $0 https://example.com",
                "",
                "To run a proxy, whilst also serving static files",
                "  $0 https://example.com htdocs/themes/example"
            ].join("\n")
        );

    const argv = yargs.argv;
    const input = argv._;
    const command = input[0];
    const valid = ["start", "init", "reload", "recipe"];

    if (valid.indexOf(command) > -1) {
        return handleIncoming(command, freshYargs());
    }

    if (input.length) {
        return handleNoCommand(argv, input, freshYargs());
    }

    if (existsSync("index.html")) {
        return handleNoCommand(argv, ["."], freshYargs());
    }

    yargs.showHelp();
}

/**
 * Feature: If no command was specified, try to do the 'right thing'
 *
 * If paths were given, start the server
 *          eg: browser-sync app/code app/design
 * is equal to: browser-sync start --server app/code app/design
 *
 *           eg: browser-sync http://example.com
 * is equal to: browser-sync start --proxy http://example.com
 *
 *           eg: browser-sync http://example.com themes/example
 * is equal to: browser-sync start --proxy http://example.com --ss themes/example
 *
 * @param argv
 * @param input
 * @returns {any}
 */
function handleNoCommand(argv, input, yargs) {
    const processed = processStart(yargs);
    const paths = input.map(path => {
        const resolved = resolve(path);
        const isUrl = /^https?:\/\//.test(path);
        return {
            isUrl,
            userInput: path,
            resolved,
            errors: isUrl ? [] : pathErrors(path, resolved)
        };
    });

    const withErrors = paths.filter(item => item.errors.length);
    const withoutErrors = paths.filter(item => item.errors.length === 0);

    if (withErrors.length) {
        withErrors.forEach(item => {
            logger.unprefixed("error", printErrors(item.errors));
        });
        return process.exit(1);
    }

    const serveStaticPaths = withoutErrors
        .filter(item => item.isUrl === false)
        .map(item => item.resolved);

    const urls = withoutErrors
        .filter(item => item.isUrl === true)
        .map(item => item.userInput);

    /**
     * If a URL was given, switch to proxy mode and use
     * any other paths as serveStatic options
     */
    if (urls.length) {
        const proxy = urls[0];
        const config = {
            ...processed,
            proxy,
            serveStatic: serveStaticPaths
        };
        return handleCli({ cli: { flags: config, input: ["start"] } });
    }

    /**
     * if NO urls were given switch directly to server mode
     * @type {{server: {baseDir: any}}}
     */
    const config = {
        ...processed,
        server: { baseDir: serveStaticPaths }
    };

    return handleCli({ cli: { flags: config, input: ["start"] } });
}

/**
 * @param {{cli: object, [whitelist]: array, [cb]: function}} opts
 * @returns {*}
 */
function handleCli(opts) {
    opts.cb = opts.cb || utils.defaultCallback;
    const m = require(`./cli/command.${opts.cli.input[0]}`);
    if (m.default) {
        return m.default(opts);
    }
    return m(opts);
}

export default handleCli;

function processStart(yargs) {
    return yargs
        .usage("Usage: $0 start [options]")
        .options(startOpts)
        .example("$0 start -s app", "- Use the App directory to serve files")
        .example("$0 start -p www.bbc.co.uk", "- Proxy an existing website")
        .default("cwd", () => process.cwd())
        .argv;
}

/**
 * @param {string} command
 * @param {object} yargs
 * @param cwd
 */
function handleIncoming(command, yargs) {
    let out;
    if (command === "start") {
        out = processStart(yargs);
    }
    if (command === "init") {
        out = yargs
            .usage("Usage: $0 init")
            .example("$0 init")
            .default("cwd", () => process.cwd())
            .help().argv;
    }
    if (command === "reload") {
        out = yargs
            .usage("Usage: $0 reload")
            .options(reloadOpts)
            .example("$0 reload")
            .example("$0 reload --port 4000")
            .default("cwd", () => process.cwd())
            .argv;
    }
    if (command === "recipe") {
        out = yargs
            .usage("Usage: $0 recipe <recipe-name>")
            .option(recipeOpts)
            .example("$0 recipe ls", "list the recipes")
            .example("$0 recipe gulp.sass", "use the gulp.sass recipe")
            .default("cwd", () => process.cwd())
            .argv;
    }

    if (out.help) {
        return yargs.showHelp();
    }

    handleCli({ cli: { flags: out, input: out._ } });
}

function pathErrors(input, resolved): BsErrors {
    if (!existsSync(resolved)) {
        return [
            {
                type: BsErrorTypes.PathNotFound,
                level: BsErrorLevels.Fatal,
                errors: [
                    {
                        error: new Error(`Path not found: ${input}`),
                        meta() {
                            return [
                                `Your Input:    ${chalk.yellow(input)}`,
                                `CWD:           ${chalk.yellow(process.cwd())}`,
                                `Resolved to:   ${chalk.yellow(resolved)}`
                            ];
                        }
                    }
                ]
            }
        ];
    }
    return [];
}


================================================
FILE: packages/browser-sync/lib/browser-sync.js
================================================
"use strict";

var hooks = require("./hooks");
var asyncTasks = require("./async-tasks");
var config = require("./config");
var connectUtils = require("./connect-utils");
var utils = require("./utils");
var logger = require("./logger");
var chalk  = require("chalk");

var eachSeries = utils.eachSeries;
var _ = require("./lodash.custom");
var EE = require("easy-extender");

/**
 * Required internal plugins.
 * Any of these can be overridden by deliberately
 * causing a name-clash.
 */
var defaultPlugins = {
    logger: logger,
    socket: require("./sockets"),
    "file:watcher": require("./file-watcher"),
    server: require("./server"),
    tunnel: require("./tunnel"),
    "client:script": require("browser-sync-client"),
    UI: require("browser-sync-ui")
};

/**
 * @constructor
 */
var BrowserSync = function(emitter) {
    var bs = this;

    bs.cwd = process.cwd();
    bs.active = false;
    bs.paused = false;
    bs.config = config;
    bs.utils = utils;
    bs.events = bs.emitter = emitter;

    bs._userPlugins = [];
    bs._reloadQueue = [];
    bs._cleanupTasks = [];
    bs._browserReload = false;

    // Plugin management
    bs.pluginManager = new EE(defaultPlugins, hooks);
};

/**
 * Call a user-options provided callback
 * @param name
 */
BrowserSync.prototype.callback = function(name) {
    var bs = this;
    var cb = bs.options.getIn(["callbacks", name]);

    if (_.isFunction(cb)) {
        cb.apply(bs.publicInstance, _.toArray(arguments).slice(1));
    }
};

/**
 * @param {Map} options
 * @param {Function} cb
 * @returns {BrowserSync}
 */
BrowserSync.prototype.init = function(options, cb) {
    /**
     * Safer access to `this`
     * @type {BrowserSync}
     */
    var bs = this;

    /**
     * Set user-provided callback, or assign a noop
     * @type {Function}
     */
    bs.cb = cb || utils.defaultCallback;

    /**
     * Verify provided config.
     * Some options are not compatible and will cause us to
     * end the process.
     */
    if (!utils.verifyConfig(options, bs.cb)) {
        return;
    }

    /**
     * Save a reference to the original options
     * @type {Map}
     * @private
     */
    bs._options = options;

    /**
     * Set additional options that depend on what the
     * user may of provided
     * @type {Map}
     */
    bs.options = options;

    /**
     * Kick off default plugins.
     */
    bs.pluginManager.init();

    /**
     * Create a base logger & debugger.
     */
    bs.logger = bs.pluginManager.get("logger")(bs.events, bs);
    bs.debugger = bs.logger.clone({ useLevelPrefixes: true });
    bs.debug = bs.debugger.debug;

    /**
     * Run each setup task in sequence
     */
    eachSeries(asyncTasks, taskRunner(bs), tasksComplete(bs));

    return this;
};

/**
 * Run 1 setup task.
 * Each task is a pure function.
 * They can return options or instance properties to set,
 * but they cannot set them directly.
 * @param {BrowserSync} bs
 * @returns {Function}
 */
function taskRunner(bs) {
    return function(item, cb) {
        bs.debug("-> %s", chalk.yellow("Starting Step: " + item.step));

        /**
         * Execute the current task.
         */
        item.fn(bs, executeTask);

        function executeTask(err, out) {
            /**
             * Exit early if any task returned an error.
             */
            if (err) {
                return cb(err);
            }

            /**
             * Act on return values (such as options to be set,
             * or instance properties to be set
             */
            if (out) {
                handleOut(bs, out);
            }

            bs.debug("+  %s", chalk.green("Step Complete: " + item.step));

            cb();
        }
    };
}

/**
 * @param bs
 * @param out
 */
function handleOut(bs, out) {
    /**
     * Set a single/many option.
     */
    if (out.options) {
        setOptions(bs, out.options);
    }

    /**
     * Any options returned that require path access?
     */
    if (out.optionsIn) {
        out.optionsIn.forEach(function(item) {
            bs.setOptionIn(item.path, item.value);
        });
    }

    /**
     * Any instance properties returned?
     */
    if (out.instance) {
        Object.keys(out.instance).forEach(function(key) {
            bs[key] = out.instance[key];
        });
    }
}

/**
 * Update the options Map
 * @param bs
 * @param options
 */
function setOptions(bs, options) {
    /**
     * If multiple options were set, act on the immutable map
     * in an efficient way
     */
    if (Object.keys(options).length > 1) {
        bs.setMany(function(item) {
            Object.keys(options).forEach(function(key) {
                item.set(key, options[key]);
                return item;
            });
        });
    } else {
        Object.keys(options).forEach(function(key) {
            bs.setOption(key, options[key]);
        });
    }
}

/**
 * At this point, ALL async tasks have completed
 * @param {BrowserSync} bs
 * @returns {Function}
 */
function tasksComplete(bs) {
    return function(err) {
        if (err) {
            bs.logger.setOnce("useLevelPrefixes", true).error(err.message);
        }

        /**
         * Set active flag
         */
        bs.active = true;

        /**
         * @deprecated
         */
        bs.events.emit("init", bs);

        /**
         * This is no-longer needed as the Callback now only resolves
         * when everything (including slow things, like the tunnel) is ready.
         * It's here purely for backwards compatibility.
         * @deprecated
         */
        bs.events.emit("service:running", {
            options: bs.options,
            baseDir: bs.options.getIn(["server", "baseDir"]),
            type: bs.options.get("mode"),
            port: bs.options.get("port"),
            url: bs.options.getIn(["urls", "local"]),
            urls: bs.options.get("urls").toJS(),
            tunnel: bs.options.getIn(["urls", "tunnel"])
        });

        /**
         * Call any option-provided callbacks
         */
        bs.callback("ready", null, bs);

        /**
         * Finally, call the user-provided callback given as last arg
         */
        bs.cb(null, bs);
    };
}

/**
 * @param module
 * @param opts
 * @param cb
 */
BrowserSync.prototype.registerPlugin = function(module, opts, cb) {
    var bs = this;

    bs.pluginManager.registerPlugin(module, opts, cb);

    if (module["plugin:name"]) {
        bs._userPlugins.push(module);
    }
};

/**
 * Get a plugin by name
 * @param name
 */
BrowserSync.prototype.getUserPlugin = function(name) {
    var bs = this;

    var items = bs.getUserPlugins(function(item) {
        return item["plugin:name"] === name;
    });

    if (items && items.length) {
        return items[0];
    }

    return false;
};

/**
 * @param {Function} [filter]
 */
BrowserSync.prototype.getUserPlugins = function(filter) {
    var bs = this;

    filter =
        filter ||
        function() {
            return true;
        };

    /**
     * Transform Plugins option
     */
    bs.userPlugins = bs._userPlugins.filter(filter).map(function(plugin) {
        return {
            name: plugin["plugin:name"],
            active: plugin._enabled,
            opts: bs.pluginManager.pluginOptions[plugin["plugin:name"]]
        };
    });

    return bs.userPlugins;
};

/**
 * Get middleware
 * @returns {*}
 */
BrowserSync.prototype.getMiddleware = function(type) {
    var types = {
        connector: connectUtils.socketConnector(this.options)
    };

    if (type in types) {
        return function(req, res) {
            res.setHeader("Content-Type", "text/javascript");
            res.end(types[type]);
        };
    }
};

/**
 * Shortcut for pushing a file-serving middleware
 * onto the stack
 * @param {String} path
 * @param {{type: string, content: string}} props
 */
var _serveFileCount = 0;
BrowserSync.prototype.serveFile = function(path, props) {
    var bs = this;
    var mode = bs.options.get("mode");
    var entry = {
        handle: function(req, res) {
            res.setHeader("Content-Type", props.type);
            res.end(props.content);
        },
        id: "Browsersync - " + _serveFileCount++,
        route: path
    };

    bs._addMiddlewareToStack(entry);
};

/**
 * Add middlewares on the fly
 */
BrowserSync.prototype._addMiddlewareToStack = function(entry) {
    var bs = this;

    /**
     * additional middlewares are always appended -1,
     * this is to allow the proxy middlewares to remain,
     * and the directory index to remain in serveStatic/snippet modes
     */
    bs.app.stack.splice(bs.app.stack.length - 1, 0, entry);
};

var _addMiddlewareCount = 0;
BrowserSync.prototype.addMiddleware = function(route, handle, opts) {
    var bs = this;

    if (!bs.app) {
        return;
    }

    opts = opts || {};

    if (!opts.id) {
        opts.id = "bs-mw-" + _addMiddlewareCount++;
    }

    if (route === "*") {
        route = "";
    }

    var entry = {
        id: opts.id,
        route: route,
        handle: handle
    };

    if (opts.override) {
        entry.override = true;
    }

    bs.options = bs.options.update("middleware", function(mw) {
        if (bs.options.get("mode") === "proxy") {
            return mw.insert(mw.size - 1, entry);
        }
        return mw.concat(entry);
    });

    bs.resetMiddlewareStack();
};

/**
 * Remove middlewares on the fly
 * @param {String} id
 * @returns {Server}
 */
BrowserSync.prototype.removeMiddleware = function(id) {
    var bs = this;

    if (!bs.app) {
        return;
    }

    bs.options = bs.options.update("middleware", function(mw) {
        return mw.filter(function(mw) {
            return mw.id !== id;
        });
    });

    bs.resetMiddlewareStack();
};

/**
 * Middleware for socket connection (external usage)
 * @param opts
 * @returns {*}
 */
BrowserSync.prototype.getSocketConnector = function(opts) {
    var bs = this;

    return function(req, res) {
        res.setHeader("Content-Type", "text/javascript");
        res.end(bs.getExternalSocketConnector(opts));
    };
};

/**
 * Socket connector as a string
 * @param {Object} opts
 * @returns {*}
 */
BrowserSync.prototype.getExternalSocketConnector = function(opts) {
    var bs = this;

    return connectUtils.socketConnector(
        bs.options.withMutations(function(item) {
            item.set("socket", item.get("socket").merge(opts));
            if (!bs.options.getIn(["proxy", "ws"])) {
                item.set("mode", "snippet");
            }
        })
    );
};

/**
 * Callback helper
 * @param name
 */
BrowserSync.prototype.getOption = function(name) {
    this.debug("Getting option: {magenta:%s", name);
    return this.options.get(name);
};

/**
 * Callback helper
 * @param path
 */
BrowserSync.prototype.getOptionIn = function(path) {
    this.debug("Getting option via path: {magenta:%s", path);
    return this.options.getIn(path);
};

/**
 * @returns {BrowserSync.options}
 */
BrowserSync.prototype.getOptions = function() {
    return this.options;
};

/**
 * @returns {BrowserSync.options}
 */
BrowserSync.prototype.getLogger = logger.getLogger;

/**
 * @param {String} name
 * @param {*} value
 * @returns {BrowserSync.options|*}
 */
BrowserSync.prototype.setOption = function(name, value, opts) {
    var bs = this;

    opts = opts || {};

    bs.debug("Setting Option: {cyan:%s} - {magenta:%s", name, value.toString());

    bs.options = bs.options.set(name, value);

    if (!opts.silent) {
        bs.events.emit("options:set", {
            path: name,
            value: value,
            options: bs.options
        });
    }
    return this.options;
};

/**
 * @param path
 * @param value
 * @param opts
 * @returns {Map|*|BrowserSync.options}
 */
BrowserSync.prototype.setOptionIn = function(path, value, opts) {
    var bs = this;

    opts = opts || {};

    bs.debug(
        "Setting Option: {cyan:%s} - {magenta:%s",
        path.join("."),
        value.toString()
    );
    bs.options = bs.options.setIn(path, value);
    if (!opts.silent) {
        bs.events.emit("options:set", {
            path: path,
            value: value,
            options: bs.options
        });
    }
    return bs.options;
};

/**
 * Set multiple options with mutations
 * @param fn
 * @param opts
 * @returns {Map|*}
 */
BrowserSync.prototype.setMany = function(fn, opts) {
    var bs = this;

    opts = opts || {};

    bs.debug("Setting multiple Options");
    bs.options = bs.options.withMutations(fn);
    if (!opts.silent) {
        bs.events.emit("options:set", { options: bs.options.toJS() });
    }
    return this.options;
};

BrowserSync.prototype.addRewriteRule = function(rule) {
    var bs = this;

    bs.options = bs.options.update("rewriteRules", function(rules) {
        return rules.concat(rule);
    });

    bs.resetMiddlewareStack();
};

BrowserSync.prototype.removeRewriteRule = function(id) {
    var bs = this;
    bs.options = bs.options.update("rewriteRules", function(rules) {
        return rules.filter(function(rule) {
            return rule.id !== id;
        });
    });

    bs.resetMiddlewareStack();
};

BrowserSync.prototype.setRewriteRules = function(rules) {
    var bs = this;
    bs.options = bs.options.update("rewriteRules", function(_) {
        return rules;
    });

    bs.resetMiddlewareStack();
};

/**
 * Add a new rewrite rule to the stack
 * @param {Object} rule
 */
BrowserSync.prototype.resetMiddlewareStack = function() {
    var bs = this;
    var middlewares = require("./server/utils").getMiddlewares(bs, bs.options);

    bs.app.stack = middlewares;
};

/**
 * @param fn
 */
BrowserSync.prototype.registerCleanupTask = function(fn) {
    this._cleanupTasks.push(fn);
};

/**
 * Instance Cleanup
 */
BrowserSync.prototype.cleanup = function(cb) {
    var bs = this;
    if (!bs.active) {
        return;
    }

    // Remove all event listeners
    if (bs.events) {
        bs.debug("Removing event listeners...");
        bs.events.removeAllListeners();
    }

    // Close any core file watchers
    if (bs.watchers) {
        Object.keys(bs.watchers).forEach(function(key) {
            bs.watchers[key].watchers.forEach(function(watcher) {
                watcher.close();
            });
        });
    }

    // Run any additional clean up tasks
    bs._cleanupTasks.forEach(function(fn) {
        if (_.isFunction(fn)) {
            fn(bs);
        }
    });

    // Reset the flag
    bs.debug("Setting {magenta:active: false");
    bs.active = false;
    bs.paused = false;

    bs.pluginManager.plugins = {};
    bs.pluginManager.pluginOptions = {};
    bs.pluginManager.defaultPlugins = defaultPlugins;

    bs._userPlugins = [];
    bs.userPlugins = [];
    bs._reloadTimer = undefined;
    bs._reloadQueue = [];
    bs._cleanupTasks = [];

    if (_.isFunction(cb)) {
        cb(null, bs);
    }
};

module.exports = BrowserSync;


================================================
FILE: packages/browser-sync/lib/cli/cli-info.js
================================================
"use strict";

var config = require("../config");
var logger = require("../logger").logger;

var fs = require("fs");
var _ = require("../lodash.custom");
var path = require("path");
var chalk = require("chalk");

var info = {
    /**
     * Version info
     * @param {Object} pjson
     * @returns {String}
     */
    getVersion: function(pjson) {
        console.log(pjson.version);
        return pjson.version;
    },
    /**
     * Retrieve the config file
     * @returns {*}
     * @private
     * @param filePath
     */
    getConfigFile: function(filePath) {
        return require(path.resolve(filePath));
    },
    /**
     * Generate an example Config file.
     */
    makeConfig: function(cwd, cb) {
        var opts = require(path.join(__dirname, "..", config.configFile));
        var userOpts = {};

        var ignore = ["excludedFileTypes", "injectFileTypes", "snippetOptions"];

        Object.keys(opts).forEach(function(key) {
            if (!_.includes(ignore, key)) {
                userOpts[key] = opts[key];
            }
        });

        var file = fs.readFileSync(config.template, "utf8");
        file = file.replace("//OPTS", JSON.stringify(userOpts, null, 4));

        fs.writeFile(path.resolve(cwd, config.userFile), file, function() {
            logger.info("Config file created %s", chalk.magenta(config.userFile));
            logger.info(
                "To use it, in the same directory run: " +
                    chalk.cyan("browser-sync start --config bs-config.js")
            );
            cb();
        });
    }
};

module.exports = info;


================================================
FILE: packages/browser-sync/lib/cli/cli-options.ts
================================================
import { Map, List, fromJS } from "immutable";
import { addToFilesOption } from "./transforms/addToFilesOption";
import { addDefaultIgnorePatterns } from "./transforms/addDefaultIgnorePatterns";
import { copyCLIIgnoreToWatchOptions } from "./transforms/copyCLIIgnoreToWatchOptions";
import { handleExtensionsOption } from "./transforms/handleExtensionsOption";
import { handleFilesOption } from "./transforms/handleFilesOption";
import { handleGhostModeOption } from "./transforms/handleGhostModeOption";
import { handlePortsOption } from "./transforms/handlePortsOption";
import { handleProxyOption } from "./transforms/handleProxyOption";
import { handleServerOption } from "./transforms/handleServerOption";
import { appendServerIndexOption } from "./transforms/appendServerIndexOption";
import { appendServerDirectoryOption } from "./transforms/appendServerDirectoryOption";
import { addCwdToWatchOptions } from "./transforms/addCwdToWatchOptions";
import {
    setMode,
    setScheme,
    setStartPath,
    setProxyWs,
    setServerOpts,
    liftExtensionsOptionFromCli,
    setNamespace,
    fixSnippetIgnorePaths,
    fixSnippetIncludePaths,
    fixRewriteRules,
    setMiddleware,
    setOpen,
    setUiPort
} from "../options";
import { BsErrors } from "../bin";
import { handleHostOption } from "./transforms/handleHostOption";

const _ = require("../lodash.custom");
const defaultConfig = require("../default-config");
const immDefs = fromJS(defaultConfig);

/**
 * @param {Object} input
 * @returns {Map}
 */
export type BsTempOptions = Map<string, any>;
export type TransformResult = [BsTempOptions, BsErrors];
export type TransformFn = (subject: BsTempOptions) => TransformResult;

export function merge(input) {
    const merged = immDefs.mergeDeep(input);
    const transforms: TransformFn[] = [
        addToFilesOption,
        addCwdToWatchOptions,
        addDefaultIgnorePatterns,
        copyCLIIgnoreToWatchOptions,
        handleServerOption,
        appendServerIndexOption,
        appendServerDirectoryOption,
        handleProxyOption,
        handlePortsOption,
        handleHostOption,
        handleGhostModeOption,
        handleFilesOption,
        handleExtensionsOption,
        setMode,
        setScheme,
        setStartPath,
        setProxyWs,
        setServerOpts,
        liftExtensionsOptionFromCli,
        setNamespace,
        fixSnippetIgnorePaths,
        fixSnippetIncludePaths,
        fixRewriteRules,
        setMiddleware,
        setOpen,
        setUiPort
    ];

    const output = transforms.reduce(
        (acc: TransformResult, item: TransformFn) => {
            const [current, currentErrors] = acc;
            const [result, errors] = item.call(null, current);
            return [result, [...currentErrors, ...errors]];
        },
        [merged, []] as TransformResult
    );

    return output;
}

/**
 * @param string
 */
export function explodeFilesArg(string): string {
    return string.split(",").map(item => item.trim());
}

/**
 * @param value
 * @returns {{globs: Array, objs: Array}}
 */
export function makeFilesArg(value) {
    let globs = [];
    let objs = [];

    if (_.isString(value)) {
        globs = globs.concat(explodeFilesArg(value));
    }

    if (List.isList(value) && value.size) {
        value.forEach(function(value) {
            if (_.isString(value)) {
                globs.push(value);
            } else {
                if (Map.isMap(value)) {
                    objs.push(value);
                }
            }
        });
    }

    return {
        globs: globs,
        objs: objs
    };
}

export function printErrors(errors: BsErrors) {
    return errors
        .map(error =>
            [
                `Error Type:    ${error.type}`,
                `Error Level:   ${error.level}`,
                error.errors.map(item =>
                    [
                        `Error Message: ${item.error.message}`,
                        item.meta ? item.meta().join("\n") : ""
                    ]
                        .filter(Boolean)
                        .join("\n")
                )
            ].join("\n")
        )
        .join("\n\n");
}


================================================
FILE: packages/browser-sync/lib/cli/command.init.js
================================================
"use strict";

var info = require("./cli-info");

/**
 * $ browser-sync init
 *
 * This command will generate a configuration
 * file in the current directory
 *
 * @param opts
 */
module.exports = function(opts) {
    info.makeConfig(process.cwd(), opts.cb);
};


================================================
FILE: packages/browser-sync/lib/cli/command.recipe.js
================================================
"use strict";
var logger = require("../logger").logger;
var chalk  = require("chalk");

/**
 * $ browser-sync recipe <name> <options>
 *
 * This command will copy a recipe into either the current directory
 * or one given with the --output flag
 *
 * @param opts
 * @returns {Function}
 */
module.exports = function(opts) {
    var path = require("path");
    var fs = require("fs-extra");
    var input = opts.cli.input.slice(1);
    var resolved = require.resolve("bs-recipes");
    var dir = path.dirname(resolved);

    var logRecipes = function() {
        var dirs = fs.readdirSync(path.join(dir, "recipes"));
        logger.info(
            "Install one of the following with %s\n",
            chalk.cyan('browser-sync recipe <name>')
        );
        dirs.forEach(function(name) {
            console.log("    " + name);
        });
    };

    if (!input.length) {
        logger.info("No recipe name provided!");
        logRecipes();
        return opts.cb();
    }

    if (opts.cli.input[1] === "ls") {
        logRecipes();
        return opts.cb();
    }

    input = input[0];
    var flags = opts.cli.flags;
    var output = flags.output
        ? path.resolve(flags.output)
        : path.join(process.cwd(), input);
    var targetDir = path.join(dir, "recipes", input);

    if (fs.existsSync(output)) {
        return opts.cb(
            new Error("Target folder exists remove it first and then try again")
        );
    }

    if (fs.existsSync(targetDir)) {
        fs.copy(targetDir, output, function(err) {
            if (err) {
                opts.cb(err);
            } else {
                logger.info("Recipe copied into %s", chalk.cyan(output));
                logger.info(
                    "Next, inside that folder, run %s",
                    chalk.cyan("npm i && npm start")
                );
                opts.cb(null);
            }
        });
    } else {
        logger.info(
            "Recipe %s not found. The following are available though",
            chalk.cyan(input)
        );
        logRecipes();
        opts.cb();
    }
};


================================================
FILE: packages/browser-sync/lib/cli/command.reload.js
================================================
"use strict";

/**
 * $ browser-sync reload <options>
 *
 * This commands starts the Browsersync servers
 * & Optionally UI.
 *
 * @param opts
 * @returns {Function}
 */
module.exports = function(opts) {
    var flags = opts.cli.flags;
    if (!flags.url) {
        flags.url = "http://localhost:" + (flags.port || 3000);
    }
    var proto = require("../http-protocol");
    var scheme = flags.url.match(/^https/) ? "https" : "http";
    var args = { method: "reload" };

    if (flags.files) {
        args.args = flags.files;
    }

    var url = proto.getUrl(args, flags.url);

    if (scheme === "https") {
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    }

    require(scheme)
        .get(url, function(res) {
            res.on("data", function() {
                if (res.statusCode === 200) {
                    opts.cb(null, res);
                }
            });
        })
        .on("error", function(err) {
            if (err.code === "ECONNREFUSED") {
                err.message = "Browsersync not running at " + flags.url;
            }
            return opts.cb(err);
        });
};


================================================
FILE: packages/browser-sync/lib/cli/command.start.ts
================================================
import * as path from "path";
import { existsSync } from "fs";
import { fromJS } from "immutable";
import * as utils from "../utils";
import { explodeFilesArg } from "./cli-options";
const _ = require("../lodash.custom");

/**
 * $ browser-sync start <options>
 *
 * This commands starts the Browsersync servers
 * & Optionally UI.
 *
 * @param opts
 * @returns {Function}
 */
export default function(opts) {
    const flags = preprocessFlags(opts.cli.flags);
    const cwd = flags.cwd || process.cwd();
    const maybepkg = path.resolve(cwd, "package.json");
    let input = flags;

    if (flags.config) {
        const maybeconf = path.resolve(cwd, flags.config);
        if (existsSync(maybeconf)) {
            const conf = require(maybeconf);
            input = _.merge({}, conf, flags);
        } else {
            utils.fail(
                true,
                new Error(`Configuration file '${flags.config}' not found`),
                opts.cb
            );
        }
    } else {
        if (existsSync(maybepkg)) {
            const pkg = require(maybepkg);
            if (pkg["browser-sync"]) {
                console.log("> Configuration obtained from package.json");
                input = _.merge({}, pkg["browser-sync"], flags);
            }
        }
    }

    return require("../")
        .create("cli")
        .init(input, opts.cb);
}

/**
 * @param flags
 * @returns {*}
 */
function preprocessFlags(flags) {
    return [
        stripUndefined,
        legacyFilesArgs,
        removeWatchBooleanWhenFalse
    ].reduce((flags, fn) => fn.call(null, flags), flags);
}

/**
 * Incoming undefined values are problematic as
 * they interfere with Immutable.Map.mergeDeep
 * @param subject
 * @returns {*}
 */
function stripUndefined(subject) {
    return Object.keys(subject).reduce((acc, key) => {
        const value = subject[key];
        if (typeof value === "undefined") {
            return acc;
        }
        acc[key] = value;
        return acc;
    }, {});
}

/**
 * @param flags
 * @returns {*}
 */
function legacyFilesArgs(flags) {
    if (flags.files && flags.files.length) {
        flags.files = flags.files.reduce(
            (acc, item) => acc.concat(explodeFilesArg(item)),
            []
        );
    }
    return flags;
}

/**
 * `watch` is a CLI boolean so should be removed if false to
 * allow config to set watch: true
 * @param flags
 * @returns {any}
 */
function removeWatchBooleanWhenFalse(flags) {
    if (flags.watch === false) {
        return fromJS(flags)
            .delete("watch")
            .toJS();
    }
    return flags;
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/addCwdToWatchOptions.ts
================================================
import { BsTempOptions, TransformResult } from "../cli-options";

export function addCwdToWatchOptions(incoming: BsTempOptions): TransformResult {
    const output = incoming.updateIn(["watchOptions", "cwd"], watchCwd => {
        return watchCwd || incoming.get("cwd");
    });

    return [output, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/addDefaultIgnorePatterns.ts
================================================
import { List } from "immutable";
import { BsTempOptions, TransformResult } from "../cli-options";

const defaultIgnorePatterns = [
    /node_modules/,
    /bower_components/,
    ".sass-cache",
    ".vscode",
    ".git",
    ".idea"
];

export function addDefaultIgnorePatterns(
    incoming: BsTempOptions
): TransformResult {
    if (!incoming.get("watch")) {
        return [incoming, []];
    }

    const output = incoming.update("watchOptions", watchOptions => {
        const userIgnored = List([])
            .concat(watchOptions.get("ignored"))
            .filter(Boolean)
            .toSet();

        const merged = userIgnored.merge(defaultIgnorePatterns);

        return watchOptions.merge({
            ignored: merged.toList()
        });
    });

    return [output, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/addToFilesOption.ts
================================================
import { List, Map } from "immutable";
import { BsTempOptions, TransformResult } from "../cli-options";

export function addToFilesOption(incoming: BsTempOptions): TransformResult {
    if (!incoming.get("watch")) {
        return [incoming, []];
    }

    let serverPaths = [];

    const fromServeStatic = incoming.get("serveStatic", List([])).toArray();
    const ssPaths = fromServeStatic.reduce((acc, ss) => {
        if (typeof ss === "string") {
            return acc.concat(ss);
        }
        if (ss.dir && typeof ss.dir === "string") {
            return acc.concat(ss);
        }
        return acc;
    }, []);

    ssPaths.forEach(p => serverPaths.push(p));

    const server = incoming.get("server");
    if (server) {
        if (server === true) {
            serverPaths.push(".");
        }
        if (typeof server === "string") {
            serverPaths.push(server);
        }
        if (List.isList(server) && server.every(x => typeof x === "string")) {
            server.forEach(s => serverPaths.push(s));
        }
        if (Map.isMap(server)) {
            const baseDirProp = server.get("baseDir");
            const baseDirs = List([])
                .concat(baseDirProp)
                .filter(Boolean);
            baseDirs.forEach(s => serverPaths.push(s));
        }
    }

    const output = incoming.update("files", files => {
        return List([])
            .concat(files, serverPaths)
            .filter(Boolean);
    });
    return [output, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/appendServerDirectoryOption.ts
================================================
import { BsTempOptions, TransformResult } from "../cli-options";

export function appendServerDirectoryOption(
    incoming: BsTempOptions
): TransformResult {
    if (!incoming.get("server")) return [incoming, []];
    if (incoming.get("directory")) {
        return [
            incoming.setIn(["server", "directory"], incoming.has("directory")),
            []
        ];
    }
    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/appendServerIndexOption.ts
================================================
import { BsTempOptions, TransformResult } from "../cli-options";

export function appendServerIndexOption(
    incoming: BsTempOptions
): TransformResult {
    if (!incoming.get("server")) return [incoming, []];
    const value = incoming.get("index");

    if (value) {
        return [incoming.setIn(["server", "index"], value), []];
    }

    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/copyCLIIgnoreToWatchOptions.ts
================================================
import { List } from "immutable";
import { BsTempOptions, TransformResult } from "../cli-options";

export function copyCLIIgnoreToWatchOptions(
    incoming: BsTempOptions
): TransformResult {
    if (!incoming.get("ignore")) {
        return [incoming, []];
    }
    const output = incoming.updateIn(
        ["watchOptions", "ignored"],
        List([]),
        ignored => {
            return List([]).concat(ignored, incoming.get("ignore"));
        }
    );

    return [output, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleExtensionsOption.ts
================================================
import { List } from "immutable";
import {
    BsTempOptions,
    explodeFilesArg,
    TransformResult
} from "../cli-options";

const _ = require("../../lodash.custom");

export function handleExtensionsOption(
    incoming: BsTempOptions
): TransformResult {
    const value = incoming.get("extensions");
    if (_.isString(value)) {
        const split = explodeFilesArg(value);
        if (split.length) {
            return [incoming.set("extensions", List(split)), []];
        }
    }
    if (List.isList(value)) {
        return [incoming.set("extensions", value), []];
    }
    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleFilesOption.ts
================================================
import { fromJS } from "immutable";
import { BsTempOptions, makeFilesArg, TransformResult } from "../cli-options";
import { FilesNamespaces } from "../../types";

export function handleFilesOption(incoming: BsTempOptions): TransformResult {
    const value = incoming.get("files");
    const namespaces: FilesNamespaces = {
        core: {
            globs: [],
            objs: []
        }
    };

    const processed = makeFilesArg(value);

    if (processed.globs.length) {
        namespaces.core.globs = processed.globs;
    }

    if (processed.objs.length) {
        namespaces.core.objs = processed.objs;
    }

    return [incoming.set("files", fromJS(namespaces)), []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleGhostModeOption.ts
================================================
import { fromJS } from "immutable";
import { BsTempOptions, TransformResult } from "../cli-options";

export function handleGhostModeOption(
    incoming: BsTempOptions
): TransformResult {
    const value = incoming.get("ghostMode");
    var trueAll = {
        clicks: true,
        scroll: true,
        forms: {
            submit: true,
            inputs: true,
            toggles: true
        }
    };

    var falseAll = {
        clicks: false,
        scroll: false,
        forms: {
            submit: false,
            inputs: false,
            toggles: false
        }
    };

    if (value === false || value === "false") {
        return [incoming.set("ghostMode", fromJS(falseAll)), []];
    }

    if (value === true || value === "true") {
        return [incoming.set("ghostMode", fromJS(trueAll)), []];
    }

    if (value.get("forms") === false) {
        return [
            incoming.set(
                "ghostMode",
                value.withMutations(function(map) {
                    map.set(
                        "forms",
                        fromJS({
                            submit: false,
                            inputs: false,
                            toggles: false
                        })
                    );
                })
            ),
            []
        ];
    }

    if (value.get("forms") === true) {
        return [
            incoming.set(
                "ghostMode",
                value.withMutations(function(map) {
                    map.set(
                        "forms",
                        fromJS({
                            submit: true,
                            inputs: true,
                            toggles: true
                        })
                    );
                })
            ),
            []
        ];
    }

    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleHostOption.ts
================================================
import { BsTempOptions, TransformResult } from "../cli-options";
import { BsErrorLevels, BsErrorTypes } from "../../bin";

export function handleHostOption(incoming: BsTempOptions): TransformResult {
    const host: string | null = incoming.get("host");
    const listen: string | null = incoming.get("listen");

    if (host && listen) {
        if (host !== listen) {
            return [
                incoming,
                [
                    {
                        errors: [
                            {
                                error: new Error(
                                    "Cannot specify both `host` and `listen` options"
                                ),
                                meta() {
                                    return [
                                        "",
                                        "Tip:           Use just the `listen` option *only* if you want to bind only to a particular host."
                                    ];
                                }
                            }
                        ],
                        level: BsErrorLevels.Fatal,
                        type: BsErrorTypes.HostAndListenIncompatible
                    }
                ]
            ];
        }

        // whenever we have have both `host` + `listen` options,
        // we remove the 'host' to prevent complication further down the line
        return [incoming.delete("host"), []];
    }

    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handlePortsOption.ts
================================================
import { Map } from "immutable";
import { PortsOption } from "../../types";
import { BsTempOptions, TransformResult } from "../cli-options";

export function handlePortsOption(incoming: BsTempOptions): TransformResult {
    const value = incoming.get("ports");
    if (!value) return [incoming, []];

    const obj: PortsOption = { min: null, max: null };

    if (typeof value === "string") {
        if (~value.indexOf(",")) {
            const segs = value.split(",");
            obj.min = parseInt(segs[0], 10);
            obj.max = parseInt(segs[1], 10);
        } else {
            obj.min = parseInt(value, 10);
            obj.max = null;
        }
    } else {
        obj.min = value.get("min");
        obj.max = value.get("max") || null;
    }

    return [incoming.set("ports", Map(obj)), []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleProxyOption.ts
================================================
import * as url from "url";
import { Map } from "immutable";
import { BrowsersyncProxy } from "../../types";
import { BsTempOptions, TransformResult } from "../cli-options";

export function handleProxyOption(incoming: BsTempOptions): TransformResult {
    let value = incoming.get("proxy");
    let mw;
    let target;

    if (!value || value === true) {
        return [incoming, []];
    }

    if (typeof value !== "string") {
        target = value.get("target");
        mw = value.get("middleware");
    } else {
        target = value;
        value = Map({});
    }

    if (!target.match(/^(https?):\/\//)) {
        target = "http://" + target;
    }

    const parsedUrl = url.parse(target);

    if (!parsedUrl.port) {
        parsedUrl.port = "80";
    }

    const out: BrowsersyncProxy = {
        target: parsedUrl.protocol + "//" + parsedUrl.host,
        url: Map(parsedUrl)
    };

    if (mw) {
        out.middleware = mw;
    }

    const proxyOutput = value.mergeDeep(out);

    return [incoming.set("proxy", proxyOutput), []];
}


================================================
FILE: packages/browser-sync/lib/cli/transforms/handleServerOption.ts
================================================
import { IServerOption } from "../../types";
import { fromJS, List, Map } from "immutable";
import { BsTempOptions, TransformResult } from "../cli-options";

export function handleServerOption(incoming: BsTempOptions): TransformResult {
    const value = incoming.get("server");
    if (value === false) {
        return [incoming, []];
    }

    // server: true
    if (value === true) {
        const obj: IServerOption = {
            baseDir: ["./"]
        };
        return [incoming.set("server", fromJS(obj)), []];
    }

    // server: "./app"
    if (typeof value === "string") {
        const obj: IServerOption = {
            baseDir: [value]
        };
        return [incoming.set("server", fromJS(obj)), []];
    }

    if (List.isList(value)) {
        const obj: IServerOption = {
            baseDir: value
        };
        return [incoming.set("server", fromJS(obj)), []];
    }

    if (Map.isMap(value)) {
        const dirs = List([])
            .concat(value.get("baseDir", "./"))
            .filter(Boolean);

        const merged = value.merge({ baseDir: dirs });

        return [incoming.set("server", merged), []];
    }

    return [incoming, []];
}


================================================
FILE: packages/browser-sync/lib/config.js
================================================
"use strict";

var path = require("path");
/**
 * @type {{controlPanel: {jsFile: string, baseDir: *}, socketIoScript: string, configFile: string, client: {shims: string}}}
 */
module.exports = {
    controlPanel: {
        jsFile: "/js/app.js",
        baseDir: path.join(__dirname, "control-panel")
    },
    templates: {
        scriptTag: path.join(__dirname, "..", "templates/script-tags.html"),
        scriptTagSimple: path.join(
            __dirname,
            "..",
            "templates/script-tags-simple.html"
        ),
        connector: path.join(__dirname, "..", "templates/connector.tmpl")
    },
    socketIoScript: "/public/socket.io.min.1.6.0.js",
    configFile: "default-config.js",
    userFile: "bs-config.js",
    template: path.join(__dirname, "..", "templates/cli-template.js"),
    httpProtocol: {
        path: "/__browser_sync__"
    },
    client: {
        shims: "/client/client-shims.js"
    },
    errors: {
        "server+proxy":
            "Invalid config. You cannot specify both server & proxy options.",
        "proxy+https":
            "Invalid config. You set https: true, but your proxy target doesn't reflect this."
    }
};


================================================
FILE: packages/browser-sync/lib/connect-utils.js
================================================
"use strict";

var _ = require("./lodash.custom");
var fs = require("fs");
var config = require("./config");

function getPath(options, relative, port) {
    if (options.get("mode") === "snippet") {
        return options.get("scheme") + "://HOST:" + port + relative;
    } else {
        return "//HOST:" + port + relative;
    }
}

var connectUtils = {
    /**
     * Allow users to disable the Browsersync snippet
     * @param {Immutable.Map} options
     * @returns {Boolean}
     */
    enabled: function(options) {
        const userValue = options.get("snippet");
        if (typeof userValue === "boolean") {
            return userValue
        }
        return true
    },
    /**
     * @param {Immutable.Map} options
     * @returns {String}
     */
    scriptTags: function(options) {
        var scriptPath = this.clientScript(options);
        var async = options.getIn(["snippetOptions", "async"]);
        var scriptDomain = options.getIn(["script", "domain"]);

        /**
         * Generate the [src] attribute based on user options
         */
        var scriptSrc = (function() {
            if (options.get("localOnly")) {
                return [
                    options.get("scheme"),
                    "://localhost:",
                    options.get("port"),
                    scriptPath
                ].join("");
            }

            /**
             * First, was "scriptPath" set? if so the user wanted full control over the
             * script tag output
             *
             */
            if (_.isFunction(options.get("scriptPath"))) {
                return options
                    .get("scriptPath")
                    .apply(null, getScriptArgs(options, scriptPath));
            }

            /**
             * Next, if "script.domain" was given, allow that + the path to the JS file
             * eg:
             *  script.domain=localhost:3000
             * -> localhost:3000/browser-sync/browser-sync-client.js
             */
            if (scriptDomain) {
                if (_.isFunction(scriptDomain)) {
                    return scriptDomain.call(null, options) + scriptPath;
                }
                if (scriptDomain.match(/\{port\}/)) {
                    return (
                        scriptDomain.replace("{port}", options.get("port")) +
                        scriptPath
                    );
                }
                return scriptDomain + scriptPath;
            }

            /**
             * Now if server or proxy, use dynamic script
             * eg:
             *  browser-sync start --server
             * ->
             *  "HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)
             */
            if (options.get("server") || options.get("proxy")) {
                return scriptPath;
            }

            /**
             * Final use case is snippet mode
             * -> "http://HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)
             * -> "//HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)"
             */
            return getPath(options, scriptPath, options.get("port"));
        })();

        /**
         * Decide which template shall be used to generate the script tags
         */
        var template = (function() {
            if (scriptDomain || options.get("localOnly")) {
                return config.templates.scriptTagSimple;
            }
            return config.templates.scriptTag;
        })();

        /**
         * Finally read the template file from disk and replace
         * the dynamic values.
         */
        return fs
            .readFileSync(template, "utf8")
            .replace("%script%", scriptSrc)
            .replace("%async%", async ? "async" : "");
    },
    /**
     * @param {Map} options
     * @returns {String}
     */
    socketConnector: function(options) {
        var socket = options.get("socket");
        var template = fs.readFileSync(config.templates.connector, "utf-8");
        var url = connectUtils.getConnectionUrl(options);

        /**
         * ***Backwards compatibility***. While `socket.path` is technically a
         * socketIoClientConfig property, it's been documented previously
         * as a top-level option, so must stay.
         */
        var clientConfig = socket.get("socketIoClientConfig").merge({
            path: socket.get("path")
        });

        template = template
            .replace("%config%", JSON.stringify(clientConfig.toJS()))
            .replace("%options%", JSON.stringify(options))
            .replace("%url%", url);

        return template;
    },
    /**
     * @param {Object} socketOpts
     * @param {Map} options
     * @returns {String|Function}
     */
    getNamespace: function(socketOpts, options) {
        var namespace = socketOpts.namespace;

        if (typeof namespace === "function") {
            return namespace(options);
        }

        if (!namespace.match(/^\//)) {
            namespace = "/" + namespace;
        }

        return namespace;
    },
    /**
     * @param {Map} options
     * @returns {string}
     */
    getConnectionUrl: function(options) {
        var socketOpts = options.get("socket").toJS();
        var namespace = connectUtils.getNamespace(socketOpts, options);

        var protocol = "";
        var withHostnamePort =
            "'{protocol}' + location.hostname + ':{port}{ns}'";
        var withHost = "'{protocol}' + location.host + '{ns}'";
        var withDomain = "'{domain}{ns}'";
        var port = options.get("port");

        // default use-case is server/proxy
        var string = withHost;

        if (options.get("mode") !== "server") {
            protocol = options.get("scheme") + "://";
            string = withHostnamePort;
        }

        if (options.get("mode") === "proxy" && options.getIn(["proxy", "ws"])) {
            port = options.getIn(["socket", "port"]);
        }

        /**
         * Ensure socket.domain is always a string (for noop replacements later)
         */
        socketOpts.domain = (function() {
            if (options.get("localOnly")) {
                string = withDomain;
                return [
                    options.get("scheme"),
                    "://localhost:",
                    options.get("port")
                ].join("");
            }
            if (socketOpts.domain) {
                string = withDomain;
                /**
                 * User provided a function
                 */
                if (_.isFunction(socketOpts.domain)) {
                    return socketOpts.domain.call(null, options);
                }
                /**
                 * User provided a string
                 */
                if (_.isString(socketOpts.domain)) {
                    return socketOpts.domain;
                }
            }
            return "";
        })();

        return string
            .replace("{protocol}", protocol)
            .replace("{port}", port)
            .replace("{domain}", socketOpts.domain.replace("{port}", port))
            .replace("{ns}", namespace);
    },
    /**
     * @param {Object} [options]
     * @param {Boolean} [both]
     */
    clientScript: function(options, both) {
        var prefix = options.getIn(["socket", "clientPath"]);
        var script = prefix + "/browser-sync-client.js";
        var versioned =
            prefix + "/browser-sync-client.js?v=" + options.get("version");

        if (both) {
            return {
                path: script,
                versioned: versioned
            };
        }

        return versioned;
    }
};

/**
 * @param options
 * @returns {*[]}
 */
function getScriptArgs(options, scriptPath) {
    var abspath =
        options.get("scheme") + "://HOST:" + options.get("port") + scriptPath;
    return [scriptPath, options.get("port"), options.set("absolute", abspath)];
}

module.exports = connectUtils;


================================================
FILE: packages/browser-sync/lib/default-config.js
================================================
/**
 * @module BrowserSync.options
 */
module.exports = {
    /**
     * Browsersync includes a user-interface that is accessed via a separate port.
     * The UI allows to controls all devices, push sync updates and much more.
     * @property ui
     * @type Object
     * @param {Number} [port=3001]
     * @since 2.0.0
     * @default false
     */
    ui: {
        port: 3001
    },

    /**
     * Browsersync can watch your files as you work. Changes you make will either
     * be injected into the page (CSS & images) or will cause all browsers to do
     * a full-page refresh.
     * @property files
     * @type Array|String
     * @default false
     */
    files: false,

    /**
     * Specify which file events to respond to.
     * Available events: `add`, `change`, `unlink`, `addDir`, `unlinkDir`
     * @property watchEvents
     * @type Array
     * @default ["change"]
     * @since 2.18.8
     */
    watchEvents: ["change"],

    /**
     * Watch files automatically - this should be used as an
     * alternative to the `files` option. When this option is used, some directories
     * will be ignored automatically such as `node_modules` `bower_components` `.sass-cache`
     * `.vscode` `.git` `.idea`
     *
     * @property watch
     * @type Boolean
     * @default false
     * @since 2.23.0
     */
    watch: false,

    /**
     * Patterns for any watchers to ignore. Anything provided here
     * will end up inside `watchOptions.ignored`
     * @property ignore
     * @type Array
     * @default []
     * @since 2.23.0
     */
    ignore: [],

    /**
     * Serve an index.html file for all non-asset routes. Useful
     * when using client-routers
     * @property single
     * @type Boolean
     * @default false
     * @since 2.23.0
     */
    single: false,

    /**
     * File watching options that get passed along to [Chokidar](https://github.com/paulmillr/chokidar).
     * Check their docs for available options
     * @property watchOptions
     * @type Object
     * @default undefined
     * @since 2.6.0
     */
    watchOptions: {
        ignoreInitial: true
        /*
         persistent: true,

         ignored: '*.txt',
         followSymlinks: true,
         cwd: '.',

         usePolling: true,
         alwaysStat: false,
         depth: undefined,
         interval: 100,

         ignorePermissionErrors: false,
         atomic: true
         */
    },

    /**
     * Use the built-in static server for basic HTML/JS/CSS websites.
     * @property server
     * @type Object|Boolean
     * @default false
     */
    server: false,

    /**
     * Proxy an EXISTING vhost. Browsersync will wrap your vhost with a proxy URL to view your site.
     * @property proxy
     * @type String|Object|Boolean
     * @param {String} [target]
     * @param {Boolean} [ws] - Enable websocket proxying
     * @param {Function|Array} [middleware]
     * @param {Function} [reqHeaders]
     * @param {Array} [proxyReq]
     * @param {Array} [proxyRes]
     * @default false
     */
    proxy: false,

    /**
     * @property port
     * @type Number
     * @default 3000
     */
    port: 3000,

    /**
     * @property middleware
     * @type Function|Array
     * @default false
     */
    middleware: false,

    /**
     * Add additional directories from which static
     * files should be served. Should only be used in `proxy` or `snippet`
     * mode.
     * @property serveStatic
     * @type Array
     * @default []
     * @since 2.8.0
     */
    serveStatic: [],

    /**
     * Options that are passed to the serve-static middleware
     * when you use the string[] syntax: eg: `serveStatic: ['./app']`. Please see
     * [serve-static](https://github.com/expressjs/serve-static) for details
     *
     * @property serveStaticOptions
     * @type Object
     * @since 2.17.0
     */

    /**
     * Enable https for localhost development. **Note** - this is not needed for proxy
     * option as it will be inferred from your target url.
     * @property https
     * @type Boolean
     * @default undefined
     * @since 1.3.0
     */

    /**
     * Override http module to allow using 3rd party server modules (such as http2)
     * *Note*: these modules are not included in the Browsersync package - you need
     * to 'npm install' any that you'd like to use.
     * @property httpModule
     * @type string
     * @default undefined
     * @since 2.18.0
     */

    /**
     * Current working directory
     * @property cwd
     * @type String
     * @since 2.23.0
     */

    /**
     * Register callbacks via a regular option - this can be used
     * to get access the Browsersync instance in situations where you
     * cannot provide a callback via the normal API (for example, in a Gruntfile)
     *
     * **Note**: Only the `ready` callback is currently supported here.
     *
     * @property callbacks
     * @type Object
     * @param {Function} ready
     */

    /**
     * Clicks, Scrolls & Form inputs on any device will be mirrored to all others.
     * @property ghostMode
     * @param {Boolean} [clicks=true]
     * @param {Boolean} [scroll=true]
     * @param {Boolean} [location=true]
     * @param {Boolean} [forms=true]
     * @param {Boolean} [forms.submit=true]
     * @param {Boolean} [forms.inputs=true]
     * @param {Boolean} [forms.toggles=true]
     * @type Object
     */
    ghostMode: {
        clicks: true,
        scroll: true,
        location: true,
        forms: {
            submit: true,
            inputs: true,
            toggles: true
        }
    },

    /**
     * Can be either "info", "debug", "warn", or "silent"
     * @property logLevel
     * @type String
     * @default info
     */
    logLevel: "info",

    /**
     * Change the console logging prefix. Useful if you're creating your
     * own project based on Browsersync
     * @property logPrefix
     * @type String
     * @default Browsersync
     * @since 1.5.1
     */
    logPrefix: "Browsersync",

    /**
     * @property logConnections
     * @type Boolean
     * @default false
     */
    logConnections: false,

    /**
     * @property logFileChanges
     * @type Boolean
     * @default true
     */
    logFileChanges: true,

    /**
     * Log the snippet to the console when you're in snippet mode (no proxy/server)
     * @property logSnippet
     * @type: Boolean
     * @default true
     * @since 1.5.2
     */
    logSnippet: true,

    /**
     * You can prevent Browsersync from injecting the connection snippet
     * by passing `snippet: false`.
     * @property snippet
     * @type Boolean
     * @default undefined
     */

    /**
     * You can control how the snippet is injected
     * onto each page via a custom regex + function.
     * You can also provide patterns for certain urls
     * that should be ignored from the snippet injection.
     * @property snippetOptions
     * @since 2.0.0
     * @param {Boolean} [async] - should the script tags have the async attribute?
     * @param {Array} [blacklist]
     * @param {Array} [whitelist]
     * @param {RegExp} [rule.match=/$/]
     * @param {Function} [rule.fn=Function]
     * @type Object
     */
    snippetOptions: {
        async: true,
        whitelist: [],
        blacklist: [],
        rule: {
            match: /<body[^>]*>/i,
            fn: function(snippet, match) {
                return match + snippet;
            }
        }
    },

    /**
     * Add additional HTML rewriting rules.
     * @property rewriteRules
     * @since 2.4.0
     * @type Array
     * @default false
     */
    rewriteRules: [],

    /**
     * @property tunnel
     * @type String|Boolean
     * @default null
     */

    /**
     * Decide which URL to open automatically when Browsersync starts. Defaults to "local" if none set.
     * Can be `true`, `local`, `external`, `ui`, `ui-external`, `tunnel` or `false`
     * @property open
     * @type Boolean|String
     * @default true
     */
    open: "local",

    /**
     * @property browser
     * @type String|Array
     * @default default
     */
    browser: "default",

    /**
     * Add HTTP access control (CORS) headers to assets served by Browsersync.
     * @property cors
     * @type boolean
     * @default false
     * @since 2.16.0
     */
    cors: false,

    hostnameSuffix: false,

    /**
     * Reload each browser when Browsersync is restarted.
     * @property reloadOnRestart
     * @type Boolean
     * @default false
     */
    reloadOnRestart: false,

    /**
     * The small pop-over notifications in the browser are not always needed/wanted.
     * @property notify
     * @type Boolean
     * @default true
     */
    notify: true,

    /**
     * @property scrollProportionally
     * @type Boolean
     * @default true
     */
    scrollProportionally: true,

    /**
     * @property scrollThrottle
     * @type Number
     * @default 0
     */
    scrollThrottle: 0,

    /**
     * Decide which technique should be used to restore
     * scroll position following a reload.
     * Can be `window.name` or `cookie`
     * @property scrollRestoreTechnique
     * @type String
     * @default 'window.name'
     */
    scrollRestoreTechnique: "window.name",

    /**
     * Sync the scroll position of any element
     * on the page. Add any amount of CSS selectors
     * @property scrollElements
     * @type Array
     * @default []
     * @since 2.9.0
     */
    scrollElements: [],

    /**
     * Sync the scroll position of any element
     * on the page - where any scrolled element
     * will cause all others to match scroll position.
     * This is helpful when a breakpoint alters which element
     * is actually scrolling
     * @property scrollElementMapping
     * @type Array
     * @default []
     * @since 2.9.0
     */
    scrollElementMapping: [],

    /**
     * Time, in milliseconds, to wait before
     * instructing the browser to reload/inject following a
     * file change event
     * @property reloadDelay
     * @type Number
     * @default 0
     */
    reloadDelay: 0,

    /**
     * Wait for a specified window of event-silence before
     * sending any reload events.
     * @property reloadDebounce
     * @type Number
     * @default 0
     * @since 2.6.0
     */
    reloadDebounce: 500,

    /**
     * Emit only the first event during sequential time windows
     * of a specified duration.
     * @property reloadThrottle
     * @type Number
     * @default 0
     * @since 2.13.0
     */
    reloadThrottle: 0,

    /**
     * User provided plugins
     * @property plugins
     * @type Array
     * @default []
     * @since 2.6.0
     */
    plugins: [],

    /**
     * @property injectChanges
     * @type Boolean
     * @default true
     */
    injectChanges: true,

    /**
     * @property startPath
     * @type String|Null
     * @default null
     */
    startPath: null,

    /**
     * Whether to minify client script, or not.
     * @property minify
     * @type Boolean
     * @default true
     */
    minify: true,

    /**
     * @property host
     * @type String
     * @default null
     */
    host: null,

    /**
     * Specify a host to listen on. Use this if you want to
     * prevent binding to all interfaces.
     *
     * Note: When you specify this option, it overrides the 'host' option
     * @property listen
     * @type String
     * @default undefined
     */

    /**
     * Support environments where dynamic hostnames are not required
     * (ie: electron)
     * @property localOnly
     * @type Boolean
     * @default false
     * @since 2.14.0
     */
    localOnly: false,

    /**
     * @property codeSync
     * @type Boolean
     * @default true
     */
    codeSync: true,

    /**
     * @property timestamps
     * @type Boolean
     * @default true
     */
    timestamps: true,

    clientEvents: [
        "scroll",
        "scroll:element",
        "input:text",
        "input:toggles",
        "form:submit",
        "form:reset",
        "click"
    ],

    /**
     * Alter the script path for complete control over where the Browsersync
     * Javascript is served from. Whatever you return from this function
     * will be used as the script path.
     * @property scriptPath
     * @default undefined
     * @since 1.5.0
     * @type Function
     */

    /**
     * Configure the Socket.IO path and namespace & domain to avoid collisions.
     * @property socket
     * @param {String} [path="/browser-sync/socket.io"]
     * @param {String} [clientPath="/browser-sync"]
     * @param {String|Function} [namespace="/browser-sync"]
     * @param {String|Function} [domain=undefined]
     * @param {String|Function} [port=undefined]
     * @param {Object} [clients.heartbeatTimeout=5000]
     * @since 1.6.2
     * @type Object
     */
    socket: {
        socketIoOptions: {
            log: false
        },
        socketIoClientConfig: {
            reconnectionAttempts: 50
        },
        path: "/browser-sync/socket.io",
        clientPath: "/browser-sync",
        namespace: "/browser-sync",
        clients: {
            heartbeatTimeout: 5000
        }
    },

    /**
     * Configure the script domain
     * @property script
     * @param {String|Function} [domain=undefined]
     * @since 2.14.0
     * @type Object
     */

    tagNames: {
        less: "link",
        scss: "link",
        css: "link",
        jpg: "img",
        jpeg: "img",
        png: "img",
        svg: "img",
        gif: "img",
        js: "script"
    },

    injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp", "map"],
    injectNotification: false, // console | overlay
    excludedFileTypes: [
        "js",
        "css",
        "pdf",
        "map",
        "svg",
        "ico",
        "woff",
        "json",
        "eot",
        "ttf",
        "png",
        "jpg",
        "jpeg",
        "webp",
        "gif",
        "mp4",
        "mp3",
        "3gp",
        "ogg",
        "ogv",
        "webm",
        "m4a",
        "flv",
        "wmv",
        "avi",
        "swf",
        "scss"
    ]
};


================================================
FILE: packages/browser-sync/lib/file-event-handler.js
================================================
var utils = require("./utils");

/**
 * Apply the operators that apply to the 'file:changed' event
 * @param {Rx.Observable} subject
 * @param options
 * @return {Rx.Observable<{type: string, files: Array<any>}>}
 */
function fileChanges(subject, options) {
    const operators = [
        {
            option: "reloadThrottle",
            fnName: "throttle"
        },
        {
            option: "reloadDelay",
            fnName: "delay"
        }
    ];

    const scheduler = options.getIn(["debug", "scheduler"]);

    /**
     * Create a stream buffered/debounced stream of events
     */
    const initial = getAggregatedDebouncedStream(subject, options, scheduler);

    return applyOperators(operators, initial, options, scheduler).map(function(
        items
    ) {
        const paths = items.map(x => x.path);

        if (
            utils.willCauseReload(paths, options.get("injectFileTypes").toJS())
        ) {
            return {
                type: "reload",
                files: items
            };
        }
        return {
            type: "inject",
            files: items
        };
    });
}
module.exports.fileChanges = fileChanges;

/**
 * Apply the operators that apply to the 'browser:reload' event
 * @param {Rx.Observable} subject
 * @param options
 * @returns {Rx.Observable}
 */
function applyReloadOperators(subject, options) {
    var operators = [
        {
            option: "reloadDebounce",
            fnName: "debounce"
        },
        {
            option: "reloadThrottle",
            fnName: "throttle"
        },
        {
            option: "reloadDelay",
            fnName: "delay"
        }
    ];

    return applyOperators(
        operators,
        subject,
        options,
        options.getIn(["debug", "scheduler"])
    );
}
module.exports.applyReloadOperators = applyReloadOperators;

/**
 * @param items
 * @param subject
 * @param options
 * @param scheduler
 */
function applyOperators(items, subject, options, scheduler) {
    return items.reduce(function(subject, item) {
        var value = options.get(item.option);
        if (value > 0) {
            return subject[item.fnName].call(subject, value, scheduler);
        }
        return subject;
    }, subject);
}

/**
 * @param subject
 * @param options
 * @param scheduler
 */
function getAggregatedDebouncedStream(subject, options, scheduler) {
    return subject
        .filter(function(x) {
            return options.get("watchEvents").indexOf(x.event) > -1;
        })
        .buffer(subject.debounce(options.get("reloadDebounce"), scheduler));
}


================================================
FILE: packages/browser-sync/lib/file-utils.js
================================================
"use strict";

var _ = require("./lodash.custom");

var fileUtils = {
    /**
     * React to file-change events that occur on "core" namespace only
     * @param bs
     * @param data
     */
    changedFile: function(bs, data) {
        /**
         * If the event property is undefined, infer that it's a 'change'
         * event due the fact this handler is for emitter.emit("file:changed")
         */
        if (_.isUndefined(data.event)) {
            data.event = "change";
        }
        /**
         * Chokidar always sends an 'event' property - which could be
         * `add` `unlink` etc etc so we need to check for that and only
         * respond to 'change', for now.
         */
        if (bs.options.get("watchEvents").indexOf(data.event) > -1) {
            if (!bs.paused && data.namespace === "core") {
                bs.events.emit(
                    "file:reload",
                    fileUtils.getFileInfo(data, bs.options)
                );
            }
        }
    },
    /**
     * @param data
     * @param options
     * @returns {{assetFileName: *, fileExtension: String}}
     */
    getFileInfo: function(data, options) {
        data.ext = require("path")
            .extname(data.path)
            .slice(1);
        data.basename = require("path").basename(data.path);

        var obj = {
            ext: data.ext,
            path: data.path,
            basename: data.basename,
            event: data.event,
            type: "inject"
        };

        // RELOAD page
        if (!_.includes(options.get("injectFileTypes").toJS(), obj.ext)) {
            obj.url = obj.path;
            obj.type = "reload";
        }

        obj.path = data.path;
        obj.log = data.log;

        return obj;
    }
};

module.exports = fileUtils;


================================================
FILE: packages/browser-sync/lib/file-watcher.js
================================================
"use strict";

var _ = require("./lodash.custom");
var utils = require("./utils");
var Rx = require("rx");

/**
 * Plugin interface
 * @returns {*|function(this:exports)}
 */
module.exports.plugin = function(bs) {
    var options = bs.options;
    var emitter = bs.emitter;

    var defaultWatchOptions = options.get("watchOptions").toJS();

    return options.get("files").reduce(function(map, glob, namespace) {
        /**
         * Default CB when not given
         * @param event
         * @param path
         */
        var fn = function(event, path) {
            emitter.emit("file:changed", {
                event: event,
                path: path,
                namespace: namespace
            });
        };

        var jsItem = glob.toJS();

        if (jsItem.globs.length) {
            var watcher = watch(jsItem.globs, defaultWatchOptions, fn);
            map[namespace] = {
                watchers: [watcher]
            };
        }

        if (jsItem.objs.length) {
            jsItem.objs.forEach(function(item) {
                if (!_.isFunction(item.fn)) {
                    item.fn = fn;
                }
                var watcher = watch(
                    item.match,
                    item.options || defaultWatchOptions,
                    item.fn.bind(bs.publicInstance)
                );
                if (!map[namespace]) {
                    map[namespace] = {
                        watchers: [watcher]
                    };
                } else {
                    map[namespace].watchers.push(watcher);
                }
            });
        }

        return map;
    }, {});
};

/**
 * @param patterns
 * @param opts
 * @param cb
 * @returns {*}
 */
function watch(patterns, opts, cb) {
    if (typeof opts === "function") {
        cb = opts;
        opts = {};
    }

    var watcher = require("chokidar").watch(patterns, opts);

    if (_.isFunction(cb)) {
        watcher.on("all", cb);
    }

    // watcher.on('ready', () => {
    //     console.log(watcher.getWatched());
    // });

    return watcher;
}

module.exports.watch = watch;


================================================
FILE: packages/browser-sync/lib/hooks.js
================================================
"use strict";

var _ = require("./lodash.custom");
var Immutable = require("immutable");
var snippetUtils = require("./snippet").utils;

module.exports = {
    /**
     *
     * @this {BrowserSync}
     * @returns {String}
     */
    "client:js": function(hooks, data) {
        var js = snippetUtils.getClientJs(data.port, data.options);

        return hooks.reduce(
            function(acc, hook) {
                if (typeof hook === "function") {
                    return acc.concat(hook);
                }
                return acc.concat(String(hook));
            },
            [js]
        );
    },
    /**
     * @this {BrowserSync}
     * @returns {Array}
     */
    "client:events": function(hooks, clientEvents) {
        hooks.forEach(function(hook) {
            var result = hook(this);

            if (Array.isArray(result)) {
                clientEvents = _.union(clientEvents, result);
            } else {
                clientEvents.push(result);
            }
        }, this);

        return clientEvents;
    },
    /**
     * @returns {Array}
     */
    "server:middleware": function(hooks, initial) {
        initial = initial || [];

        _.each(
            hooks,
            function(hook) {
                var result = hook(this);

                if (Array.isArray(result)) {
                    result.forEach(function(res) {
                        if (_.isFunction(res)) {
                            initial = initial.push(res);
                        }
                    });
                } else {
                    if (_.isFunction(result)) {
                        initial = initial.push(result);
                    }
                }
            },
            this
        );

        return initial;
    },
    /**
     * @param {Array} hooks
     * @param {Map|List} initial
     * @param pluginOptions
     * @returns {any}
     */
    "files:watch": function(hooks, initial, pluginOptions) {
        var opts;

        if (pluginOptions) {
            opts = Immutable.fromJS(pluginOptions);
            opts.forEach(function(value, key) {
                if (!value) {
                    return;
                }
                var files = value.get("files");
                if (files) {
                    var fileArg = require("./cli/cli-options").makeFilesArg(
                        files
                    );
                    if (fileArg) {
                        initial = initial.set(key, Immutable.fromJS(fileArg));
                    }
                }
            });
        }

        return initial;
    }
};


================================================
FILE: packages/browser-sync/lib/http-protocol.js
================================================
"use strict";

var proto = exports;
var instanceMethods = ["exit", "notify", "pause", "resume"];
var getBody = require("raw-body");
const { parseParams, serializeParams } = require("./utils");
const permittedSocketEvents = [
    "file:reload",
    "browser:reload",
    "browser:notify",
    "browser:location",
    "options:set"
];

/**
 * Does the requested method expect an instance of BrowserSync
 * or raw access to the emitter?
 * @param method
 * @returns {boolean}
 */
function methodRequiresInstance(method) {
    return instanceMethods.indexOf(method) > -1;
}

/**
 * Use BrowserSync options + querystring to create a
 * full HTTP/HTTTPS url.
 *
 * Eg. http://localhost:3000/__browser_sync__?method=reload
 * Eg. http://localhost:3000/__browser_sync__?method=reload&args=core.css
 * Eg. http://localhost:3000/__browser_sync__?method=reload&args=core.css&args=core.min
 *
 * @param args
 * @param url
 * @returns {string}
 */
proto.getUrl = function(args, url) {
    return [
        url,
        require("./config").httpProtocol.path,
        "?",
        serializeParams(args).toString()
    ].join("");
};

/**
 * Return a middleware for handling the requests
 * @param {BrowserSync} bs
 * @returns {Function}
 */
proto.middleware = function(bs) {
    return function(req, res) {
        if (req.method === "POST") {
            return getBody(req, function(err, body) {
                if (err) {
                    const output = ["Error: could not parse JSON."];
                    res.writeHead(500, { "Content-Type": "text/plain" });
                    return res.end(output.join("\n"));
                }
                try {
                    const [name, payload] = JSON.parse(body.toString());
                    bs.io.sockets.emit(name, payload);
                    return res.end(
                        `Browsersync HTTP Protocol received: ${name} ${JSON.stringify(
                            payload
                        )}`
                    );
                } catch (e) {
                    const output = [`Error: ${e.message}`];
                    res.writeHead(500, { "Content-Type": "text/plain" });
                    return res.end(output.join("\n"));
                }
            });
        }
        var split = req.url.split("?");
        var params = parseParams(split[1]);
        var output;

        if (!Object.keys(params).length) {
            output = [
                "Error: No Parameters were provided.",
                "Example: http://localhost:3000/__browser_sync__?method=reload&args=core.css"
            ];
            res.writeHead(500, { "Content-Type": "text/plain" });
            res.end(output.join("\n"));
            return;
        }

        try {
            var bsOrEmitter = methodRequiresInstance(params.method)
                ? bs
                : bs.events;

            require("./public/" + params.method)(bsOrEmitter).apply(null, [
                params.args
            ]);

            output = [
                "Called public API method `.%s()`".replace("%s", params.method),
                "With args: " + JSON.stringify(params.args)
            ];

            res.end(output.join("\n"));
        } catch (e) {
            res.writeHead(404, { "Content-Type": "text/plain" });
            res.write("Public API method `" + params.method + "` not found.");
            res.end();

            return;
        }
    };
};


================================================
FILE: packages/browser-sync/lib/index.js
================================================
#! /usr/bin/env node
"use strict";

/**
 * @module BrowserSync
 */
var pjson = require("../package.json");
var BrowserSync = require("./browser-sync");
var publicUtils = require("./public/public-utils");
var events = require("events");
var chalk  = require("chalk");
var PassThrough = require("stream").PassThrough;
var logger = require("eazy-logger").Logger({
    useLevelPrefixes: true
});

var singleton = false;
var singletonPlugins = [];
var instances = [];

/**
 * @type {boolean|EventEmitter}
 */
var singletonEmitter = false;

module.exports = initSingleton;

/**
 * Create a Browsersync instance
 * @method create
 * @param {String} name an identifier that can used for retrieval later
 */

/**
 * Get a single instance by name. This is useful if you have your
 * build scripts in separate files
 * @method get
 * @param {String} name
 * @returns {Object|Boolean}
 */
module.exports.get = function(name) {
    var instance = getSingle(name);
    if (instance) {
        return instance;
    }
    throw new Error(
        "An instance with the name `%s` was not found.".replace("%s", name)
    );
};

/**
 * Check if an instance has been created.
 * @method has
 * @param {String} name
 * @returns {Boolean}
 */
module.exports.has = function(name) {
    var instance = getSingle(name);
    if (instance) {
        return true;
    }
    return false;
};

/**
 * Start the Browsersync service. This will launch a server, proxy or start the snippet
 * mode depending on your use-case.
 * @method init
 * @param {Object} [config] This is the main configuration for your Browsersync instance and can contain any of the [available options]({{site.links.options}})
 *  If you do not pass a config an argument for configuration, Browsersync will still run; but it will be in the `snippet` mode
 * @param {Function} [cb] If you pass a callback function, it will be called when Browsersync has completed all setup tasks and is ready to use. This
 * is useful when you need to wait for information (for example: urls, port etc) or perform other tasks synchronously.
 * @returns {BrowserSync}
 */
module.exports.init = initSingleton;

/**
 * Register a plugin. Must implement at least a 'plugin' method that returns a
 * callable function.
 *
 * @method use
 * @param {String} name The name of the plugin
 * @param {Object} module The object to be `required`.
 * @param {Function} [cb] A callback function that will return any errors.
 */
module.exports.use = function() {
    var args = Array.prototype.slice.call(arguments);
    singletonPlugins.push({
        args: args
    });
};

/**
 * The `reload` method will inform all browsers about changed files and will either cause the browser to refresh, or inject the files where possible.
 *
 * @method reload
 * @param {String|Array|Object} [arg] The file or files to be reloaded.
 * @returns {*}
 */
module.exports.reload = noop("reload");

/**
 * The `stream` method returns a transform stream and can act once or on many files.
 *
 * @method stream
 * @param {Object} [opts] Configuration for the stream method
 * @param {Object} [opts.match] Resulting files to reload. The path is from the
 * root of the site (not the root of your project).  You can use '**' to recurse
 * directories.
 * @param {Object} [opts.once] Only reload on the first changed file in the stream.
 * @since 2.6.0
 * @returns {*}
 */
module.exports.stream = noop("stream");

/**
 * Helper method for browser notifications
 *
 * @method notify
 * @param {String|HTML} msg Can be a simple message such as 'Connected' or HTML
 * @param {Number} [timeout] How long the message will remain in the browser. @since 1.3.0
 */
module.exports.notify = noop("notify");

/**
 * This method will close any running server, stop file watching & exit the current process.
 *
 * @method exit
 */
module.exports.exit = noop("exit");

/**
 * Stand alone file-watcher. Use this along with Browsersync to create your own, minimal build system
 * @method watch
 * @param {string} patterns Glob patterns for files to watch
 * @param {object} [opts] Options to be passed to Chokidar - check what's available in [their docs](https://github.com/paulmillr/chokidar#getting-started)
 * @param {function} [fn] Callback function for each event.
 * @since 2.6.0
 */
module.exports.watch = noop("watch");

/**
 * Method to pause file change events
 *
 * @method pause
 */
module.exports.pause = noop("pause");

/**
 * Method to resume paused watchers
 *
 * @method resume
 */
module.exports.resume = noop("resume");

/**
 * Add properties fo
 */
Object.defineProperties(module.exports, {
    /**
     * The internal Event Emitter used by the running Browsersync instance (if there is one).
     * You can use this to emit your own events, such as changed files, logging etc.
     *
     * @property emitter
     */
    emitter: {
        get: function() {
            if (!singletonEmitter) {
                singletonEmitter = newEmitter();
                return singletonEmitter;
            }
            return singletonEmitter;
        }
    },
    /**
     * A simple true/false flag that you can use to determine if there's a currently-running Browsersync instance.
     *
     * @property active
     */
    active: {
        get: getSingletonValue.bind(null, "active")
    },
    /**
     * A simple true/false flag to determine if the current instance is paused
     *
     * @property paused
     */
    paused: {
        get: getSingletonValue.bind(null, "paused")
    }
});

/**
 * Event emitter factory
 * @returns {EventEmitter}
 */
function newEmitter() {
    var emitter = new events.EventEmitter();
    emitter.setMaxListeners(20);
    return emitter;
}

/**
 * Get the singleton's emitter, or a new one.
 * @returns {EventEmitter}
 */
function getSingletonEmitter() {
    if (singletonEmitter) {
        return singletonEmitter;
    }
    singletonEmitter = newEmitter();
    return singletonEmitter;
}

/**
 * Helper to allow methods to be called on the module export
 * before there's a running instance
 * @param {String} name
 * @returns {Function}
 */
function noop(name) {
    return function() {
        var args = Array.prototype.slice.call(arguments);
        if (singleton) {
            return singleton[name].apply(singleton, args);
        } else {
            if (publicUtils.isStreamArg(name, args)) {
                return new PassThrough({ objectMode: true });
            }
        }
    };
}

/**
 * Create a single instance when module export is used directly via browserSync({});
 * This is mostly for back-compatibility, for also for the nicer api.
 * This will never be removed to ensure we never break user-land, but
 * we should discourage it's use.
 * @returns {*}
 */
function initSingleton() {
    var instance;
    if (instances.length) {
        instance = instances.filter(function(item) {
            return item.name === "singleton";
        });
        if (instance.length) {
            logger.error(
                chalk.yellow("You tried to start Browsersync twice!"),
                "To create multiple instances, use",
                chalk.cyan("browserSync.create().init()")
            );
            return instance;
        }
    }
    var args = Array.prototype.slice.call(arguments);
    singleton = create("singleton", getSingletonEmitter());

    if (singletonPlugins.length) {
        singletonPlugins.forEach(function(obj) {
            singleton.instance.registerPlugin.apply(
                singleton.instance,
                obj.args
            );
        });
    }

    singleton.init.apply(null, args);
    return singleton;
}

/**
 * @param {String} prop
 * @returns {Object|Boolean}
 */
function getSingletonValue(prop) {
    var single = getSingle("singleton");
    if (single) {
        return single[prop];
    }
    return false;
}

/**
 * Get a single instance by name
 * @param {String} name
 * @returns {Object|Boolean}
 */
function getSingle(name) {
    if (instances.length) {
        var match = instances.filter(function(item) {
            return item.name === name;
        });
        if (match.length) {
            return match[0];
        }
    }
    return false;
}

/**
 * Create an instance of Browsersync
 * @param {String} [name]
 * @param {EventEmitter} [emitter]
 * @returns {{init: *, exit: (exit|exports), notify: *, reload: *, cleanup: *, emitter: (Browsersync.events|*), use: *}}
 */

/**
 * Reset the state of the module.
 * (should only be needed for test environments)
 */
module.exports.reset = function() {
    instances.forEach(function(item) {
        item.cleanup();
    });
    instances = [];
    singletonPlugins = [];
    singletonEmitter = false;
    singleton = false;
};

/**
 * @type {Array}
 */
module.exports.instances = instances;

/**
 * Create an instance of Browsersync
 * @param {String} [name]
 * @param {EventEmitter} [emitter]
 * @returns {{init: *, exit: (exit|exports), notify: *, reload: *, cleanup: *, emitter: (Browsersync.events|*), use: *}}
 */
module.exports.create = create;
function create(name, emitter) {
    name = name || new Date().getTime();
    emitter = emitter || newEmitter();

    var browserSync = new BrowserSync(emitter);

    var instance = {
        name: name,
        instance: browserSync,
        exit: require("./public/exit")(browserSync),
        notify: require("./public/notify")(browserSync),
        pause: require("./public/pause")(browserSync),
        resume: require("./public/resume")(browserSync),
        reload: require("./public/reload")(emitter),
        stream: require("./public/stream")(emitter),
        cleanup: browserSync.cleanup.bind(browserSync),
        use: browserSync.registerPlugin.bind(browserSync),
        getOption: browserSync.getOption.bind(browserSync),
        emitter: browserSync.events,
        watch: require("./file-watcher").watch
    };

    browserSync.publicInstance = instance;
    instance.init = require("./public/init")(browserSync, name, pjson);

    Object.defineProperty(instance, "active", {
        get: function() {
            return browserSync.active;
        }
    });

    Object.defineProperty(instance, "paused", {
        get: function() {
            return browserSync.paused;
        }
    });

    /**
     * Access to client-side socket for emitting events
     *
     * @property sockets
     */
    Object.defineProperty(instance, "sockets", {
        get: function() {
            if (!browserSync.active) {
                return {
                    emit: function() {},
                    on: function() {}
                };
            } else {
                return browserSync.io.sockets;
            }
        }
    });

    instances.push(instance);

    return instance;
}


================================================
FILE: packages/browser-sync/lib/internal-events.js
================================================
"use strict";

var utils = require("./utils");
var fileUtils = require("./file-utils");
var Rx = require("rx");
var fromEvent = Rx.Observable.fromEvent;
var fileHandler = require("./file-event-handler");

module.exports = function(bs) {
    var events = {
        /**
         * File reloads
         * @param data
         */
        "file:reload": function(data) {
            bs.io.sockets.emit("file:reload", data);
        },
        /**
         * Browser Reloads
         */
        "browser:reload": function() {
            bs.io.sockets.emit("browser:reload");
        },
        /**
         * Browser Notify
         * @param data
         */
        "browser:notify": function(data) {
            bs.io.sockets.emit("browser:notify", data);
        },
        /**
         * Things that happened after the service is running
         * @param data
         */
        "service:running": function(data) {
            var mode = bs.options.get("mode");
            var open = bs.options.get("open");

            if (
                mode === "proxy" ||
                mode === "server" ||
                open === "ui" ||
                open === "ui-external"
            ) {
                utils.openBrowser(data.url, bs.options, bs);
            }

            // log about any file watching
            if (bs.watchers) {
                bs.events.emit("file:watching", bs.watchers);
            }
        },
        /**
         * Option setting
         * @param data
         */
        "options:set": function(data) {
            if (bs.io) {
                bs.io.sockets.emit("options:set", data);
            }
        },
        /**
         * Plugin configuration setting
         * @param data
         */
        "plugins:configure": function(data) {
            if (data.active) {
                bs.pluginManager.enablePlugin(data.name);
            } else {
                bs.pluginManager.disablePlugin(data.name);
            }
            bs.setOption("userPlugins", bs.getUserPlugins());
        },
        "plugins:opts": function(data) {
            if (bs.pluginManager.pluginOptions[data.name]) {
                bs.pluginManager.pluginOptions[data.name] = data.opts;
                bs.setOption("userPlugins", bs.getUserPlugins());
            }
        }
    };

    Object.keys(events).forEach(function(event) {
        bs.events.on(event, events[event]);
    });

    var reloader = fileHandler
        .applyReloadOperators(
            fromEvent(bs.events, "_browser:reload"),
            bs.options
        )
        .subscribe(function() {
            bs.events.emit("browser:reload");
        });

    var coreNamespacedWatchers = fromEvent(bs.events, "file:changed")
        .filter(function() {
            return bs.options.get("codeSync");
        })
        .filter(function(x) {
            return x.namespace === "core";
        });

    var handler = fileHandler
        .fileChanges(coreNamespacedWatchers, bs.options)
        .subscribe(function(x) {
            if (x.type === "reload") {
                bs.events.emit("browser:reload", x);
            }
            if (x.type === "inject") {
                x.files.forEach(function(data) {
                    if (!bs.paused && data.namespace === "core") {
                        bs.events.emit(
                            "file:reload",
                            fileUtils.getFileInfo(data, bs.options)
                        );
                    }
                });
            }
        });

    bs.registerCleanupTask(function() {
        handler.dispose();
        reloader.dispose();
    });
};


================================================
FILE: packages/browser-sync/lib/lodash.custom.js
================================================
/**
 * @license
 * Lodash (Custom Build) <https://lodash.com/>
 * Build: `lodash include="isUndefined,isFunction,toArray,includes,union,each,isString,merge,isObject,set" exports="node"`
 * Copyright JS Foundation and other contributors <https://js.foundation/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */
(function() {
    /** Used as a safe reference for `undefined` in pre-ES5 environments. */
    var undefined;

    /** Used as the semantic version number. */
    var VERSION = "4.17.4";

    /** Used as the size to enable large array optimizations. */
    var LARGE_ARRAY_SIZE = 200;

    /** Error message constants. */
    var FUNC_ERROR_TEXT = "Expected a function";

    /** Used to stand-in for `undefined` hash values. */
    var HASH_UNDEFINED = "__lodash_hash_undefined__";

    /** Used as the maximum memoize cache size. */
    var MAX_MEMOIZE_SIZE = 500;

    /** Used to compose bitmasks for cloning. */
    var CLONE_DEEP_FLAG = 1,
        CLONE_FLAT_FLAG = 2,
        CLONE_SYMBOLS_FLAG = 4;

    /** Used to compose bitmasks for value comparisons. */
    var COMPARE_PARTIAL_FLAG = 1,
        COMPARE_UNORDERED_FLAG = 2;

    /** Used to detect hot functions by number of calls within a span of milliseconds. */
    var HOT_COUNT = 800,
        HOT_SPAN = 16;

    /** Used as references for various `Number` constants. */
    var INFINITY = 1 / 0,
        MAX_SAFE_INTEGER = 9007199254740991,
        MAX_INTEGER = 1.7976931348623157e308,
        NAN = 0 / 0;

    /** `Object#toString` result references. */
    var argsTag = "[object Arguments]",
        arrayTag = "[object Array]",
        asyncTag = "[object AsyncFunction]",
        boolTag = "[object Boolean]",
        dateTag = "[object Date]",
        errorTag = "[object Error]",
        funcTag = "[object Function]",
        genTag = "[object GeneratorFunction]",
        mapTag = "[object Map]",
        numberTag = "[object Number]",
        nullTag = "[object Null]",
        objectTag = "[object Object]",
        promiseTag = "[object Promise]",
        proxyTag = "[object Proxy]",
        regexpTag = "[object RegExp]",
        setTag = "[object Set]",
        stringTag = "[object String]",
        symbolTag = "[object Symbol]",
        undefinedTag = "[object Undefined]",
        weakMapTag = "[object WeakMap]";

    var arrayBufferTag = "[object ArrayBuffer]",
        dataViewTag = "[object DataView]",
        float32Tag = "[object Float32Array]",
        float64Tag = "[object Float64Array]",
        int8Tag = "[object Int8Array]",
        int16Tag = "[object Int16Array]",
        int32Tag = "[object Int32Array]",
        uint8Tag = "[object Uint8Array]",
        uint8ClampedTag = "[object Uint8ClampedArray]",
        uint16Tag = "[object Uint16Array]",
        uint32Tag = "[object Uint32Array]";

    /** Used to match property names within property paths. */
    var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
        reIsPlainProp = /^\w*$/,
        reLeadingDot = /^\./,
        rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;

    /**
     * Used to match `RegExp`
     * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
     */
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

    /** Used to match leading and trailing whitespace. */
    var reTrim = /^\s+|\s+$/g;

    /** Used to match backslashes in property paths. */
    var reEscapeChar = /\\(\\)?/g;

    /** Used to match `RegExp` flags from their coerced string values. */
    var reFlags = /\w*$/;

    /** Used to detect bad signed hexadecimal string values. */
    var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

    /** Used to detect binary string values. */
    var reIsBinary = /^0b[01]+$/i;

    /** Used to detect host constructors (Safari). */
    var reIsHostCtor = /^\[object .+?Constructor\]$/;

    /** Used to detect octal string values. */
    var reIsOctal = /^0o[0-7]+$/i;

    /** Used to detect unsigned integer values. */
    var reIsUint = /^(?:0|[1-9]\d*)$/;

    /** Used to compose unicode character classes. */
    var rsAstralRange = "\\ud800-\\udfff",
        rsComboMarksRange = "\\u0300-\\u036f",
        reComboHalfMarksRange = "\\ufe20-\\ufe2f",
        rsComboSymbolsRange = "\\u20d0-\\u20ff",
        rsComboRange =
            rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
        rsVarRange = "\\ufe0e\\ufe0f";

    /** Used to compose unicode capture groups. */
    var rsAstral = "[" + rsAstralRange + "]",
        rsCombo = "[" + rsComboRange + "]",
        rsFitz = "\\ud83c[\\udffb-\\udfff]",
        rsModifier = "(?:" + rsCombo + "|" + rsFitz + ")",
        rsNonAstral = "[^" + rsAstralRange + "]",
        rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}",
        rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]",
        rsZWJ = "\\u200d";

    /** Used to compose unicode regexes. */
    var reOptMod = rsModifier + "?",
        rsOptVar = "[" + rsVarRange + "]?",
        rsOptJoin =
            "(?:" +
            rsZWJ +
            "(?:" +
            [rsNonAstral, rsRegional, rsSurrPair].join("|") +
            ")" +
            rsOptVar +
            reOptMod +
            ")*",
        rsSeq = rsOptVar + reOptMod + rsOptJoin,
        rsSymbol =
            "(?:" +
            [
                rsNonAstral + rsCombo + "?",
                rsCombo,
                rsRegional,
                rsSurrPair,
                rsAstral
            ].join("|") +
            ")";

    /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
    var reUnicode = RegExp(
        rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq,
        "g"
    );

    /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
    var reHasUnicode = RegExp(
        "[" + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + "]"
    );

    /** Used to identify `toStringTag` values of typed arrays. */
    var typedArrayTags = {};
    typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[
        int8Tag
    ] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[
        uint8Tag
    ] = typedArrayTags[uint8ClampedTag] = typedArrayTags[
        uint16Tag
    ] = typedArrayTags[uint32Tag] = true;
    typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[
        arrayBufferTag
    ] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[
        dateTag
    ] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[
        mapTag
    ] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[
        regexpTag
    ] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[
        weakMapTag
    ] = false;

    /** Used to identify `toStringTag` values supported by `_.clone`. */
    var cloneableTags = {};
    cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[
        arrayBufferTag
    ] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[
        dateTag
    ] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[
        int8Tag
    ] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[
        mapTag
    ] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[
        regexpTag
    ] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[
        symbolTag
    ] = cloneableTags[uint8Tag] = cloneableTags[
        uint8ClampedTag
    ] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
    cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[
        weakMapTag
    ] = false;

    /** Built-in method references without a dependency on `root`. */
    var freeParseInt = parseInt;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal =
        typeof global == "object" &&
        global &&
        global.Object === Object &&
        global;

    /** Detect free variable `self`. */
    var freeSelf =
        typeof self == "object" && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root = freeGlobal || freeSelf || Function("return this")();

    /** Detect free variable `exports`. */
    var freeExports =
        typeof exports == "object" && exports && !exports.nodeType && exports;

    /** Detect free variable `module`. */
    var freeModule =
        freeExports &&
        typeof module == "object" &&
        module &&
        !module.nodeType &&
        module;

    /** Detect the popular CommonJS extension `module.exports`. */
    var moduleExports = freeModule && freeModule.exports === freeExports;

    /** Detect free variable `process` from Node.js. */
    var freeProcess = moduleExports && freeGlobal.process;

    /** Used to access faster Node.js helpers. */
    var nodeUtil = (function() {
        try {
            return (
                freeProcess &&
                freeProcess.binding &&
                freeProcess.binding("util")
            );
        } catch (e) {}
    })();

    /* Node.js helper references. */
    var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;

    /*--------------------------------------------------------------------------*/

    /**
     * Adds the key-value `pair` to `map`.
     *
     * @private
     * @param {Object} map The map to modify.
     * @param {Array} pair The key-value pair to add.
     * @returns {Object} Returns `map`.
     */
    function addMapEntry(map, pair) {
        // Don't return `map.set` because it's not chainable in IE 11.
        map.set(pair[0], pair[1]);
        return map;
    }

    /**
     * Adds `value` to `set`.
     *
     * @private
     * @param {Object} set The set to modify.
     * @param {*} value The value to add.
     * @returns {Object} Returns `set`.
     */
    function addSetEntry(set, value) {
        // Don't return `set.add` because it's not chainable in IE 11.
        set.add(value);
        return set;
    }

    /**
     * A faster alternative to `Function#apply`, this function invokes `func`
     * with the `this` binding of `thisArg` and the arguments of `args`.
     *
     * @private
     * @param {Function} func The function to invoke.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {Array} args The arguments to invoke `func` with.
     * @returns {*} Returns the result of `func`.
     */
    function apply(func, thisArg, args) {
        switch (args.length) {
            case 0:
                return func.call(thisArg);
            case 1:
                return func.call(thisArg, args[0]);
            case 2:
                return func.call(thisArg, args[0], args[1]);
            case 3:
                return func.call(thisArg, args[0], args[1], args[2]);
        }
        return func.apply(thisArg, args);
    }

    /**
     * A specialized version of `_.forEach` for arrays without support for
     * iteratee shorthands.
     *
     * @private
     * @param {Array} [array] The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns `array`.
     */
    function arrayEach(array, iteratee) {
        var index = -1,
            length = array == null ? 0 : array.length;

        while (++index < length) {
            if (iteratee(array[index], index, array) === false) {
                break;
            }
        }
        return array;
    }

    /**
     * A specialized version of `_.filter` for arrays without support for
     * iteratee shorthands.
     *
     * @private
     * @param {Array} [array] The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Array} Returns the new filtered array.
     */
    function arrayFilter(array, predicate) {
        var index = -1,
            length = array == null ? 0 : array.length,
            resIndex = 0,
            result = [];

        while (++index < length) {
            var value = array[index];
            if (predicate(value, index, array)) {
                result[resIndex++] = value;
            }
        }
        return result;
    }

    /**
     * A specialized version of `_.includes` for arrays without support for
     * specifying an index to search from.
     *
     * @private
     * @param {Array} [array] The array to inspect.
     * @param {*} target The value to search for.
     * @returns {boolean} Returns `true` if `target` is found, else `false`.
     */
    function arrayIncludes(array, value) {
        var length = array == null ? 0 : array.length;
        return !!length && baseIndexOf(array, value, 0) > -1;
    }

    /**
     * This function is like `arrayIncludes` except that it accepts a comparator.
     *
     * @private
     * @param {Array} [array] The array to inspect.
     * @param {*} target The value to search for.
     * @param {Function} comparator The comparator invoked per element.
     * @returns {boolean} Returns `true` if `target` is found, else `false`.
     */
    function arrayIncludesWith(array, value, comparator) {
        var index = -1,
            length = array == null ? 0 : array.length;

        while (++index < length) {
            if (comparator(value, array[index])) {
                return true;
            }
        }
        return false;
    }

    /**
     * A specialized version of `_.map` for arrays without support for iteratee
     * shorthands.
     *
     * @private
     * @param {Array} [array] The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the new mapped array.
     */
    function arrayMap(array, iteratee) {
        var index = -1,
            length = array == null ? 0 : array.length,
            result = Array(length);

        while (++index < length) {
            result[index] = iteratee(array[index], index, array);
        }
        return result;
    }

    /**
     * Appends the elements of `values` to `array`.
     *
     * @private
     * @param {Array} array The array to modify.
     * @param {Array} values The values to append.
     * @returns {Array} Returns `array`.
     */
    function arrayPush(array, values) {
        var index = -1,
            length = values.length,
            offset = array.length;

        while (++index < length) {
            array[offset + index] = values[index];
        }
        return array;
    }

    /**
     * A specialized version of `_.reduce` for arrays without support for
     * iteratee shorthands.
     *
     * @private
     * @param {Array} [array] The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {boolean} [initAccum] Specify using the first element of `array` as
     *  the initial value.
     * @returns {*} Returns the accumulated value.
     */
    function arrayReduce(array, iteratee, accumulator, initAccum) {
        var index = -1,
            length = array == null ? 0 : array.length;

        if (initAccum && length) {
            accumulator = array[++index];
        }
        while (++index < length) {
            accumulator = iteratee(accumulator, array[index], index, array);
        }
        return accumulator;
    }

    /**
     * A specialized version of `_.some` for arrays without support for iteratee
     * shorthands.
     *
     * @private
     * @param {Array} [array] The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     */
    function arraySome(array, predicate) {
        var index = -1,
            length = array == null ? 0 : array.length;

        while (++index < length) {
            if (predicate(array[index], index, array)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Converts an ASCII `string` to an array.
     *
     * @private
     * @param {string} string The string to convert.
     * @returns {Array} Returns the converted array.
     */
    function asciiToArray(string) {
        return string.split("");
    }

    /**
     * The base implementation of `_.findIndex` and `_.findLastIndex` without
     * support for iteratee shorthands.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} predicate The function invoked per iteration.
     * @param {number} fromIndex The index to search from.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {number} Returns the index of the matched value, else `-1`.
     */
    function baseFindIndex(array, predicate, fromIndex, fromRight) {
        var length = array.length,
            index = fromIndex + (fromRight ? 1 : -1);

        while (fromRight ? index-- : ++index < length) {
            if (predicate(array[index], index, array)) {
                return index;
            }
        }
        return -1;
    }

    /**
     * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} value The value to search for.
     * @param {number} fromIndex The index to search from.
     * @returns {number} Returns the index of the matched value, else `-1`.
     */
    function baseIndexOf(array, value, fromIndex) {
        return value === value
            ? strictIndexOf(array, value, fromIndex)
            : baseFindIndex(array, baseIsNaN, fromIndex);
    }

    /**
     * The base implementation of `_.isNaN` without support for number objects.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
     */
    function baseIsNaN(value) {
        return value !== value;
    }

    /**
     * The base implementation of `_.property` without support for deep paths.
     *
     * @private
     * @param {string} key The key of the property to get.
     * @returns {Function} Returns the new accessor function.
     */
    function baseProperty(key) {
        return function(object) {
            return object == null ? undefined : object[key];
        };
    }

    /**
     * The base implementation of `_.times` without support for iteratee shorthands
     * or max array length checks.
     *
     * @private
     * @param {number} n The number of times to invoke `iteratee`.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the array of results.
     */
    function baseTimes(n, iteratee) {
        var index = -1,
            result = Array(n);

        while (++index < n) {
            result[index] = iteratee(index);
        }
        return result;
    }

    /**
     * The base implementation of `_.unary` without support for storing metadata.
     *
     * @private
     * @param {Function} func The function to cap arguments for.
     * @returns {Function} Returns the new capped function.
     */
    function baseUnary(func) {
        return function(value) {
            return func(value);
        };
    }

    /**
     * The base implementation of `_.values` and `_.valuesIn` which creates an
     * array of `object` property values corresponding to the property names
     * of `props`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array} props The property names to get values for.
     * @returns {Object} Returns the array of property values.
     */
    function baseValues(object, props) {
        return arrayMap(props, function(key) {
            return object[key];
        });
    }

    /**
     * Checks if a `cache` value for `key` exists.
     *
     * @private
     * @param {Object} cache The cache to query.
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function cacheHas(cache, key) {
        return cache.has(key);
    }

    /**
     * Gets the value at `key` of `object`.
     *
     * @private
     * @param {Object} [object] The object to query.
     * @param {string} key The key of the property to get.
     * @returns {*} Returns the property value.
     */
    function getValue(object, key) {
        return object == null ? undefined : object[key];
    }

    /**
     * Checks if `string` contains Unicode symbols.
     *
     * @private
     * @param {string} string The string to inspect.
     * @returns {boolean} Returns `true` if a symbol is found, else `false`.
     */
    function hasUnicode(string) {
        return reHasUnicode.test(string);
    }

    /**
     * Converts `iterator` to an array.
     *
     * @private
     * @param {Object} iterator The iterator to convert.
     * @returns {Array} Returns the converted array.
     */
    function iteratorToArray(iterator) {
        var data,
            result = [];

        while (!(data = iterator.next()).done) {
            result.push(data.value);
        }
        return result;
    }

    /**
     * Converts `map` to its key-value pairs.
     *
     * @private
     * @param {Object} map The map to convert.
     * @returns {Array} Returns the key-value pairs.
     */
    function mapToArray(map) {
        var index = -1,
            result = Array(map.size);

        map.forEach(function(value, key) {
            result[++index] = [key, value];
        });
        return result;
    }

    /**
     * Creates a unary function that invokes `func` with its argument transformed.
     *
     * @private
     * @param {Function} func The function to wrap.
     * @param {Function} transform The argument transform.
     * @returns {Function} Returns the new function.
     */
    function overArg(func, transform) {
        return function(arg) {
            return func(transform(arg));
        };
    }

    /**
     * Converts `set` to an array of its values.
     *
     * @private
     * @param {Object} set The set to convert.
     * @returns {Array} Returns the values.
     */
    function setToArray(set) {
        var index = -1,
            result = Array(set.size);

        set.forEach(function(value) {
            result[++index] = value;
        });
        return result;
    }

    /**
     * A specialized version of `_.indexOf` which performs strict equality
     * comparisons of values, i.e. `===`.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} value The value to search for.
     * @param {number} fromIndex The index to search from.
     * @returns {number} Returns the index of the matched value, else `-1`.
     */
    function strictIndexOf(array, value, fromIndex) {
        var index = fromIndex - 1,
            length = array.length;

        while (++index < length) {
            if (array[index] === value) {
                return index;
            }
        }
        return -1;
    }

    /**
     * Converts `string` to an array.
     *
     * @private
     * @param {string} string The string to convert.
     * @returns {Array} Returns the converted array.
     */
    function stringToArray(string) {
        return hasUnicode(string)
            ? unicodeToArray(string)
            : asciiToArray(string);
    }

    /**
     * Converts a Unicode `string` to an array.
     *
     * @private
     * @param {string} string The string to convert.
     * @returns {Array} Returns the converted array.
     */
    function unicodeToArray(string) {
        return string.match(reUnicode) || [];
    }

    /*--------------------------------------------------------------------------*/

    /** Used for built-in method references. */
    var arrayProto = Array.prototype,
        funcProto = Function.prototype,
        objectProto = Object.prototype;

    /** Used to detect overreaching core-js shims. */
    var coreJsData = root["__core-js_shared__"];

    /** Used to resolve the decompiled source of functions. */
    var funcToString = funcProto.toString;

    /** Used to check objects for own properties. */
    var hasOwnProperty = objectProto.hasOwnProperty;

    /** Used to detect methods masquerading as native. */
    var maskSrcKey = (function() {
        var uid = /[^.]+$/.exec(
            (coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO) || ""
        );
        return uid ? "Symbol(src)_1." + uid : "";
    })();

    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */
    var nativeObjectToString = objectProto.toString;

    /** Used to infer the `Object` constructor. */
    var objectCtorString = funcToString.call(Object);

    /** Used to detect if a method is native. */
    var reIsNative = RegExp(
        "^" +
            funcToString
                .call(hasOwnProperty)
                .replace(reRegExpChar, "\\$&")
                .replace(
                    /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
                    "$1.*?"
                ) +
            "$"
    );

    /** Built-in value references. */
    var Buffer = moduleExports ? root.Buffer : undefined,
        Symbol = root.Symbol,
        Uint8Array = root.Uint8Array,
        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
        getPrototype = overArg(Object.getPrototypeOf, Object),
        objectCreate = Object.create,
        propertyIsEnumerable = objectProto.propertyIsEnumerable,
        splice = arrayProto.splice,
        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
        symIterator = Symbol ? Symbol.iterator : undefined,
        symToStringTag = Symbol ? Symbol.toStringTag : undefined;

    var defineProperty = (function() {
        try {
            var func = getNative(Object, "defineProperty");
            func({}, "", {});
            return func;
        } catch (e) {}
    })();

    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeGetSymbols = Object.getOwnPropertySymbols,
        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
        nativeKeys = overArg(Object.keys, Object),
        nativeMax = Math.max,
        nativeNow = Date.now;

    /* Built-in method references that are verified to be native. */
    var DataView = getNative(root, "DataView"),
        Map = getNative(root, "Map"),
        Promise = getNative(root, "Promise"),
        Set = getNative(root, "Set"),
        WeakMap = getNative(root, "WeakMap"),
        nativeCreate = getNative(Object, "create");

    /** Used to lookup unminified function names. */
    var realNames = {};

    /** Used to detect maps, sets, and weakmaps. */
    var dataViewCtorString = toSource(DataView),
        mapCtorString = toSource(Map),
        promiseCtorString = toSource(Promise),
        setCtorString = toSource(Set),
        weakMapCtorString = toSource(WeakMap);

    /** Used to convert symbols to primitives and strings. */
    var symbolProto = Symbol ? Symbol.prototype : undefined,
        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
        symbolToString = symbolProto ? symbolProto.toString : undefined;

    /*------------------------------------------------------------------------*/

    /**
     * Creates a `lodash` object which wraps `value` to enable implicit method
     * chain sequences. Methods that operate on and return arrays, collections,
     * and functions can be chained together. Methods that retrieve a single value
     * or may return a primitive value will automatically end the chain sequence
     * and return the unwrapped value. Otherwise, the value must be unwrapped
     * with `_#value`.
     *
     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
     * enabled using `_.chain`.
     *
     * The execution of chained methods is lazy, that is, it's deferred until
     * `_#value` is implicitly or explicitly called.
     *
     * Lazy evaluation allows several methods to support sho
Download .txt
gitextract_5fuwfm2s/

├── .editorconfig
├── .gitattributes
├── .github/
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── changelog.js
├── examples/
│   ├── 404.js
│   ├── basic/
│   │   └── run.js
│   ├── callback.js
│   ├── express.js
│   ├── less.js
│   ├── middleware.css.injection.js
│   ├── notify-styles.js
│   ├── options.snippetOptions.js
│   ├── proxy.gzip.js
│   ├── proxy.headers.js
│   ├── proxy.localhost.js
│   ├── proxy.middleware.js
│   ├── proxy.middleware.multi.js
│   ├── proxy.proxyRes.js
│   ├── proxy.rewriteRules.advanced.js
│   ├── proxy.rewriteRules.simple.js
│   ├── proxy.secure.js
│   ├── proxy.vhost.js
│   ├── server.basedir.js
│   ├── server.basedir.mulitple.js
│   ├── server.default.js
│   ├── server.gzip.js
│   ├── server.http2.js
│   ├── server.latency.js
│   ├── server.middleware.js
│   ├── server.middleware.multiple.js
│   ├── server.proxy.js
│   ├── server.secure.js
│   ├── server.secure.pfx.js
│   ├── server.watch.js
│   └── snippet/
│       ├── index.html
│       └── run.js
├── lerna.json
├── nx.json
├── package.json
├── packages/
│   ├── browser-sync/
│   │   ├── .gitignore
│   │   ├── .prettierignore
│   │   ├── certs/
│   │   │   ├── browsersync.pfx
│   │   │   ├── gen.sh
│   │   │   ├── server.crt
│   │   │   ├── server.csr
│   │   │   └── server.key
│   │   ├── cli-options/
│   │   │   ├── opts.init.json
│   │   │   ├── opts.recipe.json
│   │   │   ├── opts.reload.json
│   │   │   └── opts.start.json
│   │   ├── lib/
│   │   │   ├── args.js
│   │   │   ├── async-tasks.js
│   │   │   ├── async.js
│   │   │   ├── bin.ts
│   │   │   ├── browser-sync.js
│   │   │   ├── cli/
│   │   │   │   ├── cli-info.js
│   │   │   │   ├── cli-options.ts
│   │   │   │   ├── command.init.js
│   │   │   │   ├── command.recipe.js
│   │   │   │   ├── command.reload.js
│   │   │   │   ├── command.start.ts
│   │   │   │   └── transforms/
│   │   │   │       ├── addCwdToWatchOptions.ts
│   │   │   │       ├── addDefaultIgnorePatterns.ts
│   │   │   │       ├── addToFilesOption.ts
│   │   │   │       ├── appendServerDirectoryOption.ts
│   │   │   │       ├── appendServerIndexOption.ts
│   │   │   │       ├── copyCLIIgnoreToWatchOptions.ts
│   │   │   │       ├── handleExtensionsOption.ts
│   │   │   │       ├── handleFilesOption.ts
│   │   │   │       ├── handleGhostModeOption.ts
│   │   │   │       ├── handleHostOption.ts
│   │   │   │       ├── handlePortsOption.ts
│   │   │   │       ├── handleProxyOption.ts
│   │   │   │       └── handleServerOption.ts
│   │   │   ├── config.js
│   │   │   ├── connect-utils.js
│   │   │   ├── default-config.js
│   │   │   ├── file-event-handler.js
│   │   │   ├── file-utils.js
│   │   │   ├── file-watcher.js
│   │   │   ├── hooks.js
│   │   │   ├── http-protocol.js
│   │   │   ├── index.js
│   │   │   ├── internal-events.js
│   │   │   ├── lodash.custom.js
│   │   │   ├── logger.js
│   │   │   ├── options.ts
│   │   │   ├── plugins.js
│   │   │   ├── public/
│   │   │   │   ├── exit.js
│   │   │   │   ├── init.ts
│   │   │   │   ├── notify.js
│   │   │   │   ├── pause.js
│   │   │   │   ├── public-utils.js
│   │   │   │   ├── reload.js
│   │   │   │   ├── resume.js
│   │   │   │   └── stream.js
│   │   │   ├── server/
│   │   │   │   ├── index.js
│   │   │   │   ├── proxy-server.js
│   │   │   │   ├── proxy-utils.js
│   │   │   │   ├── serve-static-wrapper.ts
│   │   │   │   ├── snippet-server.js
│   │   │   │   ├── static-server.js
│   │   │   │   └── utils.js
│   │   │   ├── snippet.js
│   │   │   ├── sockets.ts
│   │   │   ├── tunnel.js
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── templates/
│   │   │   ├── cli-template.js
│   │   │   ├── connector.tmpl
│   │   │   ├── script-tags-simple.html
│   │   │   └── script-tags.html
│   │   ├── test/
│   │   │   ├── env.js
│   │   │   ├── fixtures/
│   │   │   │   ├── .tmp/
│   │   │   │   │   └── temp.css
│   │   │   │   ├── alt/
│   │   │   │   │   └── index.htm
│   │   │   │   ├── assets/
│   │   │   │   │   ├── import.css
│   │   │   │   │   ├── import2.css
│   │   │   │   │   ├── print.css
│   │   │   │   │   └── style.css
│   │   │   │   ├── base.html
│   │   │   │   ├── bootstrap/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   ├── bootstrap-grid.css
│   │   │   │   │   │   ├── bootstrap-reboot.css
│   │   │   │   │   │   ├── bootstrap.css
│   │   │   │   │   │   └── justified-nav.css
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── js/
│   │   │   │   │       ├── bootstrap.bundle.js
│   │   │   │   │       └── bootstrap.js
│   │   │   │   ├── bootstrap.html
│   │   │   │   ├── bower.html
│   │   │   │   ├── bower_components/
│   │   │   │   │   └── app.css
│   │   │   │   ├── config/
│   │   │   │   │   ├── config.js
│   │   │   │   │   ├── si-config-partial.js
│   │   │   │   │   ├── si-config-ports.js
│   │   │   │   │   ├── si-config-proxy.js
│   │   │   │   │   ├── si-config.js
│   │   │   │   │   └── si-default-config.js
│   │   │   │   ├── css/
│   │   │   │   │   ├── bootstrap-less.css
│   │   │   │   │   ├── bootstrap-scss.css
│   │   │   │   │   └── bootstrap.css
│   │   │   │   ├── fonts/
│   │   │   │   │   └── roboto/
│   │   │   │   │       ├── Roboto-Regular-demo.html
│   │   │   │   │       └── stylesheet.css
│   │   │   │   ├── forms.html
│   │   │   │   ├── iframe.html
│   │   │   │   ├── images.html
│   │   │   │   ├── import-link.html
│   │   │   │   ├── import.html
│   │   │   │   ├── index-amd.html
│   │   │   │   ├── index-large.html
│   │   │   │   ├── index-urls.html
│   │   │   │   ├── index.html
│   │   │   │   ├── inputs.html
│   │   │   │   ├── js/
│   │   │   │   │   ├── default.js
│   │   │   │   │   └── main.js
│   │   │   │   ├── less/
│   │   │   │   │   └── bootstrap.less
│   │   │   │   ├── less.html
│   │   │   │   ├── links.html
│   │   │   │   ├── plugin.js
│   │   │   │   ├── proxy-headers.html
│   │   │   │   ├── proxy-ip.html
│   │   │   │   ├── proxy-vhost.html
│   │   │   │   ├── rewrites/
│   │   │   │   │   ├── comment.expected.html
│   │   │   │   │   ├── comment.html
│   │   │   │   │   ├── escaped.1.expected.html
│   │   │   │   │   ├── escaped.1.html
│   │   │   │   │   ├── hashes.expected.html
│   │   │   │   │   └── hashes.input.html
│   │   │   │   ├── sass.html
│   │   │   │   ├── scrolling.html
│   │   │   │   ├── scss/
│   │   │   │   │   └── bootstrap-scss.scss
│   │   │   │   ├── socket.io.html
│   │   │   │   ├── stylus/
│   │   │   │   │   └── bootstrap.styl
│   │   │   │   ├── svg.html
│   │   │   │   ├── tailwind/
│   │   │   │   │   └── index.html
│   │   │   │   ├── test.txt
│   │   │   │   ├── test2.txt
│   │   │   │   ├── username.github.io/
│   │   │   │   │   └── index.html
│   │   │   │   └── watch-func.txt
│   │   │   ├── fixtures2/
│   │   │   │   └── style-alt.css
│   │   │   ├── protractor/
│   │   │   │   ├── _run.js
│   │   │   │   ├── bs.init.js
│   │   │   │   ├── config.multi.js
│   │   │   │   ├── config.single.js
│   │   │   │   ├── logger.js
│   │   │   │   ├── runProtractor.js
│   │   │   │   ├── setup.js
│   │   │   │   ├── setup.single.js
│   │   │   │   ├── tests/
│   │   │   │   │   ├── actions.clicks.js
│   │   │   │   │   ├── actions.scroll.js
│   │   │   │   │   ├── proxy.interactions.js
│   │   │   │   │   ├── proxy.rewrites.js
│   │   │   │   │   ├── server.interactions.js
│   │   │   │   │   ├── snippet.injection.js
│   │   │   │   │   ├── with.baseurl.https.js
│   │   │   │   │   ├── with.baseurl.js
│   │   │   │   │   └── with.socket.io.js
│   │   │   │   ├── tests.multi.js
│   │   │   │   ├── tests.single.js
│   │   │   │   └── utils.js
│   │   │   ├── specs/
│   │   │   │   ├── api/
│   │   │   │   │   ├── init.active.js
│   │   │   │   │   ├── init.exit.js
│   │   │   │   │   ├── init.js
│   │   │   │   │   ├── init.notify.js
│   │   │   │   │   ├── init.pause.js
│   │   │   │   │   ├── init.reload.deprecated.js
│   │   │   │   │   ├── init.reload.js
│   │   │   │   │   ├── init.reload.multi.js
│   │   │   │   │   ├── init.reload.stream.js
│   │   │   │   │   ├── init.reload.stream.noop.js
│   │   │   │   │   ├── init.returns.js
│   │   │   │   │   ├── init.sockets.js
│   │   │   │   │   └── watch.js
│   │   │   │   ├── cli/
│   │   │   │   │   ├── cli.exec.js
│   │   │   │   │   ├── cli.get.config.js
│   │   │   │   │   ├── cli.help.js
│   │   │   │   │   ├── cli.info.js
│   │   │   │   │   ├── cli.options.files.js
│   │   │   │   │   ├── cli.options.ghost.js
│   │   │   │   │   ├── cli.options.ignore.js
│   │   │   │   │   ├── cli.options.ports.js
│   │   │   │   │   ├── cli.options.proxy.js
│   │   │   │   │   ├── cli.options.server.js
│   │   │   │   │   ├── cli.options.watch.js
│   │   │   │   │   └── cli.options.watchOptions.cwd.js
│   │   │   │   ├── commands/
│   │   │   │   │   ├── recipes.js
│   │   │   │   │   └── reload.js
│   │   │   │   ├── e2e/
│   │   │   │   │   ├── cli/
│   │   │   │   │   │   ├── e2e.cli.conf.js
│   │   │   │   │   │   ├── e2e.cli.error.js
│   │   │   │   │   │   ├── e2e.cli.files.js
│   │   │   │   │   │   ├── e2e.cli.init.js
│   │   │   │   │   │   ├── e2e.cli.plugins.js
│   │   │   │   │   │   ├── e2e.cli.proxy.js
│   │   │   │   │   │   ├── e2e.cli.proxy.ws.js
│   │   │   │   │   │   ├── e2e.cli.server.js
│   │   │   │   │   │   ├── e2e.cli.snippet.js
│   │   │   │   │   │   └── e2e.cli.ui.js
│   │   │   │   │   ├── commands.server.json
│   │   │   │   │   ├── e2e.events.js
│   │   │   │   │   ├── e2e.fail.js
│   │   │   │   │   ├── e2e.online.js
│   │   │   │   │   ├── e2e.options.callbacks.js
│   │   │   │   │   ├── e2e.options.cors.js
│   │   │   │   │   ├── e2e.options.js
│   │   │   │   │   ├── e2e.options.logPrefix.js
│   │   │   │   │   ├── e2e.options.logSnippet.js
│   │   │   │   │   ├── e2e.options.open.browsers.js
│   │   │   │   │   ├── e2e.options.open.js
│   │   │   │   │   ├── e2e.options.port.js
│   │   │   │   │   ├── e2e.options.script.async.js
│   │   │   │   │   ├── e2e.options.scriptpath.js
│   │   │   │   │   ├── e2e.options.serveStatic.js
│   │   │   │   │   ├── e2e.options.single.js
│   │   │   │   │   ├── e2e.options.snippet.js
│   │   │   │   │   ├── e2e.options.sockets.js
│   │   │   │   │   ├── e2e.options.startPath.js
│   │   │   │   │   ├── e2e.snippet.js
│   │   │   │   │   ├── files/
│   │   │   │   │   │   ├── e2e.file.changed.js
│   │   │   │   │   │   ├── e2e.file.options.js
│   │   │   │   │   │   └── e2e.file.watching.js
│   │   │   │   │   ├── middleware/
│   │   │   │   │   │   ├── middleware.option.js
│   │   │   │   │   │   ├── middleware.proxy.option.js
│   │   │   │   │   │   └── middleware.server.option.js
│   │   │   │   │   ├── proxy/
│   │   │   │   │   │   ├── e2e.proxy.cookies.js
│   │   │   │   │   │   ├── e2e.proxy.error.js
│   │   │   │   │   │   ├── e2e.proxy.external.js
│   │   │   │   │   │   ├── e2e.proxy.js
│   │   │   │   │   │   ├── e2e.proxy.proxy.options.js
│   │   │   │   │   │   ├── e2e.proxy.req.headers.js
│   │   │   │   │   │   ├── e2e.proxy.req.headers.obj.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.add.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.remove.js
│   │   │   │   │   │   ├── e2e.proxy.rewrite.rules.replace.js
│   │   │   │   │   │   ├── e2e.proxy.secure.js
│   │   │   │   │   │   ├── e2e.proxy.snippet.js
│   │   │   │   │   │   └── e2e.proxy.ws.js
│   │   │   │   │   └── server/
│   │   │   │   │       ├── e2e.server.404.js
│   │   │   │   │       ├── e2e.server.dirs.js
│   │   │   │   │       ├── e2e.server.httpModule.js
│   │   │   │   │       ├── e2e.server.js
│   │   │   │   │       ├── e2e.server.middleware.js
│   │   │   │   │       ├── e2e.server.newapi.js
│   │   │   │   │       ├── e2e.server.newapi2.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.add.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.remove.js
│   │   │   │   │       ├── e2e.server.rewrite.rules.replace.js
│   │   │   │   │       ├── e2e.server.routes.js
│   │   │   │   │       ├── e2e.server.secure.custom.js
│   │   │   │   │       ├── e2e.server.secure.js
│   │   │   │   │       ├── e2e.server.secure.pfx.js
│   │   │   │   │       ├── e2e.server.serveStatic.extensions.js
│   │   │   │   │       ├── e2e.server.serveStatic.js
│   │   │   │   │       └── e2e.server.tunnel.js
│   │   │   │   ├── files/
│   │   │   │   │   ├── files.event-handler.js
│   │   │   │   │   ├── files.watching.debounce.js
│   │   │   │   │   ├── files.watching.delay.js
│   │   │   │   │   └── files.watching.js
│   │   │   │   ├── hooks/
│   │   │   │   │   └── files.watch.hook.js
│   │   │   │   ├── http-protocol/
│   │   │   │   │   └── http.reload.js
│   │   │   │   ├── instances/
│   │   │   │   │   ├── multi.emitter.js
│   │   │   │   │   ├── multi.get.js
│   │   │   │   │   ├── multi.has.js
│   │   │   │   │   ├── multi.init.js
│   │   │   │   │   ├── multi.js
│   │   │   │   │   ├── multi.plugins.js
│   │   │   │   │   ├── multi.proxy.js
│   │   │   │   │   └── single.js
│   │   │   │   ├── logger/
│   │   │   │   │   ├── logger.baseDir.js
│   │   │   │   │   └── logger.files.changed.js
│   │   │   │   ├── options/
│   │   │   │   │   └── options.set.js
│   │   │   │   ├── plugins/
│   │   │   │   │   ├── bs.options.js
│   │   │   │   │   ├── connector.js
│   │   │   │   │   ├── files.js
│   │   │   │   │   ├── hooks.js
│   │   │   │   │   ├── logger.js
│   │   │   │   │   ├── options.js
│   │   │   │   │   ├── ui.error.js
│   │   │   │   │   ├── ui.js
│   │   │   │   │   ├── user.plugins.add.middleware.js
│   │   │   │   │   ├── user.plugins.cleanup.js
│   │   │   │   │   ├── user.plugins.error.js
│   │   │   │   │   ├── user.plugins.inline.enabled.js
│   │   │   │   │   ├── user.plugins.inline.error.js
│   │   │   │   │   ├── user.plugins.inline.js
│   │   │   │   │   ├── user.plugins.inline.obj.js
│   │   │   │   │   ├── user.plugins.inline.obj.reference.js
│   │   │   │   │   ├── user.plugins.inline.options.js
│   │   │   │   │   ├── user.plugins.js
│   │   │   │   │   ├── user.plugins.proxy.js
│   │   │   │   │   └── user.plugins.serve.files.js
│   │   │   │   ├── resp-mod/
│   │   │   │   │   └── rewrite-links.js
│   │   │   │   ├── server/
│   │   │   │   │   └── server.snippet.js
│   │   │   │   └── utils/
│   │   │   │       ├── utils.connect.js
│   │   │   │       ├── utils.default.callback.js
│   │   │   │       ├── utils.fail.js
│   │   │   │       ├── utils.getHostIp.js
│   │   │   │       ├── utils.getUrl.js
│   │   │   │       ├── utils.getUrls.js
│   │   │   │       ├── utils.js
│   │   │   │       ├── utils.setUrlOptions.js
│   │   │   │       └── utils.verifyOptions.js
│   │   │   └── utils.js
│   │   └── tsconfig.json
│   ├── browser-sync-client/
│   │   ├── .gitignore
│   │   ├── .travis.yml
│   │   ├── LICENSE-MIT
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── lib/
│   │   │   ├── browser.utils.ts
│   │   │   ├── dom-effects/
│   │   │   │   ├── link-replace.dom-effect.ts
│   │   │   │   ├── prop-set.dom-effect.ts
│   │   │   │   ├── set-scroll.dom-effect.ts
│   │   │   │   ├── set-window-name.dom-effect.ts
│   │   │   │   └── style-set.dom-effect.ts
│   │   │   ├── dom-effects.ts
│   │   │   ├── effects/
│   │   │   │   ├── browser-reload.effect.ts
│   │   │   │   ├── browser-set-location.effect.ts
│   │   │   │   ├── file-reload.effect.ts
│   │   │   │   ├── set-element-toggle-value.effect.ts
│   │   │   │   ├── set-element-value.effect.ts
│   │   │   │   ├── set-options.effect.ts
│   │   │   │   ├── set-scroll.ts
│   │   │   │   └── simulate-click.effect.ts
│   │   │   ├── effects.ts
│   │   │   ├── index.ts
│   │   │   ├── listeners/
│   │   │   │   ├── clicks.listener.ts
│   │   │   │   ├── form-inputs.listener.ts
│   │   │   │   ├── form-toggles.listener.ts
│   │   │   │   └── scroll.listener.ts
│   │   │   ├── listeners.ts
│   │   │   ├── log.ts
│   │   │   ├── messages/
│   │   │   │   ├── BrowserLocation.ts
│   │   │   │   ├── BrowserNotify.ts
│   │   │   │   ├── BrowserReload.ts
│   │   │   │   ├── ClickEvent.ts
│   │   │   │   ├── Connection.ts
│   │   │   │   ├── Disconnect.ts
│   │   │   │   ├── FileReload.ts
│   │   │   │   ├── FormToggleEvent.ts
│   │   │   │   ├── KeyupEvent.ts
│   │   │   │   ├── OptionsSet.ts
│   │   │   │   └── ScrollEvent.ts
│   │   │   ├── notify.ts
│   │   │   ├── scroll-restore.ts
│   │   │   ├── socket-messages.ts
│   │   │   ├── socket.ts
│   │   │   ├── types/
│   │   │   │   ├── socket.ts
│   │   │   │   └── types.d.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.ts
│   │   │   └── vendor/
│   │   │       ├── Reloader.ts
│   │   │       ├── Timer.ts
│   │   │       └── logger.ts
│   │   ├── package.json
│   │   ├── test/
│   │   │   ├── .jshintrc
│   │   │   ├── client-new/
│   │   │   │   ├── bs.options.js
│   │   │   │   ├── code-sync.js
│   │   │   │   ├── emitter.js
│   │   │   │   ├── ghostmode.click.js
│   │   │   │   ├── ghostmode.forms.inputs.js
│   │   │   │   ├── ghostmode.forms.js
│   │   │   │   ├── ghostmode.forms.submit.js
│   │   │   │   ├── ghostmode.forms.toggles.js
│   │   │   │   ├── ghostmode.js
│   │   │   │   ├── ghostmode.location.js
│   │   │   │   ├── ghostmode.scroll.js
│   │   │   │   ├── index.js
│   │   │   │   ├── libs/
│   │   │   │   │   └── assert.js
│   │   │   │   ├── notify.js
│   │   │   │   ├── socket.js
│   │   │   │   ├── stubs/
│   │   │   │   │   └── bs.js
│   │   │   │   └── utils.js
│   │   │   ├── fixtures/
│   │   │   │   ├── css/
│   │   │   │   │   └── style.css
│   │   │   │   ├── forms.html
│   │   │   │   ├── index-large.html
│   │   │   │   ├── index-urls.html
│   │   │   │   ├── index.html
│   │   │   │   ├── inputs.html
│   │   │   │   ├── less.html
│   │   │   │   ├── links.html
│   │   │   │   ├── proxy-headers.html
│   │   │   │   ├── proxy-ip.html
│   │   │   │   ├── proxy-vhost.html
│   │   │   │   ├── sass.html
│   │   │   │   └── scrolling.html
│   │   │   ├── karma.conf.ci.js
│   │   │   ├── karma.conf.js
│   │   │   ├── middleware/
│   │   │   │   ├── file.js
│   │   │   │   └── middleware.js
│   │   │   └── test.conf.js
│   │   ├── tsconfig.json
│   │   └── webpack.config.js
│   └── browser-sync-ui/
│       ├── .editorconfig
│       ├── .gitignore
│       ├── .jshintrc
│       ├── LICENSE
│       ├── README.md
│       ├── crossbow.yaml
│       ├── example.stream.js
│       ├── index.js
│       ├── lib/
│       │   ├── UI.js
│       │   ├── async-tasks.js
│       │   ├── async.js
│       │   ├── client-elements.js
│       │   ├── client-js.js
│       │   ├── config.js
│       │   ├── directive-stripper.js
│       │   ├── hooks.js
│       │   ├── opts.js
│       │   ├── plugins/
│       │   │   ├── connections/
│       │   │   │   ├── connections.client.js
│       │   │   │   ├── connections.directive.html
│       │   │   │   ├── connections.html
│       │   │   │   ├── connections.plugin.js
│       │   │   │   └── lib/
│       │   │   │       └── connections.js
│       │   │   ├── help/
│       │   │   │   ├── help.client.js
│       │   │   │   ├── help.directive.html
│       │   │   │   ├── help.html
│       │   │   │   └── help.plugin.js
│       │   │   ├── history/
│       │   │   │   ├── history.client.js
│       │   │   │   ├── history.directive.html
│       │   │   │   ├── history.html
│       │   │   │   ├── history.js
│       │   │   │   └── history.plugin.js
│       │   │   ├── network-throttle/
│       │   │   │   ├── network-throttle.client.js
│       │   │   │   ├── network-throttle.directive.html
│       │   │   │   ├── network-throttle.html
│       │   │   │   ├── network-throttle.js
│       │   │   │   ├── network-throttle.plugin.js
│       │   │   │   ├── targets.js
│       │   │   │   └── throttle-server.js
│       │   │   ├── overview/
│       │   │   │   ├── overview.client.js
│       │   │   │   ├── overview.html
│       │   │   │   ├── overview.plugin.js
│       │   │   │   ├── snippet-info.html
│       │   │   │   └── url-info.html
│       │   │   ├── plugins/
│       │   │   │   ├── plugins.client.js
│       │   │   │   ├── plugins.html
│       │   │   │   └── plugins.plugin.js
│       │   │   ├── remote-debug/
│       │   │   │   ├── client-files.js
│       │   │   │   ├── compression.html
│       │   │   │   ├── compression.js
│       │   │   │   ├── css/
│       │   │   │   │   ├── pesticide-depth.css
│       │   │   │   │   └── pesticide.css
│       │   │   │   ├── latency/
│       │   │   │   │   ├── latency.client.js
│       │   │   │   │   ├── latency.html
│       │   │   │   │   └── latency.js
│       │   │   │   ├── no-cache.html
│       │   │   │   ├── no-cache.js
│       │   │   │   ├── overlay-grid/
│       │   │   │   │   ├── css/
│       │   │   │   │   │   ├── grid-overlay-horizontal.css
│       │   │   │   │   │   └── grid-overlay-vertical.css
│       │   │   │   │   ├── js/
│       │   │   │   │   │   └── grid-overlay.js
│       │   │   │   │   ├── overlay-grid.client.js
│       │   │   │   │   ├── overlay-grid.html
│       │   │   │   │   └── overlay-grid.js
│       │   │   │   ├── remote-debug.client.js
│       │   │   │   ├── remote-debug.html
│       │   │   │   └── remote-debug.plugin.js
│       │   │   └── sync-options/
│       │   │       ├── sync-options.client.js
│       │   │       ├── sync-options.html
│       │   │       └── sync-options.plugin.js
│       │   ├── resolve-plugins.js
│       │   ├── server.js
│       │   ├── transform.options.js
│       │   ├── transforms.js
│       │   ├── urls.js
│       │   └── utils.js
│       ├── package.json
│       ├── public/
│       │   ├── css/
│       │   │   ├── components.css
│       │   │   └── core.css
│       │   ├── img/
│       │   │   └── icons/
│       │   │       └── preview.html
│       │   ├── index.html
│       │   └── js/
│       │       └── app.js
│       ├── src/
│       │   ├── crossbow/
│       │   │   ├── _config.yml
│       │   │   ├── _includes/
│       │   │   │   ├── enable.disable.hbs
│       │   │   │   ├── form.input.checkbox.hbs
│       │   │   │   ├── form.input.text.hbs
│       │   │   │   ├── header.hbs
│       │   │   │   ├── icon.hbs
│       │   │   │   └── nav.hbs
│       │   │   ├── _layouts/
│       │   │   │   ├── components.hbs
│       │   │   │   ├── main.hbs
│       │   │   │   └── parent.hbs
│       │   │   ├── components/
│       │   │   │   ├── button-bars.hbs
│       │   │   │   ├── buttons.hbs
│       │   │   │   ├── footer.hbs
│       │   │   │   ├── forms.hbs
│       │   │   │   ├── header.hbs
│       │   │   │   ├── heading.hbs
│       │   │   │   ├── help-content.hbs
│       │   │   │   ├── lists.hbs
│       │   │   │   ├── panels.hbs
│       │   │   │   ├── switches.hbs
│       │   │   │   └── type.hbs
│       │   │   ├── components.hbs
│       │   │   ├── content/
│       │   │   │   └── help.content.hbs
│       │   │   ├── help.hbs
│       │   │   ├── history.hbs
│       │   │   ├── network-throttle.hbs
│       │   │   ├── plugins.hbs
│       │   │   ├── remote-debug.hbs
│       │   │   ├── server-info-snippet.hbs
│       │   │   ├── server-info.hbs
│       │   │   └── sync-options.hbs
│       │   ├── scripts/
│       │   │   ├── angular.js
│       │   │   ├── app.js
│       │   │   ├── directives/
│       │   │   │   ├── icon.js
│       │   │   │   ├── link-to.js
│       │   │   │   ├── new-tab.js
│       │   │   │   └── switch.js
│       │   │   ├── directives.js
│       │   │   ├── editor.js
│       │   │   ├── filters.js
│       │   │   ├── main/
│       │   │   │   └── controller.js
│       │   │   ├── module.js
│       │   │   ├── modules/
│       │   │   │   ├── bsClients.js
│       │   │   │   ├── bsDisconnect.js
│       │   │   │   ├── bsHistory.js
│       │   │   │   ├── bsNotify.js
│       │   │   │   ├── bsSocket.js
│       │   │   │   └── bsStore.js
│       │   │   ├── services/
│       │   │   │   ├── Options.js
│       │   │   │   └── Pages.js
│       │   │   └── utils.js
│       │   ├── scss/
│       │   │   ├── _vars.scss
│       │   │   ├── components.scss
│       │   │   ├── core.scss
│       │   │   ├── modules/
│       │   │   │   ├── _mixins.scss
│       │   │   │   └── _reset.scss
│       │   │   ├── theme/
│       │   │   │   ├── _animations.scss
│       │   │   │   ├── _base.scss
│       │   │   │   ├── _buttons.scss
│       │   │   │   ├── _cloak.scss
│       │   │   │   ├── _code.scss
│       │   │   │   ├── _custom-icons.scss
│       │   │   │   ├── _disconnect.scss
│       │   │   │   ├── _footer.scss
│       │   │   │   ├── _forms.scss
│       │   │   │   ├── _grid.scss
│       │   │   │   ├── _header.scss
│       │   │   │   ├── _headings.scss
│       │   │   │   ├── _helpers.scss
│       │   │   │   ├── _links.scss
│       │   │   │   ├── _lists.scss
│       │   │   │   ├── _main-content.scss
│       │   │   │   ├── _misc.scss
│       │   │   │   ├── _msgs.scss
│       │   │   │   ├── _notifications.scss
│       │   │   │   ├── _panel.scss
│       │   │   │   ├── _paragraphs.scss
│       │   │   │   ├── _section-nav.scss
│       │   │   │   ├── _sidebar.scss
│       │   │   │   ├── _spinner.scss
│       │   │   │   ├── _state.scss
│       │   │   │   ├── _svg.scss
│       │   │   │   ├── _switch.scss
│       │   │   │   └── _top-bar.scss
│       │   │   └── vendor/
│       │   │       ├── _fonts.scss
│       │   │       └── _normalize.scss
│       │   └── svg-template.tmpl
│       ├── static/
│       │   ├── components/
│       │   │   ├── button-bars.html
│       │   │   ├── buttons.html
│       │   │   ├── footer.html
│       │   │   ├── forms.html
│       │   │   ├── header.html
│       │   │   ├── heading.html
│       │   │   ├── help-content.html
│       │   │   ├── lists.html
│       │   │   ├── panels.html
│       │   │   ├── switches.html
│       │   │   └── type.html
│       │   └── content/
│       │       └── help.content.html
│       ├── tasks/
│       │   ├── crossbow.js
│       │   └── icons.js
│       ├── templates/
│       │   ├── config.item.tmpl
│       │   ├── config.tmpl
│       │   ├── directives/
│       │   │   └── bs-switch.html
│       │   ├── inline.template.tmpl
│       │   ├── plugin.item.tmpl
│       │   └── plugin.tmpl
│       ├── test/
│       │   ├── .jshintrc
│       │   ├── client/
│       │   │   └── e2e/
│       │   │       ├── bs-init.js
│       │   │       ├── config.js
│       │   │       ├── e2e.plugins.js
│       │   │       ├── e2e.server-info.js
│       │   │       ├── e2e.sync-options.js
│       │   │       ├── test-utils.js
│       │   │       └── tests/
│       │   │           ├── history.js
│       │   │           ├── history.newtabs.js
│       │   │           ├── home.js
│       │   │           ├── network-throttle.auto.js
│       │   │           ├── network-throttle.js
│       │   │           ├── network-throttle.manual.js
│       │   │           ├── network-throttle.remove.js
│       │   │           ├── plugins.inline.js
│       │   │           ├── plugins.js
│       │   │           └── remote-debug.js
│       │   ├── fixtures/
│       │   │   ├── content.html
│       │   │   ├── css/
│       │   │   │   ├── blog.css
│       │   │   │   └── bootstrap.css
│       │   │   ├── forms.html
│       │   │   ├── index.html
│       │   │   ├── plugin/
│       │   │   │   ├── index.plugin.js
│       │   │   │   ├── package.json
│       │   │   │   └── ui/
│       │   │   │       ├── client.js
│       │   │   │       ├── test.directive.html
│       │   │   │       └── test.html
│       │   │   ├── plugin-multi-templates/
│       │   │   │   ├── index.plugin.js
│       │   │   │   ├── package.json
│       │   │   │   └── ui/
│       │   │   │       ├── client.js
│       │   │   │       ├── client2.js
│       │   │   │       ├── test.directive.html
│       │   │   │       ├── test.html
│       │   │   │       └── test.list.html
│       │   │   ├── plugin-noui/
│       │   │   │   ├── index.plugin.js
│       │   │   │   └── package.json
│       │   │   └── scrolling.html
│       │   ├── opts.server.json
│       │   ├── protractor.sh
│       │   └── server/
│       │       ├── history/
│       │       │   └── history.js
│       │       ├── init.js
│       │       ├── plugins.js
│       │       ├── plugins.templates.js
│       │       └── remote-debug/
│       │           ├── client.files.js
│       │           ├── latency.js
│       │           ├── no-cache.js
│       │           ├── throttle.https.js
│       │           └── throttle.js
│       └── webpack.config.js
├── playwright.config.ts
└── tests/
    ├── examples/
    │   ├── basic/
    │   │   └── basic.spec.ts
    │   ├── html-inject/
    │   │   └── html-inject.spec.ts
    │   ├── snippet/
    │   │   └── snippet.spec.ts
    │   └── tailwind/
    │       └── tailwind.spec.ts
    └── utils.ts
Download .txt
SYMBOL INDEX (1288 symbols across 149 files)

FILE: changelog.js
  function getParts (line 54) | function getParts(item, index) {

FILE: examples/middleware.css.injection.js
  function less (line 50) | function less(src) {

FILE: examples/server.latency.js
  function fakeLatency (line 19) | function fakeLatency(req, res, next) {

FILE: packages/browser-sync-client/index.js
  function supportsGzip (line 17) | function supportsGzip(req) {
  function setHeaders (line 27) | function setHeaders(res, body) {
  function isConditionalGet (line 37) | function isConditionalGet(req) {
  function notModified (line 45) | function notModified(res) {
  function processItems (line 51) | function processItems(items) {
  function init (line 73) | function init(options, requestBody, type) {

FILE: packages/browser-sync-client/lib/browser.utils.ts
  function getWindow (line 7) | function getWindow() {
  function getDocument (line 14) | function getDocument() {
  function getBrowserScrollPosition (line 22) | function getBrowserScrollPosition(window, document): ICoords {
  function getDocumentScrollSpace (line 45) | function getDocumentScrollSpace(
  function saveScrollPosition (line 59) | function saveScrollPosition(window, document) {
  function restoreScrollPosition (line 67) | function restoreScrollPosition() {
  function getElementIndex (line 82) | function getElementIndex(tagName, elem) {
  function forceChange (line 90) | function forceChange(elem) {
  function getElementData (line 99) | function getElementData(elem) {
  function getSingleElement (line 112) | function getSingleElement(tagName, index) {
  function getBody (line 120) | function getBody() {
  function setScroll (line 127) | function setScroll(pos) {
  function reloadBrowser (line 134) | function reloadBrowser() {
  function forEach (line 143) | function forEach(coll, fn) {
  function isOldIe (line 153) | function isOldIe() {
  function getLocation (line 163) | function getLocation(url) {
  function isUndefined (line 178) | function isUndefined(val) {
  function getByPath (line 186) | function getByPath(obj, path) {
  function getScrollPosition (line 205) | function getScrollPosition(
  function getScrollPositionForElement (line 216) | function getScrollPositionForElement(
  function getScrollTopPercentage (line 233) | function getScrollTopPercentage(pos, document): number {
  function getScrollPercentage (line 239) | function getScrollPercentage(

FILE: packages/browser-sync-client/lib/dom-effects.ts
  type Events (line 8) | enum Events {

FILE: packages/browser-sync-client/lib/dom-effects/link-replace.dom-effect.ts
  type LinkReplacePayload (line 10) | type LinkReplacePayload = {
  function linkReplaceDomEffect (line 18) | function linkReplaceDomEffect(
  function linkReplace (line 37) | function linkReplace(

FILE: packages/browser-sync-client/lib/dom-effects/prop-set.dom-effect.ts
  type PropSetPayload (line 7) | interface PropSetPayload {
  function propSetDomEffect (line 14) | function propSetDomEffect(xs: Observable<PropSetPayload>) {
  function propSet (line 26) | function propSet(incoming: PropSetPayload): [Events.PropSet, any] {

FILE: packages/browser-sync-client/lib/dom-effects/set-scroll.dom-effect.ts
  type SetScrollPayload (line 8) | type SetScrollPayload = { x: number; y: number };
  function setScroll (line 10) | function setScroll(
  function setScrollDomEffect (line 17) | function setScrollDomEffect(

FILE: packages/browser-sync-client/lib/dom-effects/set-window-name.dom-effect.ts
  function setWindowNameDomEffect (line 8) | function setWindowNameDomEffect(xs: Observable<string>, inputs: Inputs) {
  function setWindowName (line 16) | function setWindowName(

FILE: packages/browser-sync-client/lib/dom-effects/style-set.dom-effect.ts
  type StyleSetPayload (line 7) | interface StyleSetPayload {
  function styleSetDomEffect (line 15) | function styleSetDomEffect(xs: Observable<StyleSetPayload>) {
  function styleSet (line 25) | function styleSet(incoming: StyleSetPayload): [Events.StyleSet, any] {

FILE: packages/browser-sync-client/lib/effects.ts
  type EffectNames (line 11) | enum EffectNames {

FILE: packages/browser-sync-client/lib/effects/browser-reload.effect.ts
  function browserReload (line 7) | function browserReload() {
  function preBrowserReload (line 11) | function preBrowserReload() {
  function browserReloadEffect (line 15) | function browserReloadEffect(xs: Observable<any>, inputs: Inputs) {

FILE: packages/browser-sync-client/lib/effects/browser-set-location.effect.ts
  function browserSetLocationEffect (line 9) | function browserSetLocationEffect(
  function browserSetLocation (line 31) | function browserSetLocation(input: IncomingPayload) {

FILE: packages/browser-sync-client/lib/effects/file-reload.effect.ts
  function fileReload (line 9) | function fileReload(event: FileReloadEventPayload) {
  function fileReloadEffect (line 18) | function fileReloadEffect(

FILE: packages/browser-sync-client/lib/effects/set-element-toggle-value.effect.ts
  function setElementToggleValueEffect (line 8) | function setElementToggleValueEffect(
  function setElementToggleValue (line 32) | function setElementToggleValue(event: FormToggleEvent.IncomingPayload) {

FILE: packages/browser-sync-client/lib/effects/set-element-value.effect.ts
  function setElementValueEffect (line 8) | function setElementValueEffect(
  function setElementValue (line 24) | function setElementValue(event: KeyupEvent.IncomingPayload) {

FILE: packages/browser-sync-client/lib/effects/set-options.effect.ts
  function setOptionsEffect (line 14) | function setOptionsEffect(
  function setOptions (line 25) | function setOptions(options: IBrowserSyncOptions) {

FILE: packages/browser-sync-client/lib/effects/set-scroll.ts
  type Tuple (line 13) | type Tuple = [IncomingPayload, Window, Document, boolean];
  function setScrollEffect (line 15) | function setScrollEffect(
  function scrollElement (line 137) | function scrollElement(element, scrollProportionally, event: IncomingPay...

FILE: packages/browser-sync-client/lib/effects/simulate-click.effect.ts
  function simulateClickEffect (line 10) | function simulateClickEffect(
  function simulateClick (line 42) | function simulateClick(event: IncomingPayload) {

FILE: packages/browser-sync-client/lib/index.ts
  type Inputs (line 25) | interface Inputs {
  function getStream (line 59) | function getStream(name: string, inputs) {

FILE: packages/browser-sync-client/lib/listeners.ts
  function initListeners (line 10) | function initListeners(

FILE: packages/browser-sync-client/lib/listeners/clicks.listener.ts
  function getClickStream (line 17) | function getClickStream(

FILE: packages/browser-sync-client/lib/listeners/form-inputs.listener.ts
  function getFormInputStream (line 17) | function getFormInputStream(

FILE: packages/browser-sync-client/lib/listeners/form-toggles.listener.ts
  function getFormTogglesStream (line 17) | function getFormTogglesStream(

FILE: packages/browser-sync-client/lib/listeners/scroll.listener.ts
  function getScrollStream (line 20) | function getScrollStream(

FILE: packages/browser-sync-client/lib/log.ts
  function initLogger (line 13) | function initLogger(options: IBrowserSyncOptions) {
  type LogNames (line 20) | enum LogNames {
  type Overlay (line 26) | enum Overlay {
  type ConsolePayload (line 30) | type ConsolePayload = [LogNames, any[]];
  function consoleInfo (line 32) | function consoleInfo(...args): [LogNames.Log, ConsolePayload] {
  function consoleDebug (line 36) | function consoleDebug(...args): [LogNames.Log, ConsolePayload] {
  type OverlayInfoPayload (line 40) | type OverlayInfoPayload = [string, number];
  function overlayInfo (line 42) | function overlayInfo(

FILE: packages/browser-sync-client/lib/messages/BrowserLocation.ts
  type IncomingPayload (line 9) | interface IncomingPayload {
  function incomingBrowserLocation (line 14) | function incomingBrowserLocation(

FILE: packages/browser-sync-client/lib/messages/BrowserNotify.ts
  type IncomingPayload (line 5) | interface IncomingPayload {
  function incomingBrowserNotify (line 11) | function incomingBrowserNotify(xs: Observable<IncomingPayload>) {

FILE: packages/browser-sync-client/lib/messages/BrowserReload.ts
  function incomingBrowserReload (line 15) | function incomingBrowserReload(xs: Observable<any>, inputs: Inputs) {
  function reloadBrowserSafe (line 23) | function reloadBrowserSafe() {

FILE: packages/browser-sync-client/lib/messages/ClickEvent.ts
  type ElementData (line 10) | interface ElementData {
  type IncomingPayload (line 15) | interface IncomingPayload extends ElementData {
  function outgoing (line 19) | function outgoing(
  function incomingHandler$ (line 25) | function incomingHandler$(

FILE: packages/browser-sync-client/lib/messages/Connection.ts
  function incomingConnection (line 10) | function incomingConnection(

FILE: packages/browser-sync-client/lib/messages/Disconnect.ts
  function incomingDisconnect (line 5) | function incomingDisconnect(xs: Observable<any>) {

FILE: packages/browser-sync-client/lib/messages/FileReload.ts
  function incomingFileReload (line 13) | function incomingFileReload(

FILE: packages/browser-sync-client/lib/messages/FormToggleEvent.ts
  type Payload (line 11) | interface Payload {
  type OutgoingPayload (line 19) | type OutgoingPayload = Payload;
  type IncomingPayload (line 21) | interface IncomingPayload extends OutgoingPayload {
  function outgoing (line 25) | function outgoing(
  function incomingInputsToggles (line 38) | function incomingInputsToggles(

FILE: packages/browser-sync-client/lib/messages/KeyupEvent.ts
  type Payload (line 11) | interface Payload {
  type OutgoingPayload (line 17) | type OutgoingPayload = Payload;
  type IncomingPayload (line 19) | interface IncomingPayload extends OutgoingPayload {
  function outgoing (line 23) | function outgoing(
  function incomingKeyupHandler (line 36) | function incomingKeyupHandler(

FILE: packages/browser-sync-client/lib/messages/OptionsSet.ts
  type Payload (line 6) | interface Payload {
  type IncomingPayload (line 12) | type IncomingPayload = Payload;
  function incomingOptionsSet (line 14) | function incomingOptionsSet(xs: Observable<IncomingPayload>) {

FILE: packages/browser-sync-client/lib/messages/ScrollEvent.ts
  type ICoords (line 10) | interface ICoords {
  type Data (line 15) | interface Data {
  type OutgoingPayload (line 20) | interface OutgoingPayload {
  type IncomingPayload (line 27) | interface IncomingPayload extends OutgoingPayload {
  function outgoing (line 32) | function outgoing(
  function incomingScrollHandler (line 44) | function incomingScrollHandler(

FILE: packages/browser-sync-client/lib/notify.ts
  function initNotify (line 24) | function initNotify(options) {

FILE: packages/browser-sync-client/lib/scroll-restore.ts
  constant PREFIX (line 14) | const PREFIX = "<<BS_START>>";
  constant SUFFIX (line 15) | const SUFFIX = "<<BS_START>>";
  function parseFromString (line 18) | function parseFromString(input: string): any {
  function initWindowName (line 29) | function initWindowName(window: Window) {

FILE: packages/browser-sync-client/lib/socket-messages.ts
  type IncomingSocketNames (line 18) | enum IncomingSocketNames {
  type OutgoingSocketEvents (line 32) | enum OutgoingSocketEvents {
  type SocketEvent (line 39) | type SocketEvent = [IncomingSocketNames, any];
  type OutgoingSocketEvent (line 40) | type OutgoingSocketEvent = [OutgoingSocketEvents, any];
  function emitWithPathname (line 62) | function emitWithPathname(name) {

FILE: packages/browser-sync-client/lib/socket.ts
  function initWindow (line 29) | function initWindow() {
  function initDocument (line 33) | function initDocument() {
  function initNavigator (line 37) | function initNavigator() {
  function initOptions (line 41) | function initOptions() {
  function initSocket (line 45) | function initSocket() {

FILE: packages/browser-sync-client/lib/types.ts
  type InitOptions (line 1) | interface InitOptions {
  type ISnippetOptions (line 61) | interface ISnippetOptions {
  type IRule (line 68) | interface IRule {
  type IMatch (line 72) | interface IMatch {}
  type IScriptPaths (line 74) | interface IScriptPaths {
  type IServer (line 79) | interface IServer {
  type IServeStaticOptions (line 84) | interface IServeStaticOptions {
  type IUrls (line 88) | interface IUrls {
  type IWatchOptions (line 95) | interface IWatchOptions {
  type IIgnoredItem (line 101) | interface IIgnoredItem {}
  type IGhostMode (line 103) | interface IGhostMode {
  type IForms (line 110) | interface IForms {
  type IMiddlewareItem (line 116) | interface IMiddlewareItem {
  type ISocket (line 121) | interface ISocket {
  type ISocketIoOptions (line 130) | interface ISocketIoOptions {
  type ISocketIoClientConfig (line 134) | interface ISocketIoClientConfig {
  type IClients (line 138) | interface IClients {
  type IUi (line 142) | interface IUi {
  type IFiles (line 146) | interface IFiles {
  type ICore (line 150) | interface ICore {

FILE: packages/browser-sync-client/lib/types/socket.ts
  type FileReloadEventPayload (line 3) | type FileReloadEventPayload = {
  type FileReloadEvent (line 12) | type FileReloadEvent = [IncomingSocketNames.FileReload, FileReloadEventP...

FILE: packages/browser-sync-client/lib/types/types.d.ts
  type Window (line 1) | interface Window {
  type IBrowserSyncOptions (line 6) | interface IBrowserSyncOptions {
  type ISnippetOptions (line 64) | interface ISnippetOptions {
  type IRule (line 70) | interface IRule {
  type IMatch (line 73) | interface IMatch {
  type IScriptPaths (line 75) | interface IScriptPaths {
  type IServer (line 79) | interface IServer {
  type IServeStaticOptions (line 83) | interface IServeStaticOptions {
  type IUrls (line 86) | interface IUrls {
  type IWatchOptions (line 90) | interface IWatchOptions {
  type IGhostMode (line 95) | interface IGhostMode {
  type IForms (line 101) | interface IForms {
  type IMiddlewareItem (line 106) | interface IMiddlewareItem {
  type ISocket (line 110) | interface ISocket {
  type ISocketIoOptions (line 118) | interface ISocketIoOptions {
  type ISocketIoClientConfig (line 121) | interface ISocketIoClientConfig {
  type IClients (line 124) | interface IClients {
  type IUi (line 127) | interface IUi {
  type IFiles (line 130) | interface IFiles {
  type ICore (line 133) | interface ICore {

FILE: packages/browser-sync-client/lib/utils.ts
  function each (line 8) | function each(incoming) {
  function getLocation (line 86) | function getLocation(url: string) {
  function updateSearch (line 102) | function updateSearch(search, key, suffix) {
  function isBlacklisted (line 137) | function isBlacklisted(incoming) {
  function createTimedBooleanSwitch (line 143) | function createTimedBooleanSwitch(source$, timeout = 1000) {
  function array (line 152) | function array(incoming) {
  function normalisePath (line 156) | function normalisePath(path: string): string {

FILE: packages/browser-sync-client/lib/vendor/Reloader.ts
  type HTMLLinkElement (line 26) | interface HTMLLinkElement {
  constant IMAGE_STYLES (line 31) | const IMAGE_STYLES = [
  type ReloadOptions (line 42) | interface ReloadOptions {
  function reload (line 51) | function reload(document: Document, navigator: Navigator) {

FILE: packages/browser-sync-client/lib/vendor/Timer.ts
  class Timer (line 6) | class Timer {
    method constructor (line 11) | constructor(public func) {
    method start (line 20) | public start(timeout) {
    method stop (line 26) | public stop() {
    method start (line 33) | public static start (timeout, func) {

FILE: packages/browser-sync-client/lib/vendor/logger.ts
  class Nanologger (line 33) | class Nanologger {
    method constructor (line 39) | constructor(public name: string, public opts) {
    method trace (line 54) | public trace() {
    method debug (line 60) | public debug() {
    method info (line 66) | public info() {
    method warn (line 72) | public warn() {
    method error (line 78) | public error() {
    method fatal (line 84) | public fatal() {
    method _print (line 90) | private _print(level) {
  function color (line 149) | function color(color) {
  function getTimeStamp (line 153) | function getTimeStamp() {
  function pad (line 161) | function pad(str) {

FILE: packages/browser-sync-client/test/client-new/libs/assert.js
  function f (line 32) | function f() {}
  function replacer (line 103) | function replacer(key, value) {
  function truncate (line 116) | function truncate(s, n) {
  function fail (line 148) | function fail(actual, expected, message, operator, stackStartFunction) {
  function ok (line 168) | function ok(value, message) {
  function _deepEqual (line 199) | function _deepEqual(actual, expected) {
  function isUndefinedOrNull (line 244) | function isUndefinedOrNull(value) {
  function isArguments (line 248) | function isArguments(object) {
  function objEquiv (line 252) | function objEquiv(a, b) {
  function expectedException (line 322) | function expectedException(actual, expected) {
  function _throws (line 338) | function _throws(shouldThrow, block, expected, message) {

FILE: packages/browser-sync-ui/index.js
  function getPath (line 38) | function getPath (filepath) {
  function fileContent (line 46) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/UI.js
  function taskRunner (line 176) | function taskRunner (ui) {
  function handleOut (line 203) | function handleOut (ui, out) {
  function tasksComplete (line 228) | function tasksComplete (ui) {

FILE: packages/browser-sync-ui/lib/client-elements.js
  constant CLIENT_FILES_OPT (line 3) | const CLIENT_FILES_OPT = "clientFiles";
  function enableElement (line 18) | function enableElement (clients, ui, bs) {
  function disableElement (line 55) | function disableElement (clients, ui) {
  function addElement (line 76) | function addElement (clients, item) {
  function removeElement (line 85) | function removeElement(clients, id) {

FILE: packages/browser-sync-ui/lib/client-js.js
  function addJs (line 71) | function addJs(data) {
  function addCss (line 79) | function addCss(data) {
  function addDomNode (line 90) | function addDomNode(data) {
  function removeElement (line 103) | function removeElement(element) {
  function getAbsoluteUrl (line 109) | function getAbsoluteUrl(path) {
  function getHost (line 116) | function getHost () {

FILE: packages/browser-sync-ui/lib/directive-stripper.js
  function directiveStripper (line 12) | function directiveStripper(config, item, markup, done) {
  function getReplacer (line 37) | function getReplacer (name, markup) {
  function directive (line 62) | function directive (name, content, item) {

FILE: packages/browser-sync-ui/lib/hooks.js
  function templateFile (line 10) | function templateFile (filepath) {
  function createInlineTemplates (line 165) | function createInlineTemplates (hooks) {
  function transformConfig (line 179) | function transformConfig (item) {
  function createAngularRoutes (line 188) | function createAngularRoutes(all, item) {
  function createConfigItem (line 202) | function createConfigItem (joined, item) {
  function pluginTemplate (line 214) | function pluginTemplate (combined, item) {
  function preAngular (line 223) | function preAngular (plugins, config, ui) {
  function angularWrap (line 253) | function angularWrap (templateName, markup) {
  function bindOnce (line 264) | function bindOnce (markup, config) {

FILE: packages/browser-sync-ui/lib/plugins/connections/connections.client.js
  function ConnectionsControllers (line 16) | function ConnectionsControllers(pagesConfig) {
  function connectionListDirective (line 41) | function connectionListDirective($scope, Clients, Socket) {

FILE: packages/browser-sync-ui/lib/plugins/connections/connections.plugin.js
  constant PLUGIN_NAME (line 3) | const PLUGIN_NAME = "Connections";
  function getPath (line 35) | function getPath (filepath) {
  function fileContent (line 43) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/connections/lib/connections.js
  function decorateClients (line 88) | function decorateClients(clients, clientsInfo) {
  function sendUpdated (line 104) | function sendUpdated(socket, connectedClients) {

FILE: packages/browser-sync-ui/lib/plugins/help/help.client.js
  function helpAboutController (line 17) | function helpAboutController(options, pagesConfig) {

FILE: packages/browser-sync-ui/lib/plugins/help/help.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Help / About";
  function getPath (line 39) | function getPath (filepath) {
  function fileContent (line 47) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/history/history.client.js
  function historyController (line 21) | function historyController($scope, options, History, pagesConfig) {
  function historyDirective (line 69) | function historyDirective($scope, History, Clients) {

FILE: packages/browser-sync-ui/lib/plugins/history/history.js
  function decorateUrls (line 94) | function decorateUrls (urls) {
  function addPath (line 113) | function addPath(immSet, urlObj, mode) {
  function removePath (line 128) | function removePath(immSet, urlPath) {

FILE: packages/browser-sync-ui/lib/plugins/history/history.plugin.js
  constant PLUGIN_NAME (line 3) | const PLUGIN_NAME = "History";
  function getPath (line 44) | function getPath (filepath) {
  function fileContent (line 52) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/network-throttle/network-throttle.client.js
  function NetworkThrottleController (line 21) | function NetworkThrottleController (options, pagesConfig, Socket, $scope) {
  function throttleDirectiveControlller (line 193) | function throttleDirectiveControlller ($scope) {

FILE: packages/browser-sync-ui/lib/plugins/network-throttle/network-throttle.js
  function getPortArg (line 23) | function getPortArg(input) {
  function getTargetUrl (line 36) | function getTargetUrl() {
  function saveThrottleInfo (line 52) | function saveThrottleInfo (opts) {
  function createThrottle (line 80) | function createThrottle (err, port) {
  function getUrls (line 146) | function getUrls (opts) {

FILE: packages/browser-sync-ui/lib/plugins/network-throttle/network-throttle.plugin.js
  constant PLUGIN_NAME (line 3) | const PLUGIN_NAME = "Network Throttle";
  function getPath (line 43) | function getPath (filepath) {
  function fileContent (line 51) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/network-throttle/throttle-server.js
  function throttle (line 8) | function throttle (opts, listenHost) {

FILE: packages/browser-sync-ui/lib/plugins/overview/overview.client.js
  function OverviewController (line 17) | function OverviewController (options, pagesConfig) {
  function urlInfoController (line 54) | function urlInfoController($scope, $rootScope, Clients) {

FILE: packages/browser-sync-ui/lib/plugins/overview/overview.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Overview";
  function getPath (line 41) | function getPath (filepath) {
  function fileContent (line 49) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/plugins/plugins.client.js
  function PluginsPageController (line 23) | function PluginsPageController(options, Socket, pagesConfig) {

FILE: packages/browser-sync-ui/lib/plugins/plugins/plugins.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Plugins";
  function getPath (line 64) | function getPath (filepath) {
  function fileContent (line 72) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/remote-debug/latency/latency.client.js
  function latencyDirectiveControlller (line 26) | function latencyDirectiveControlller($scope, Socket) {

FILE: packages/browser-sync-ui/lib/plugins/remote-debug/overlay-grid/overlay-grid.client.js
  function overlayGridDirectiveControlller (line 27) | function overlayGridDirectiveControlller($scope, Socket) {

FILE: packages/browser-sync-ui/lib/plugins/remote-debug/overlay-grid/overlay-grid.js
  function template (line 7) | function template (string, obj) {
  function getCss (line 17) | function getCss(opts) {

FILE: packages/browser-sync-ui/lib/plugins/remote-debug/remote-debug.client.js
  function RemoteDebugController (line 19) | function RemoteDebugController(options, Socket, pagesConfig) {
  function noCacheDirectiveControlller (line 92) | function noCacheDirectiveControlller ($scope, Socket) {
  function compressionDirectiveControlller (line 129) | function compressionDirectiveControlller ($scope, Socket) {

FILE: packages/browser-sync-ui/lib/plugins/remote-debug/remote-debug.plugin.js
  constant PLUGIN_NAME (line 6) | const PLUGIN_NAME  = "Remote Debug";
  function getPath (line 72) | function getPath (filepath) {
  function fileContent (line 80) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/plugins/sync-options/sync-options.client.js
  function SyncOptionsController (line 20) | function SyncOptionsController(Socket, options, pagesConfig) {
  function ucfirst (line 90) | function ucfirst (string) {

FILE: packages/browser-sync-ui/lib/plugins/sync-options/sync-options.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Sync Options";
  function getPath (line 60) | function getPath (filepath) {
  function fileContent (line 64) | function fileContent (filepath) {

FILE: packages/browser-sync-ui/lib/resolve-plugins.js
  function resolveIfPluginHas (line 92) | function resolveIfPluginHas(optPath, propName, plugin) {
  function resolvePluginFiles (line 109) | function resolvePluginFiles (collection, relPath) {

FILE: packages/browser-sync-ui/lib/server.js
  function startServer (line 16) | function startServer(ui) {
  function insertPageMarkupFromHooks (line 91) | function insertPageMarkupFromHooks(app, pages, markup) {
  function serveFile (line 120) | function serveFile(path, type, string) {
  function getSocketJs (line 154) | function getSocketJs (cp) {
  function md5 (line 173) | function md5(src, length) {
  function publicDir (line 184) | function publicDir (filepath) {
  function staticDir (line 192) | function staticDir (filepath) {
  function publicFile (line 200) | function publicFile(filepath) {
  function staticFile (line 208) | function staticFile(filepath) {
  function packageDir (line 216) | function packageDir (filepath) {

FILE: packages/browser-sync-ui/lib/utils.js
  function createUrl (line 9) | function createUrl(localUrl, urlPath) {
  function verifyUrl (line 17) | function verifyUrl(url, cb) {

FILE: packages/browser-sync-ui/public/js/app.js
  function f (line 1) | function f(e){if(Y(e))fe(e.objectMaxDepth)&&(s.objectMaxDepth=v(e.object...
  function v (line 1) | function v(e){return de(e)&&e>0}
  function w (line 1) | function w(e,t){t=t||Error;var n="https://errors.angularjs.org/1.8.2/",r...
  function Le (line 2) | function Le(e){if(e==null||Rt(e))return!1;if(oe(e)||V(e)||S&&e instanceo...
  function M (line 2) | function M(e,t,n){var r,i;if(e)if(ve(e))for(r in e)r!=="prototype"&&r!==...
  function We (line 2) | function We(e,t,n){for(var r=Object.keys(e).sort(),i=0;i<r.length;i++)t....
  function Ze (line 2) | function Ze(e){return function(t,n){e(n,t)}}
  function vt (line 2) | function vt(){return++qe}
  function Qe (line 2) | function Qe(e,t){t?e.$$hashKey=t:delete e.$$hashKey}
  function Ct (line 2) | function Ct(e,t,n){for(var r=e.$$hashKey,i=0,l=t.length;i<l;++i){var u=t...
  function Fe (line 2) | function Fe(e){return Ct(e,se.call(arguments,1),!1)}
  function Bt (line 2) | function Bt(e){return Ct(e,se.call(arguments,1),!0)}
  function Ye (line 2) | function Ye(e){return parseInt(e,10)}
  function It (line 2) | function It(e,t){return Fe(Object.create(e),t)}
  function we (line 2) | function we(){}
  function _t (line 2) | function _t(e){return e}
  function st (line 2) | function st(e){return function(){return e}}
  function zt (line 2) | function zt(e){return ve(e.toString)&&e.toString!==P}
  function he (line 2) | function he(e){return typeof e>"u"}
  function fe (line 2) | function fe(e){return typeof e<"u"}
  function Y (line 2) | function Y(e){return e!==null&&typeof e=="object"}
  function Ae (line 2) | function Ae(e){return e!==null&&typeof e=="object"&&!G(e)}
  function V (line 2) | function V(e){return typeof e=="string"}
  function de (line 2) | function de(e){return typeof e=="number"}
  function Ee (line 2) | function Ee(e){return P.call(e)==="[object Date]"}
  function oe (line 2) | function oe(e){return Array.isArray(e)||e instanceof Array}
  function xe (line 2) | function xe(e){var t=P.call(e);switch(t){case"[object Error]":return!0;c...
  function ve (line 2) | function ve(e){return typeof e=="function"}
  function Tt (line 2) | function Tt(e){return P.call(e)==="[object RegExp]"}
  function Rt (line 2) | function Rt(e){return e&&e.window===e}
  function Vt (line 2) | function Vt(e){return e&&e.$evalAsync&&e.$watch}
  function ai (line 2) | function ai(e){return P.call(e)==="[object File]"}
  function Rf (line 2) | function Rf(e){return P.call(e)==="[object FormData]"}
  function Mf (line 2) | function Mf(e){return P.call(e)==="[object Blob]"}
  function $n (line 2) | function $n(e){return typeof e=="boolean"}
  function ui (line 2) | function ui(e){return e&&ve(e.then)}
  function Lf (line 2) | function Lf(e){return e&&de(e.length)&&Ff.test(P.call(e))}
  function Df (line 2) | function Df(e){return P.call(e)==="[object ArrayBuffer]"}
  function ds (line 2) | function ds(e){return!!(e&&(e.nodeName||e.prop&&e.attr&&e.find))}
  function If (line 2) | function If(e){var t={},n=e.split(","),r;for(r=0;r<n.length;r++)t[n[r]]=...
  function en (line 2) | function en(e){return pe(e.nodeName||e[0]&&e[0].nodeName)}
  function ps (line 2) | function ps(e,t){return Array.prototype.indexOf.call(e,t)!==-1}
  function Dr (line 2) | function Dr(e,t){var n=e.indexOf(t);return n>=0&&e.splice(n,1),n}
  function Rn (line 2) | function Rn(e,t,n){var r=[],i=[];if(n=v(n)?n:NaN,t){if(Lf(t)||Df(t))thro...
  function vs (line 2) | function vs(e,t){return e===t||e!==e&&t!==t}
  function tn (line 2) | function tn(e,t){if(e===t)return!0;if(e===null||t===null)return!1;if(e!=...
  function n (line 2) | function n(){try{return new Function(""),!1}catch{return!0}}
  function Ir (line 2) | function Ir(e,t,n){return e.concat(se.call(t,n))}
  function Nr (line 2) | function Nr(e,t){return se.call(e,t||0)}
  function Kn (line 2) | function Kn(e,t){var n=arguments.length>2?Nr(arguments,2):[];return ve(t...
  function Fo (line 2) | function Fo(e,t){var n=t;return typeof e=="string"&&e.charAt(0)==="$"&&e...
  function qr (line 2) | function qr(e,t){if(!he(e))return de(t)||(t=t?2:null),JSON.stringify(e,F...
  function Lo (line 2) | function Lo(e){return V(e)?JSON.parse(e):e}
  function gs (line 2) | function gs(e,t){e=e.replace(Nf,"");var n=Date.parse("Jan 01, 1970 00:00...
  function Do (line 2) | function Do(e,t){return e=new Date(e.getTime()),e.setMinutes(e.getMinute...
  function $s (line 2) | function $s(e,t,n){n=n?-1:1;var r=e.getTimezoneOffset(),i=gs(t,r);return...
  function un (line 2) | function un(e){e=S(e).clone().empty();var t=S("<div></div>").append(e).h...
  function Io (line 2) | function Io(e){try{return decodeURIComponent(e)}catch{}}
  function ms (line 2) | function ms(e){var t={};return M((e||"").split("&"),function(n){var r,i,...
  function qf (line 2) | function qf(e){var t=[];return M(e,function(n,r){oe(n)?M(n,function(i){t...
  function ys (line 2) | function ys(e){return Gt(e,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=")...
  function Gt (line 2) | function Gt(e,t){return encodeURIComponent(e).replace(/%40/gi,"@").repla...
  function Uf (line 2) | function Uf(e,t){var n,r,i=Zn.length;for(r=0;r<i;++r)if(n=Zn[r]+t,V(n=e....
  function Bf (line 2) | function Bf(e){var t=e.currentScript;if(!t)return!0;if(!(t instanceof c....
  function jf (line 2) | function jf(e,t){var n,r,i={};if(M(Zn,function(l){var u=l+"app";!n&&e.ha...
  function No (line 2) | function No(e,t,n){Y(n)||(n={});var r={strictDi:!1};n=Fe(r,n);var i=func...
  function Hf (line 2) | function Hf(){c.name="NG_ENABLE_DEBUG_INFO!"+c.name,c.location.reload()}
  function Wf (line 2) | function Wf(e){var t=ue.element(e).injector();if(!t)throw X("test","no i...
  function qo (line 2) | function qo(e,t){return t=t||"_",e.replace(zf,function(n,r){return(r?t:"...
  function Gf (line 2) | function Gf(){var e;if(!Uo){var t=ci();Q=he(t)?c.jQuery:t?c[t]:void 0,Q&...
  function Xf (line 2) | function Xf(){ct.legacyXHTMLReplacement=!0}
  function Ur (line 2) | function Ur(e,t,n){if(!e)throw X("areq","Argument '{0}' is {1}",t||"?",n...
  function fi (line 2) | function fi(e,t,n){return n&&oe(e)&&(e=e[e.length-1]),Ur(ve(e),t,"not a ...
  function Qn (line 2) | function Qn(e,t){if(e==="hasOwnProperty")throw X("badname","hasOwnProper...
  function Yf (line 2) | function Yf(e,t,n){if(!t)return e;for(var r=t.split("."),i,l=e,u=r.lengt...
  function li (line 2) | function li(e){for(var t=e[0],n=e[e.length-1],r,i=1;t!==n&&(t=t.nextSibl...
  function nt (line 2) | function nt(){return Object.create(null)}
  function bs (line 2) | function bs(e){if(e==null)return"";switch(typeof e){case"string":break;c...
  function Kf (line 2) | function Kf(e){var t=w("$injector"),n=w("ng");function r(l,u,a){return l...
  function nn (line 2) | function nn(e,t){if(oe(e)){t=t||[];for(var n=0,r=e.length;n<r;n++)t[n]=e...
  function Zf (line 2) | function Zf(e,t){var n=[];return v(t)&&(e=ue.copy(e,null,t)),JSON.string...
  function Bo (line 2) | function Bo(e,t){return typeof e=="function"?e.toString().replace(/ \{[\...
  function el (line 2) | function el(e){Fe(e,{errorHandlingConfig:f,bootstrap:No,copy:Rn,extend:F...
  function nl (line 2) | function nl(){return++tl}
  function sl (line 2) | function sl(e){return di(e.replace(il,"ms-"))}
  function Vo (line 2) | function Vo(e,t){return t.toUpperCase()}
  function di (line 2) | function di(e){return e.replace(rl,Vo)}
  function As (line 2) | function As(e){return!al.test(e)}
  function Ss (line 2) | function Ss(e){var t=e.nodeType;return t===mn||!t||t===Cs}
  function fl (line 2) | function fl(e){for(var t in er[e.ng339])return!0;return!1}
  function zo (line 2) | function zo(e,t){var n,r,i,l,u=t.createDocumentFragment(),a=[],o;if(As(e...
  function ll (line 2) | function ll(e,t){t=t||c.document;var n;return(n=ol.exec(e))?[t.createEle...
  function hl (line 2) | function hl(e,t){var n=e.parentNode;n&&n.replaceChild(t,e),t.appendChild...
  function ct (line 2) | function ct(e){if(e instanceof ct)return e;var t;if(V(e)&&(e=tt(e),t=!0)...
  function _s (line 2) | function _s(e){return e.cloneNode(!0)}
  function pi (line 2) | function pi(e,t){!t&&Ss(e)&&S.cleanData([e]),e.querySelectorAll&&S.clean...
  function Go (line 2) | function Go(e){var t;for(t in e)return!1;return!0}
  function Xo (line 2) | function Xo(e){var t=e.ng339,n=t&&er[t],r=n&&n.events,i=n&&n.data;(!i||G...
  function Yo (line 2) | function Yo(e,t,n,r){if(fe(r))throw ws("offargs","jqLite#off() does not ...
  function Ts (line 2) | function Ts(e,t){var n=e.ng339,r=n&&er[n];r&&(t?delete r.data[t]:r.data=...
  function vi (line 2) | function vi(e,t){var n=e.ng339,r=n&&er[n];return t&&!r&&(e.ng339=n=nl(),...
  function ks (line 2) | function ks(e,t,n){if(Ss(e)){var r,i=fe(n),l=!i&&t&&!Y(t),u=!t,a=vi(e,!l...
  function gi (line 2) | function gi(e,t){return e.getAttribute?(" "+(e.getAttribute("class")||""...
  function $i (line 2) | function $i(e,t){if(t&&e.setAttribute){var n=(" "+(e.getAttribute("class...
  function mi (line 2) | function mi(e,t){if(t&&e.setAttribute){var n=(" "+(e.getAttribute("class...
  function Os (line 2) | function Os(e,t){if(t)if(t.nodeType)e[e.length++]=t;else{var n=t.length;...
  function Jo (line 2) | function Jo(e,t){return yi(e,"$"+(t||"ngController")+"Controller")}
  function yi (line 2) | function yi(e,t,n){e.nodeType===Cs&&(e=e.documentElement);for(var r=oe(t...
  function Ko (line 2) | function Ko(e){for(pi(e,!0);e.firstChild;)e.removeChild(e.firstChild)}
  function bi (line 2) | function bi(e,t){t||pi(e);var n=e.parentNode;n&&n.removeChild(e)}
  function pl (line 2) | function pl(e,t){t=t||c,t.document.readyState==="complete"?t.setTimeout(...
  function Zo (line 2) | function Zo(e){function t(){c.document.removeEventListener("DOMContentLo...
  function ta (line 2) | function ta(e,t){var n=Ci[t.toLowerCase()];return n&&Qo[en(e)]&&n}
  function vl (line 2) | function vl(e){return ea[e]}
  function e (line 2) | function e(t,n){if(he(n)){var r=t.nodeType;return r===mn||r===wn?t.textC...
  function gl (line 2) | function gl(e,t){var n=function(r,i){r.isDefaultPrevented=function(){ret...
  function $l (line 2) | function $l(e,t,n){n.call(e,t)}
  function ml (line 2) | function ml(e,t,n){var r=t.relatedTarget;(!r||r!==e&&!dl.call(e,r))&&n.c...
  function yl (line 2) | function yl(){this.$get=function(){return Fe(ct,{hasClass:function(t,n){...
  function nr (line 2) | function nr(e,t){var n=e&&e.$$hashKey;if(n)return typeof n=="function"&&...
  function na (line 2) | function na(){this._keys=[],this._values=[],this._lastKey=NaN,this._last...
  function ra (line 2) | function ra(e){return Function.prototype.toString.call(e)}
  function ia (line 2) | function ia(e){var t=ra(e).replace(_l,""),n=t.match(El)||t.match(wl);ret...
  function Tl (line 2) | function Tl(e){var t=ia(e);return t?"function("+(t[1]||"").replace(/[\s\...
  function kl (line 2) | function kl(e,t,n){var r,i,l;if(typeof e=="function"){if(!(r=e.$inject))...
  function jr (line 2) | function jr(e,t){t=t===!0;var n={},r="Provider",i=[],l=new Ei,u={$provid...
  function Ol (line 4) | function Ol(){var e=!0;this.disableAutoScrolling=function(){e=!1},this.$...
  function Hr (line 4) | function Hr(e,t){return!e&&!t?"":e?t?(oe(e)&&(e=e.join(" ")),oe(t)&&(t=t...
  function Pl (line 4) | function Pl(e){for(var t=0;t<e.length;t++){var n=e[t];if(n.nodeType===xl...
  function Rl (line 4) | function Rl(e){V(e)&&(e=e.split(" "));var t=nt();return M(e,function(n){...
  function Ln (line 4) | function Ln(e){return Y(e)?e:{}}
  function i (line 4) | function i(a,o,h){var d=!1;return o&&(o=V(o)?o.split(" "):oe(o)?o:[],M(o...
  function l (line 4) | function l(){M(t,function(a){var o=e.get(a);if(o){var h=Rl(a.attr("class...
  function u (line 4) | function u(a,o,h){var d=e.get(a)||{},p=i(d,o,!0),g=i(d,h,!1);(p||g)&&(e....
  function l (line 4) | function l(u,a,o){if(o){var h=Pl(o);h&&!h.parentNode&&!h.previousElement...
  function n (line 4) | function n(r){t.push(r),!(t.length>1)&&e(function(){for(var i=0;i<t.leng...
  function g (line 4) | function g(){if(p===h.length){d(!0);return}h[p](function(y){if(y===!1){d...
  function y (line 4) | function y(b){g=g&&b,++p===h.length&&d(g)}
  function o (line 4) | function o(h){this.setHost(h);var d=n(),p=function(g){i(g,0,!1)};this._d...
  function o (line 4) | function o(){return e(function(){h(),u||a.complete(),u=!0}),a}
  function h (line 4) | function h(){l.addClass&&(r.addClass(l.addClass),l.addClass=null),l.remo...
  function ql (line 4) | function ql(e){var t=e.indexOf("#");return t===-1?"":e.substr(t)}
  function Ul (line 4) | function Ul(e){return e.replace(/#$/,"")}
  function Bl (line 4) | function Bl(e,t,n,r,i){var l=this,u=e.location,a=e.history,o=e.setTimeou...
  function Vl (line 4) | function Vl(){this.$get=["$window","$log","$sniffer","$document","$$task...
  function jl (line 4) | function jl(){this.$get=function(){var e={};function t(n,r){if(n in e)th...
  function Hl (line 4) | function Hl(){this.$get=["$cacheFactory",function(e){return e("templates...
  function Wl (line 4) | function Wl(){}
  function aa (line 4) | function aa(e,t){var n={},r="Directive",i=/^\s*directive:\s*([\w-]+)\s+(...
  function wi (line 5) | function wi(e,t){this.previousValue=e,this.currentValue=t}
  function rn (line 5) | function rn(e){return e.replace(ua,"").replace(zl,function(t,n,r){return...
  function q$ (line 5) | function q$(e,t,n,r){}
  function U$ (line 5) | function U$(e,t,n,r,i){}
  function ca (line 5) | function ca(e,t){var n="",r=e.split(/\s+/),i=t.split(/\s+/);e:for(var l=...
  function fa (line 5) | function fa(e){e=S(e);var t=e.length;if(t<=1)return e;for(;t--;){var n=e...
  function Gl (line 5) | function Gl(e,t){if(t&&V(t))return t;if(V(e)){var n=ha.exec(e);if(n)retu...
  function Xl (line 5) | function Xl(){var e={};this.has=function(t){return e.hasOwnProperty(t)},...
  function Yl (line 5) | function Yl(){this.$get=["$window",function(e){return S(e.document)}]}
  function Jl (line 5) | function Jl(){this.$get=["$document","$rootScope",function(e,t){var n=e[...
  function Kl (line 5) | function Kl(){this.$get=["$log",function(e){return function(t,n){e.error...
  function Rs (line 5) | function Rs(e){return Y(e)?Ee(e)?e.toISOString():qr(e):e}
  function nh (line 5) | function nh(){this.$get=function(){return function(t){if(!t)return"";var...
  function rh (line 5) | function rh(){this.$get=function(){return function(t){if(!t)return"";var...
  function Ms (line 5) | function Ms(e,t){if(V(e)){var n=e.replace(th,"").trim();if(n){var r=t("C...
  function ih (line 5) | function ih(e){var t=e.match(Ql);return t&&eh[t[0]].test(e)}
  function pa (line 5) | function pa(e){var t=nt(),n;function r(i,l){i&&(t[i]=t[i]?t[i]+", "+l:l)...
  function va (line 6) | function va(e){var t;return function(n){if(t||(t=pa(e)),n){var r=t[pe(n)...
  function ga (line 6) | function ga(e,t,n,r){return ve(r)?r(e,t,n):(M(r,function(i){e=i(e,t,n)})...
  function Fs (line 6) | function Fs(e){return 200<=e&&e<300}
  function sh (line 6) | function sh(){var e=this.defaults={transformResponse:[Ms],transformReque...
  function oh (line 6) | function oh(){this.$get=function(){return function(){return new c.XMLHtt...
  function ah (line 6) | function ah(){this.$get=["$browser","$jsonpCallbacks","$document","$xhrF...
  function uh (line 6) | function uh(e,t,n,r,i){return function(u,a,o,h,d,p,g,y,b,D){if(a=a||e.ur...
  function ch (line 8) | function ch(){var e="{{",t="}}";this.startSymbol=function(n){return n?(e...
  function lh (line 8) | function lh(){this.$get=["$$intervalFactory","$window",function(e,t){var...
  function hh (line 8) | function hh(){this.$get=["$browser","$q","$$q","$rootScope",function(e,t...
  function n (line 8) | function n(r){var i=function(l){i.data=l,i.called=!0};return i.id=r,i}
  function gh (line 8) | function gh(e){for(var t=e.split("/"),n=t.length;n--;)t[n]=ys(t[n].repla...
  function $h (line 8) | function $h(e,t){for(var n=e.split("/"),r=n.length;r--;)n[r]=decodeURICo...
  function mh (line 8) | function mh(e,t,n){var r=qf(t),i=n?"#"+ys(n):"",l=gh(e);return l+(r?"?"+...
  function $a (line 8) | function $a(e,t){var n=Nt(e);t.$$protocol=n.protocol,t.$$host=n.hostname...
  function ma (line 8) | function ma(e,t,n){if(yh.test(e))throw Wr("badpath",'Invalid url "{0}".'...
  function Ls (line 8) | function Ls(e,t){return e.slice(0,t.length)===t}
  function yn (line 8) | function yn(e,t){if(Ls(t,e))return t.substr(e.length)}
  function In (line 8) | function In(e){var t=e.indexOf("#");return t===-1?e:e.substr(0,t)}
  function bh (line 8) | function bh(e){return e.substr(0,In(e).lastIndexOf("/")+1)}
  function Ch (line 8) | function Ch(e){return e.substring(0,e.indexOf("/",e.indexOf("//")+2))}
  function Ds (line 8) | function Ds(e,t,n){this.$$html5=!0,n=n||"",$a(e,this),this.$$parse=funct...
  function Is (line 8) | function Is(e,t,n){$a(e,this),this.$$parse=function(r){var i=yn(e,r)||yn...
  function ya (line 8) | function ya(e,t,n){this.$$html5=!0,Is.apply(this,arguments),this.$$parse...
  function Si (line 8) | function Si(e){return function(){return this[e]}}
  function ba (line 8) | function ba(e,t){return function(n){return he(n)?this[e]:(this[e]=t(n),t...
  function wh (line 8) | function wh(){var e="!",t={enabled:!1,requireBase:!0,rewriteLinks:!0};th...
  function Ah (line 8) | function Ah(){var e=!0,t=this;this.debugEnabled=function(n){return fe(n)...
  function Ca (line 10) | function Ca(e){return e+""}
  function Th (line 12) | function Th(e,t){return typeof e<"u"?e:t}
  function Ea (line 12) | function Ea(e,t){return typeof e>"u"?t:typeof t>"u"?e:e+t}
  function kh (line 12) | function kh(e,t){var n=e(t);return!n.$stateful}
  function Oh (line 12) | function Oh(e,t){switch(e.type){case te.MemberExpression:if(e.computed)r...
  function yt (line 12) | function yt(e,t,n){var r,i,l,u=e.isPure=Oh(e,n);switch(e.type){case te.P...
  function Sa (line 12) | function Sa(e){if(e.length===1){var t=e[0].expression,n=t.toWatch;return...
  function _a (line 12) | function _a(e){return e.type===te.Identifier||e.type===te.MemberExpression}
  function Ta (line 12) | function Ta(e){if(e.body.length===1&&_a(e.body[0].expression))return{typ...
  function xh (line 12) | function xh(e){return e.body.length===0||e.body.length===1&&(e.body[0].e...
  function Ph (line 12) | function Ph(e){return e.constant}
  function ka (line 12) | function ka(e){this.$filter=e}
  function Oa (line 13) | function Oa(e){this.$filter=e}
  function ki (line 13) | function ki(e,t,n){this.ast=new te(e,n),this.astCompiler=n.csp?new Oa(t)...
  function Ns (line 13) | function Ns(e){return ve(e.valueOf)?e.valueOf():Sh.call(e)}
  function Rh (line 13) | function Rh(){var e=nt(),t={true:!0,false:!1,null:null,undefined:void 0}...
  function Mh (line 13) | function Mh(){var e=!0;this.$get=["$rootScope","$exceptionHandler",funct...
  function Fh (line 13) | function Fh(){var e=!0;this.$get=["$browser","$exceptionHandler",functio...
  function xa (line 13) | function xa(e,t,n){var r=w("$q",TypeError),i=0,l=[];function u(){return ...
  function Pa (line 13) | function Pa(e){return!!e.pur}
  function qs (line 13) | function qs(e){e.pur=!0}
  function Ra (line 13) | function Ra(e){e.$$state&&qs(e.$$state)}
  function Lh (line 13) | function Lh(){this.$get=["$window","$timeout",function(e,t){var n=e.requ...
  function Dh (line 13) | function Dh(){var e=10,t=w("$rootScope"),n=null,r=null;this.digestTtl=fu...
  function Ih (line 14) | function Ih(){var e=/^\s*(https?|s?ftp|mailto|tel|file):/,t=/^\s*((https...
  function Us (line 14) | function Us(e){return e.replace(Nh,Vo)}
  function qh (line 14) | function qh(e){if(e==="self")return e;if(V(e)){if(e.indexOf("***")>-1)th...
  function Ma (line 14) | function Ma(e){var t=[];return fe(e)&&M(e,function(n){t.push(qh(n))}),t}
  function Uh (line 14) | function Uh(){this.SCE_CONTEXTS=dt;var e=["self"],t=[];this.trustedResou...
  function Bh (line 14) | function Bh(){var e=!0;this.enabled=function(t){return arguments.length&...
  function Vh (line 14) | function Vh(){this.$get=["$window","$document",function(e,t){var n={},r=...
  function jh (line 14) | function jh(){this.$get=st(function(e){return new Hh(e)})}
  function Hh (line 14) | function Hh(e){var t=this,n={},r=[],i=t.ALL_TASKS_TYPE="$$all$$",l=t.DEF...
  function zh (line 14) | function zh(){var e;this.httpOptions=function(t){return t?(e=t,this):e},...
  function Gh (line 14) | function Gh(){this.$get=["$rootScope","$browser","$location",function(e,...
  function Yh (line 14) | function Yh(){this.$get=["$rootScope","$browser","$q","$$q","$exceptionH...
  function Nt (line 14) | function Nt(e){if(!V(e))return e;var t=e;x&&(Et.setAttribute("href",t),t...
  function Kh (line 14) | function Kh(e){return Bs(e,Fa)}
  function Zh (line 14) | function Zh(e){return Bs(e,ed())}
  function Qh (line 14) | function Qh(e){var t=[Fa].concat(e.map(Nt));return function(r){var i=Nt(...
  function Bs (line 14) | function Bs(e,t){return e=Nt(e),t=Nt(t),e.protocol===t.protocol&&e.host=...
  function ed (line 14) | function ed(){return c.document.baseURI?c.document.baseURI:(ir||(ir=c.do...
  function td (line 14) | function td(){this.$get=st(c)}
  function La (line 14) | function La(e){var t=e[0]||{},n={},r="";function i(u){try{return u.cooki...
  function nd (line 14) | function nd(){this.$get=La}
  function Da (line 14) | function Da(e){var t="Filter";function n(r,i){if(Y(r)){var l={};return M...
  function rd (line 14) | function rd(){return function(e,t,n,r){if(!Le(e)){if(e==null)return e;th...
  function id (line 14) | function id(e,t,n,r){var i=Y(e)&&n in e,l;return t===!0?t=tn:ve(t)||(t=f...
  function Nn (line 14) | function Nn(e,t,n,r,i,l){var u=Vs(e),a=Vs(t);if(a==="string"&&t.charAt(0...
  function Vs (line 14) | function Vs(e){return e===null?"null":typeof e}
  function qa (line 14) | function qa(e){var t=e.NUMBER_FORMATS;return function(n,r,i){he(r)&&(r=t...
  function Ua (line 14) | function Ua(e){var t=e.NUMBER_FORMATS;return function(n,r){return n==nul...
  function sd (line 14) | function sd(e){var t=0,n,r,i,l,u;for((r=e.indexOf(Na))>-1&&(e=e.replace(...
  function od (line 14) | function od(e,t,n,r){var i=e.d,l=i.length-e.i;t=he(t)?Math.min(Math.max(...
  function Ba (line 14) | function Ba(e,t,n,r,i){if(!(V(e)||de(e))||isNaN(e))return"";var l=!isFin...
  function Oi (line 14) | function Oi(e,t,n,r){var i="";for((e<0||r&&e<=0)&&(r?e=-e+1:(e=-e,i="-")...
  function kt (line 14) | function kt(e,t,n,r,i){return n=n||0,function(l){var u=l["get"+e]();retu...
  function zr (line 14) | function zr(e,t,n){return function(r,i){var l=r["get"+e](),u=(n?"STANDAL...
  function ad (line 14) | function ad(e,t,n){var r=-1*n,i=r>=0?"+":"";return i+=Oi(Math[r>0?"floor...
  function Va (line 14) | function Va(e){var t=new Date(e,0,1).getDay();return new Date(e,0,(t<=4?...
  function ud (line 14) | function ud(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+...
  function ja (line 14) | function ja(e){return function(t){var n=Va(t.getFullYear()),r=ud(t),i=+r...
  function cd (line 14) | function cd(e,t){return e.getHours()<12?t.AMPMS[0]:t.AMPMS[1]}
  function Hs (line 14) | function Hs(e,t){return e.getFullYear()<=0?t.ERAS[0]:t.ERAS[1]}
  function fd (line 14) | function fd(e,t){return e.getFullYear()<=0?t.ERANAMES[0]:t.ERANAMES[1]}
  function Ha (line 14) | function Ha(e){var t=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?...
  function pd (line 14) | function pd(){return function(e,t){return he(t)&&(t=2),qr(e,t)}}
  function $d (line 14) | function $d(){return function(e,t,n){return Math.abs(Number(t))===1/0?t=...
  function Ws (line 14) | function Ws(e,t,n){return V(e)?e.slice(t,n):se.call(e,t,n)}
  function Wa (line 14) | function Wa(e){return function(u,a,o,h){if(u==null)return u;if(!Le(u))th...
  function sr (line 14) | function sr(e){return ve(e)&&(e={link:e}),e.restrict=e.restrict||"AC",st...
  function n (line 14) | function n(l,u,a){l.$watch(a[r],function(h){a.$set(t,!!h)})}
  function yd (line 14) | function yd(e,t){e.$name=t}
  function Pi (line 14) | function Pi(e,t,n,r,i){this.$$controls=[],this.$error={},this.$$success=...
  function i (line 14) | function i(l){return l===""?n('this[""]').assign:n(l).assign||we}
  function Ya (line 14) | function Ya(e){e.$$classCache={},e.$$classCache[fu]=!(e.$$classCache[Yr]...
  function Ja (line 14) | function Ja(e){var t=e.clazz,n=e.set,r=e.unset;t.prototype.$setValidity=...
  function Ka (line 14) | function Ka(e){if(e){for(var t in e)if(e.hasOwnProperty(t))return!1}retu...
  function Gs (line 14) | function Gs(e){e.$formatters.push(function(t){return e.$isEmpty(t)?t:t.t...
  function Td (line 14) | function Td(e,t,n,r,i,l){or(e,t,n,r,i,l),Gs(r)}
  function or (line 14) | function or(e,t,n,r,i,l){var u=pe(t[0].type);if(!i.android){var a=!1;t.o...
  function kd (line 14) | function kd(e,t){if(Ee(e))return e;if(V(e)){zs.lastIndex=0;var n=zs.exec...
  function Ri (line 14) | function Ri(e,t){return function(n,r){var i,l;if(Ee(n))return n;if(V(n))...
  function Xr (line 14) | function Xr(e,t,n,r){return function(l,u,a,o,h,d,p,g){Xs(l,u,a,o,e),or(l...
  function Xs (line 14) | function Xs(e,t,n,r,i){var l=t[0],u=r.$$hasNativeValidators=Y(l.validity...
  function iu (line 14) | function iu(e){e.$parsers.push(function(t){if(e.$isEmpty(t))return null;...
  function Xt (line 14) | function Xt(e){return fe(e)&&!de(e)&&(e=parseFloat(e)),je(e)?void 0:e}
  function Ys (line 14) | function Ys(e){return(e|0)===e}
  function Js (line 14) | function Js(e){var t=e.toString(),n=t.indexOf(".");if(n===-1){if(-1<e&&e...
  function su (line 14) | function su(e,t,n){var r=Number(e),i=!Ys(r),l=!Ys(t),u=!Ys(n);if(i||l||u...
  function Od (line 14) | function Od(e,t,n,r,i,l,u,a){Xs(e,t,n,r,"number"),iu(r),or(e,t,n,r,i,l);...
  function xd (line 14) | function xd(e,t,n,r,i,l){Xs(e,t,n,r,"range"),iu(r),or(e,t,n,r,i,l);var u...
  function Pd (line 14) | function Pd(e,t,n,r,i,l){or(e,t,n,r,i,l),Gs(r),r.$validators.url=functio...
  function Rd (line 14) | function Rd(e,t,n,r,i,l){or(e,t,n,r,i,l),Gs(r),r.$validators.email=funct...
  function Md (line 14) | function Md(e,t,n,r){var i=!n.ngTrim||tt(n.ngTrim)!=="false";he(n.name)&...
  function ou (line 14) | function ou(e,t,n,r,i){var l;if(fe(r)){if(l=e(r),!l.constant)throw Jr("c...
  function Fd (line 14) | function Fd(e,t,n,r,i,l,u,a){var o=ou(a,e,"ngTrueValue",n.ngTrueValue,!0...
  function e (line 14) | function e(t,n,r){var i=fe(r)?r:x===9?"":null;t.prop("value",i),n.$set("...
  function Ks (line 14) | function Ks(e,t){e="ngClass"+e;var n;return["$parse",function(u){return{...
  function cu (line 14) | function cu(e,t,n,r,i,l){return{restrict:"A",compile:function(u,a){var o...
  function Fi (line 14) | function Fi(e,t,n,r,i,l,u,a,o){this.$viewValue=Number.NaN,this.$modelVal...
  function l (line 14) | function l(){var d=i.$$parserName;if(he(i.$$parserValid))o(d,null);else ...
  function u (line 14) | function u(){var d=!0;return M(i.$validators,function(p,g){var y=Boolean...
  function a (line 14) | function a(){var d=[],p=!0;M(i.$asyncValidators,function(g,y){var b=g(e,...
  function o (line 14) | function o(d,p){r===i.$$currentValidationRunId&&i.$setValidity(d,p)}
  function h (line 14) | function h(d){r===i.$$currentValidationRunId&&n(d)}
  function u (line 14) | function u(){n.$modelValue!==i&&n.$$writeModelToScope()}
  function Qd (line 14) | function Qd(e){e.$$scope.$watch(function(n){var r=e.$$ngModelGet(n);retu...
  function h (line 14) | function h(){o.$setTouched()}
  function Qs (line 14) | function Qs(e){this.$$options=e}
  function e (line 14) | function e(t,n){this.$$attrs=t,this.$$scope=n}
  function pu (line 14) | function pu(e,t){M(t,function(n,r){fe(e[r])||(e[r]=n)})}
  function r (line 14) | function r(a,o,h){var d=a.match(sp);if(!d)throw ip("iexp","Expected expr...
  function u (line 14) | function u(a,o,h,d){for(var p=d[0],g=d[1],y=h.multiple,b=0,D=o.children(...
  function L (line 14) | function L(F){u.text(F||"")}
  function p (line 14) | function p(b,D){b.length&&y(b)?u.append(b):(g(),D.$destroy())}
  function g (line 14) | function g(){r(l,function(b){u.append(b)})}
  function y (line 14) | function y(b){for(var D=0,z=b.length;D<z;D++){var I=b[D];if(I.nodeType!=...
  function qn (line 14) | function qn(e,t){e.prop("selected",t),e.attr("selected",t)}
  function l (line 14) | function l(){i||(i=!0,t.$$postDigest(function(){i=!1,n.ngModelCtrl.$rend...
  function a (line 14) | function a(o){u||(u=!0,t.$$postDigest(function(){t.$$destroyed||(u=!1,n....
  function e (line 14) | function e(n,r,i,l){var u=l[0],a=l[1];if(!a){u.registerOption=we;return}...
  function t (line 14) | function t(n,r,i,l){var u=l[1];if(!!u){var a=l[0];u.$render=function(){a...
  function Eu (line 14) | function Eu(e,t,n){if(!!e){if(V(e)&&(e=new RegExp("^"+e+"$")),!e.test)th...
  function Di (line 14) | function Di(e){var t=Ye(e);return je(t)?-1:t}
  function n (line 14) | function n(i){i=i+"";var l=i.indexOf(".");return l==-1?0:i.length-l-1}
  function r (line 14) | function r(i,l){var u=l;u===void 0&&(u=Math.min(n(i),3));var a=Math.pow(...
  function f (line 14) | function f(P,G){if(w(P)){G=G||[];for(var X=0,ue=P.length;X<ue;X++)G[X]=P...
  function v (line 14) | function v(P,G){var X=[],ue=P.replace(/([().])/g,"\\$1").replace(/(\/)?:...
  function S (line 14) | function S(){w=s.isArray,q=s.isObject,ae=s.isDefined,$e=s.noop;function ...
  function Q (line 14) | function Q(P){x&&P.get("$route")}
  function se (line 14) | function se(){this.$get=function(){return{}}}
  function ge (line 14) | function ge(P,G,X){return{restrict:"ECA",terminal:!0,priority:400,transc...
  function j (line 14) | function j(P,G,X){return{restrict:"ECA",priority:-400,link:function(ue,O...
  function se (line 14) | function se(){var j=!1,P=!1;this.$get=["$$sanitizeUri",function(V){retur...
  function ge (line 14) | function ge(j){var P=[],G=Q(P,Pe);return G.chars(j),P.join("")}
  function je (line 14) | function je(we){!we||Fe.push(ge(we))}
  function It (line 14) | function It(we,_t){var st,zt=vt(we);Fe.push("<a ");for(st in zt)Fe.push(...
  function v (line 14) | function v(q){return s.$$lowercase(q.nodeName||q[0]&&q[0].nodeName)}
  function $e (line 14) | function $e(Pe){var x=Pe.originalEvent||Pe,S=x.touches&&x.touches.length...
  function pe (line 14) | function pe(Pe,x){var S=[];return s.forEach(Pe,function(Q){var se=ae[Q][...
  function w (line 14) | function w(q,ae,$e){f.directive(q,["$parse","$swipe",function(pe,Pe){var...
  function Up (line 22) | function Up(c,s,f){let v="Browsersync",w="Disconnected";c._disconnected=...
  function Vp (line 24) | function Vp(c,s){var f="info",v="Browsersync:",w="Welcome to Browsersync...
  function Hp (line 24) | function Hp(c){var s=[],f=[];return c.on("ui:history:update",function(v)...
  function zp (line 24) | function zp(c){var s={reloadAll:function(){c.clientEvent("browser:reload...
  function Dt (line 24) | function Dt(c){if(c)return av(c)}
  function av (line 24) | function av(c){for(var s in Dt.prototype)c[s]=Dt.prototype[s];return c}
  function f (line 24) | function f(){this.off(c,f),s.apply(this,arguments)}
  function uv (line 24) | function uv(c,...s){return s.reduce((f,v)=>(c.hasOwnProperty(v)&&(f[v]=c...
  function lv (line 24) | function lv(c,s){s.useNativeTimers?(c.setTimeoutFn=cv.bind(Hi.globalThis...
  function dv (line 24) | function dv(c){return typeof c=="string"?pv(c):Math.ceil((c.byteLength||...
  function pv (line 24) | function pv(c){let s=0,f=0;for(let v=0,w=c.length;v<w;v++)s=c.charCodeAt...
  function $v (line 24) | function $v(c){if(c=String(c),!(c.length>100)){var s=/^(-?(?:\d+)?\.?\d+...
  function mv (line 24) | function mv(c){var s=Math.abs(c);return s>=zn?Math.round(c/zn)+"d":s>=mr...
  function yv (line 24) | function yv(c){var s=Math.abs(c);return s>=zn?Wi(c,s,zn,"day"):s>=mr?Wi(...
  function Wi (line 24) | function Wi(c,s,f,v){var w=s>=f*1.5;return Math.round(c/f)+" "+v+(w?"s":...
  function bv (line 24) | function bv(c){f.debug=f,f.default=f,f.coerce=pe,f.disable=q,f.enable=w,...
  function Cv (line 24) | function Cv(){return typeof window<"u"&&window.process&&(window.process....
  function Ev (line 24) | function Ev(c){if(c[0]=(this.useColors?"%c":"")+this.namespace+(this.use...
  function wv (line 24) | function wv(c){try{c?jt.storage.setItem("debug",c):jt.storage.removeItem...
  function Av (line 24) | function Av(){let c;try{c=jt.storage.getItem("debug")}catch{}return!c&&t...
  function Sv (line 24) | function Sv(){try{return localStorage}catch{}}
  method constructor (line 24) | constructor(s,f,v){super(s);this.description=f,this.context=v,this.type=...
  method constructor (line 24) | constructor(s){super();this.writable=!1,(0,xv.installTimerFunctions)(thi...
  method onError (line 24) | onError(s,f,v){return super.emitReserved("error",new dc(s,f,v)),this}
  method open (line 24) | open(){return(this.readyState==="closed"||this.readyState==="")&&(this.r...
  method close (line 24) | close(){return(this.readyState==="opening"||this.readyState==="open")&&(...
  method send (line 24) | send(s){this.readyState==="open"?this.write(s):Rv("transport is not open...
  method onOpen (line 24) | onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("ope...
  method onData (line 24) | onData(s){let f=(0,kv.decodePacket)(s,this.socket.binaryType);this.onPac...
  method onPacket (line 24) | onPacket(s){super.emitReserved("packet",s)}
  method onClose (line 24) | onClose(s){this.readyState="closed",super.emitReserved("close",s)}
  function $o (line 24) | function $o(c){let s="";do s=$c[c%Xi]+s,c=Math.floor(c/Xi);while(c>0);re...
  function Mv (line 24) | function Mv(c){let s=0;for(On=0;On<c.length;On++)s=s*Xi+mc[c.charAt(On)]...
  function Fv (line 24) | function Fv(){let c=$o(+new Date);return c!==gc?(vc=0,gc=c):c+"."+$o(vc++)}
  function Lv (line 24) | function Lv(c){let s="";for(let f in c)c.hasOwnProperty(f)&&(s.length&&(...
  function Dv (line 24) | function Dv(c){let s={},f=c.split("&");for(let v=0,w=f.length;v<w;v++){l...
  function qv (line 24) | function qv(c){let s=c.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!s||Iv...
  function Gv (line 24) | function Gv(){}
  method constructor (line 24) | constructor(s){super(s);if(this.polling=!1,typeof location<"u"){let v=lo...
  method name (line 24) | get name(){return"polling"}
  method doOpen (line 24) | doOpen(){this.poll()}
  method pause (line 24) | pause(s){this.readyState="pausing";let f=()=>{qt("paused"),this.readySta...
  method poll (line 24) | poll(){qt("polling"),this.polling=!0,this.doPoll(),this.emitReserved("po...
  method onData (line 24) | onData(s){qt("polling got data %s",s);let f=v=>{if(this.readyState==="op...
  method doClose (line 24) | doClose(){let s=()=>{qt("writing close packet"),this.write([{type:"close...
  method write (line 24) | write(s){this.writable=!1,(0,Ec.encodePayload)(s,f=>{this.doWrite(f,()=>...
  method uri (line 24) | uri(){let s=this.query||{},f=this.opts.secure?"https":"http",v="";this.o...
  method request (line 24) | request(s={}){return Object.assign(s,{xd:this.xd,xs:this.xs},this.opts),...
  method doWrite (line 24) | doWrite(s,f){let v=this.request({method:"POST",data:s});v.on("success",f...
  method doPoll (line 24) | doPoll(){qt("xhr poll");let s=this.request();s.on("data",this.onData.bin...
  method constructor (line 24) | constructor(s,f){super();(0,wc.installTimerFunctions)(this,f),this.opts=...
  method create (line 24) | create(){let s=(0,wc.pick)(this.opts,"agent","pfx","key","passphrase","c...
  method onError (line 24) | onError(s){this.emitReserved("error",s,this.xhr),this.cleanup(!0)}
  method cleanup (line 24) | cleanup(s){if(!(typeof this.xhr>"u"||this.xhr===null)){if(this.xhr.onrea...
  method onLoad (line 24) | onLoad(){let s=this.xhr.responseText;s!==null&&(this.emitReserved("data"...
  method abort (line 24) | abort(){this.cleanup()}
  function Ac (line 24) | function Ac(){for(let c in Kt.requests)Kt.requests.hasOwnProperty(c)&&Kt...
  method constructor (line 24) | constructor(s){super(s);this.supportsBinary=!s.forceBase64}
  method name (line 24) | get name(){return"websocket"}
  method doOpen (line 24) | doOpen(){if(!this.check())return;let s=this.uri(),f=this.opts.protocols,...
  method addEventListeners (line 24) | addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._so...
  method write (line 24) | write(s){this.writable=!1;for(let f=0;f<s.length;f++){let v=s[f],w=f===s...
  method doClose (line 24) | doClose(){typeof this.ws<"u"&&(this.ws.close(),this.ws=null)}
  method uri (line 24) | uri(){let s=this.query||{},f=this.opts.secure?"wss":"ws",v="";this.opts....
  method check (line 24) | check(){return!!Cn.WebSocket}
  function ag (line 24) | function ag(c){let s=c,f=c.indexOf("["),v=c.indexOf("]");f!=-1&&v!=-1&&(...
  function ug (line 24) | function ug(c,s){let f=/\/{2,9}/g,v=s.replace(f,"/").split("/");return(s...
  function cg (line 24) | function cg(c,s){let f={};return s.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,f...
  method constructor (line 24) | constructor(s,f={}){super();s&&typeof s=="object"&&(f=s,s=null),s?(s=(0,...
  method createTransport (line 24) | createTransport(s){ut('creating transport "%s"',s);let f=Object.assign({...
  method open (line 24) | open(){let s;if(this.opts.rememberUpgrade&&En.priorWebsocketSuccess&&thi...
  method setTransport (line 24) | setTransport(s){ut("setting transport %s",s.name),this.transport&&(ut("c...
  method probe (line 24) | probe(s){ut('probing transport "%s"',s);let f=this.createTransport(s),v=...
  method onOpen (line 24) | onOpen(){if(ut("socket open"),this.readyState="open",En.priorWebsocketSu...
  method onPacket (line 24) | onPacket(s){if(this.readyState==="opening"||this.readyState==="open"||th...
  method onHandshake (line 24) | onHandshake(s){this.emitReserved("handshake",s),this.id=s.sid,this.trans...
  method resetPingTimeout (line 24) | resetPingTimeout(){this.clearTimeoutFn(this.pingTimeoutTimer),this.pingT...
  method onDrain (line 24) | onDrain(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferL...
  method flush (line 24) | flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.up...
  method getWritablePackets (line 24) | getWritablePackets(){if(!(this.maxPayload&&this.transport.name==="pollin...
  method write (line 24) | write(s,f,v){return this.sendPacket("message",s,f,v),this}
  method send (line 24) | send(s,f,v){return this.sendPacket("message",s,f,v),this}
  method sendPacket (line 24) | sendPacket(s,f,v,w){if(typeof f=="function"&&(w=f,f=void 0),typeof v=="f...
  method close (line 24) | close(){let s=()=>{this.onClose("forced close"),ut("socket closing - tel...
  method onError (line 24) | onError(s){ut("socket error %j",s),En.priorWebsocketSuccess=!1,this.emit...
  method onClose (line 24) | onClose(s,f){(this.readyState==="opening"||this.readyState==="open"||thi...
  method filterUpgrades (line 24) | filterUpgrades(s){let f=[],v=0,w=s.length;for(;v<w;v++)~this.transports....
  function Eg (line 24) | function Eg(c){if(c=String(c),!(c.length>100)){var s=/^(-?(?:\d+)?\.?\d+...
  function wg (line 24) | function wg(c){var s=Math.abs(c);return s>=Gn?Math.round(c/Gn)+"d":s>=Sr...
  function Ag (line 24) | function Ag(c){var s=Math.abs(c);return s>=Gn?es(c,s,Gn,"day"):s>=Sr?es(...
  function es (line 24) | function es(c,s,f,v){var w=s>=f*1.5;return Math.round(c/f)+" "+v+(w?"s":...
  function Sg (line 24) | function Sg(c){f.debug=f,f.default=f,f.coerce=pe,f.disable=q,f.enable=w,...
  function _g (line 24) | function _g(){return typeof window<"u"&&window.process&&(window.process....
  function Tg (line 24) | function Tg(c){if(c[0]=(this.useColors?"%c":"")+this.namespace+(this.use...
  function kg (line 24) | function kg(c){try{c?Ht.storage.setItem("debug",c):Ht.storage.removeItem...
  function Og (line 24) | function Og(){let c;try{c=Ht.storage.getItem("debug")}catch{}return!c&&t...
  function xg (line 24) | function xg(){try{return localStorage}catch{}}
  function Lg (line 24) | function Lg(c,s="",f){let v=c;f=f||typeof location<"u"&&location,c==null...
  function Hc (line 24) | function Hc(c){return Dg&&(c instanceof ArrayBuffer||Ig(c))||Ng&&c insta...
  function ns (line 24) | function ns(c,s){if(!c||typeof c!="object")return!1;if(Array.isArray(c))...
  function Bg (line 24) | function Bg(c){let s=[],f=c.data,v=c;return v.data=Ao(f,s),v.attachments...
  function Ao (line 24) | function Ao(c,s){if(!c)return c;if(Ug.isBinary(c)){let f={_placeholder:!...
  function Vg (line 24) | function Vg(c,s){return c.data=So(c.data,s),c.attachments=void 0,c}
  function So (line 24) | function So(c,s){if(!c)return c;if(c&&c._placeholder===!0){if(typeof c.n...
  function Wg (line 24) | function Wg(c){if(c=String(c),!(c.length>100)){var s=/^(-?(?:\d+)?\.?\d+...
  function zg (line 24) | function zg(c){var s=Math.abs(c);return s>=Xn?Math.round(c/Xn)+"d":s>=Pr...
  function Gg (line 24) | function Gg(c){var s=Math.abs(c);return s>=Xn?rs(c,s,Xn,"day"):s>=Pr?rs(...
  function rs (line 24) | function rs(c,s,f,v){var w=s>=f*1.5;return Math.round(c/f)+" "+v+(w?"s":...
  function Xg (line 24) | function Xg(c){f.debug=f,f.default=f,f.coerce=pe,f.disable=q,f.enable=w,...
  function Yg (line 24) | function Yg(){return typeof window<"u"&&window.process&&(window.process....
  function Jg (line 24) | function Jg(c){if(c[0]=(this.useColors?"%c":"")+this.namespace+(this.use...
  function Kg (line 24) | function Kg(c){try{c?Wt.storage.setItem("debug",c):Wt.storage.removeItem...
  function Zg (line 24) | function Zg(){let c;try{c=Wt.storage.getItem("debug")}catch{}return!c&&t...
  function Qg (line 24) | function Qg(){try{return localStorage}catch{}}
  method constructor (line 24) | constructor(s){this.replacer=s}
  method encode (line 24) | encode(s){return _o("encoding packet %j",s),(s.type===mt.EVENT||s.type==...
  method encodeAsString (line 24) | encodeAsString(s){let f=""+s.type;return(s.type===mt.BINARY_EVENT||s.typ...
  method encodeAsBinary (line 24) | encodeAsBinary(s){let f=Kc.deconstructPacket(s),v=this.encodeAsString(f....
  method constructor (line 24) | constructor(s){super();this.reviver=s}
  method add (line 24) | add(s){let f;if(typeof s=="string"){if(this.reconstructor)throw new Erro...
  method decodeString (line 24) | decodeString(s){let f=0,v={type:Number(s.charAt(0))};if(mt[v.type]===voi...
  method tryParse (line 24) | tryParse(s){try{return JSON.parse(s,this.reviver)}catch{return!1}}
  method isPayloadValid (line 24) | static isPayloadValid(s,f){switch(s){case mt.CONNECT:return typeof f=="o...
  method destroy (line 24) | destroy(){this.reconstructor&&this.reconstructor.finishedReconstruction()}
  method constructor (line 24) | constructor(s){this.packet=s,this.buffers=[],this.reconPack=s}
  method takeBinaryData (line 24) | takeBinaryData(s){if(this.buffers.push(s),this.buffers.length===this.rec...
  method finishedReconstruction (line 24) | finishedReconstruction(){this.reconPack=null,this.buffers=[]}
  function r$ (line 24) | function r$(c,s,f){return c.on(s,f),function(){c.off(s,f)}}
  method constructor (line 24) | constructor(s,f,v){super();this.connected=!1,this.receiveBuffer=[],this....
  method disconnected (line 24) | get disconnected(){return!this.connected}
  method subEvents (line 24) | subEvents(){if(this.subs)return;let s=this.io;this.subs=[us.on(s,"open",...
  method active (line 24) | get active(){return!!this.subs}
  method connect (line 24) | connect(){return this.connected?this:(this.subEvents(),this.io._reconnec...
  method open (line 24) | open(){return this.connect()}
  method send (line 24) | send(...s){return s.unshift("message"),this.emit.apply(this,s),this}
  method emit (line 24) | emit(s,...f){if(a$.hasOwnProperty(s))throw new Error('"'+s.toString()+'"...
  method _registerAckCallback (line 24) | _registerAckCallback(s,f){let v=this.flags.timeout;if(v===void 0){this.a...
  method packet (line 24) | packet(s){s.nsp=this.nsp,this.io._packet(s)}
  method onopen (line 24) | onopen(){Ut("transport is open - connecting"),typeof this.auth=="functio...
  method onerror (line 24) | onerror(s){this.connected||this.emitReserved("connect_error",s)}
  method onclose (line 24) | onclose(s,f){Ut("close (%s)",s),this.connected=!1,delete this.id,this.em...
  method onpacket (line 24) | onpacket(s){if(s.nsp===this.nsp)switch(s.type){case Zt.PacketType.CONNEC...
  method onevent (line 24) | onevent(s){let f=s.data||[];Ut("emitting event %j",f),s.id!=null&&(Ut("a...
  method emitEvent (line 24) | emitEvent(s){if(this._anyListeners&&this._anyListeners.length){let f=thi...
  method ack (line 24) | ack(s){let f=this,v=!1;return function(...w){v||(v=!0,Ut("sending ack %j...
  method onack (line 24) | onack(s){let f=this.acks[s.id];typeof f=="function"?(Ut("calling ack %s ...
  method onconnect (line 24) | onconnect(s){Ut("socket connected with id %s",s),this.id=s,this.connecte...
  method emitBuffered (line 24) | emitBuffered(){this.receiveBuffer.forEach(s=>this.emitEvent(s)),this.rec...
  method ondisconnect (line 24) | ondisconnect(){Ut("server disconnect (%s)",this.nsp),this.destroy(),this...
  method destroy (line 24) | destroy(){this.subs&&(this.subs.forEach(s=>s()),this.subs=void 0),this.i...
  method disconnect (line 24) | disconnect(){return this.connected&&(Ut("performing disconnect (%s)",thi...
  method close (line 24) | close(){return this.disconnect()}
  method compress (line 24) | compress(s){return this.flags.compress=s,this}
  method volatile (line 24) | get volatile(){return this.flags.volatile=!0,this}
  method timeout (line 24) | timeout(s){return this.flags.timeout=s,this}
  method onAny (line 24) | onAny(s){return this._anyListeners=this._anyListeners||[],this._anyListe...
  method prependAny (line 24) | prependAny(s){return this._anyListeners=this._anyListeners||[],this._any...
  method offAny (line 24) | offAny(s){if(!this._anyListeners)return this;if(s){let f=this._anyListen...
  method listenersAny (line 24) | listenersAny(){return this._anyListeners||[]}
  method onAnyOutgoing (line 24) | onAnyOutgoing(s){return this._anyOutgoingListeners=this._anyOutgoingList...
  method prependAnyOutgoing (line 24) | prependAnyOutgoing(s){return this._anyOutgoingListeners=this._anyOutgoin...
  method offAnyOutgoing (line 24) | offAnyOutgoing(s){if(!this._anyOutgoingListeners)return this;if(s){let f...
  method listenersAnyOutgoing (line 24) | listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}
  method notifyOutgoingListeners (line 24) | notifyOutgoingListeners(s){if(this._anyOutgoingListeners&&this._anyOutgo...
  function Mr (line 24) | function Mr(c){c=c||{},this.ms=c.min||100,this.max=c.max||1e4,this.facto...
  method constructor (line 24) | constructor(s,f){var v;super();this.nsps={},this.subs=[],s&&typeof s=="o...
  method reconnection (line 24) | reconnection(s){return arguments.length?(this._reconnection=!!s,this):th...
  method reconnectionAttempts (line 24) | reconnectionAttempts(s){return s===void 0?this._reconnectionAttempts:(th...
  method reconnectionDelay (line 24) | reconnectionDelay(s){var f;return s===void 0?this._reconnectionDelay:(th...
  method randomizationFactor (line 24) | randomizationFactor(s){var f;return s===void 0?this._randomizationFactor...
  method reconnectionDelayMax (line 24) | reconnectionDelayMax(s){var f;return s===void 0?this._reconnectionDelayM...
  method timeout (line 24) | timeout(s){return arguments.length?(this._timeout=s,this):this._timeout}
  method maybeReconnectOnOpen (line 24) | maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.bac...
  method open (line 24) | open(s){if(St("readyState %s",this._readyState),~this._readyState.indexO...
  method connect (line 24) | connect(s){return this.open(s)}
  method onopen (line 24) | onopen(){St("open"),this.cleanup(),this._readyState="open",this.emitRese...
  method onping (line 24) | onping(){this.emitReserved("ping")}
  method ondata (line 24) | ondata(s){try{this.decoder.add(s)}catch(f){this.onclose("parse error",f)}}
  method ondecoded (line 24) | ondecoded(s){Oo.nextTick(()=>{this.emitReserved("packet",s)},this.setTim...
  method onerror (line 24) | onerror(s){St("error",s),this.emitReserved("error",s)}
  method socket (line 24) | socket(s,f){let v=this.nsps[s];return v||(v=new h$.Socket(this,s,f),this...
  method _destroy (line 24) | _destroy(s){let f=Object.keys(this.nsps);for(let v of f)if(this.nsps[v]....
  method _packet (line 24) | _packet(s){St("writing packet %j",s);let f=this.encoder.encode(s);for(le...
  method cleanup (line 24) | cleanup(){St("cleanup"),this.subs.forEach(s=>s()),this.subs.length=0,thi...
  method _close (line 24) | _close(){St("disconnect"),this.skipReconnect=!0,this._reconnecting=!1,th...
  method disconnect (line 24) | disconnect(){return this._close()}
  method onclose (line 24) | onclose(s,f){St("closed due to %s",s),this.cleanup(),this.backoff.reset(...
  method reconnect (line 24) | reconnect(){if(this._reconnecting||this.skipReconnect)return this;let s=...
  method onreconnect (line 24) | onreconnect(){let s=this.backoff.attempts;this._reconnecting=!1,this.bac...
  function Jn (line 24) | function Jn(c,s){typeof c=="object"&&(s=c,c=void 0),s=s||{};let f=m$.url...
  function A$ (line 24) | function A$(c,s){var f=c.defer(),v;vn.on("connection",function(q){if(v=q...
  function _$ (line 24) | function _$(c,s){return{enable:function(f){return angular.forEach(c,func...
  function k$ (line 24) | function k$(c){return{all:function(){return c.getData("options")}}}
  function ae (line 24) | function ae(){try{return v in s&&s[v]}catch{return!1}}
  function s (line 24) | function s(x,S){return x==null?!1:Object.prototype.hasOwnProperty.call(x...
  function f (line 24) | function f(x){if(!x||q(x)&&x.length===0)return!0;if(typeof x!="string"){...
  function v (line 24) | function v(x){return c.call(x)}
  function w (line 24) | function w(x){return typeof x=="object"&&v(x)==="[object Object]"}
  function ae (line 24) | function ae(x){return typeof x=="boolean"||v(x)==="[object Boolean]"}
  function $e (line 24) | function $e(x){var S=parseInt(x);return S.toString()===x?S:x}
  function pe (line 24) | function pe(x){x=x||{};var S=function(j){return Object.keys(S).reduce(fu...
  function P$ (line 24) | function P$(c){var s=gn.get("bs",{});Object.keys(s).length||gn.set("bs",...
  function R$ (line 24) | function R$(){return{create:function(c){var s=new P$(c);return s}}}
  function F$ (line 24) | function F$(c,s,f,v){var w=this;w.options=!1,w.browsers=[],w.socketId=""...
  function L$ (line 24) | function L$(c){return c.displayUrl=D$(c.urls),c}
  function D$ (line 24) | function D$(c){return c?c.external||c.local:!1}
  function N$ (line 24) | function N$(c){c.html5Mode({enabled:!0,requireBase:!1})}

FILE: packages/browser-sync-ui/src/scripts/app.js
  function Config (line 26) | function Config($locationProvider) {

FILE: packages/browser-sync-ui/src/scripts/main/controller.js
  function MainController (line 19) | function MainController ($scope, $rootScope, $location, $injector) {
  function transformOptions (line 143) | function transformOptions(options) {
  function getDisplayUrl (line 154) | function getDisplayUrl (urls) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsClients.js
  function ClientsService (line 12) | function ClientsService(Socket) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsDisconnect.js
  function disconnectController (line 20) | function disconnectController($scope, $rootScope, $window) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsHistory.js
  function HistoryService (line 7) | function HistoryService(Socket) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsNotify.js
  function notifyController (line 19) | function notifyController($scope, $rootScope) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsSocket.js
  function SocketService (line 11) | function SocketService($q, $rootScope) {

FILE: packages/browser-sync-ui/src/scripts/modules/bsStore.js
  function Store (line 9) | function Store (ns) {
  function StoreModule (line 48) | function StoreModule () {

FILE: packages/browser-sync-ui/src/scripts/services/Options.js
  function OptionsService (line 10) | function OptionsService(Socket) {

FILE: packages/browser-sync-ui/src/scripts/services/Pages.js
  function ContentSections (line 14) | function ContentSections(pagesConfig, $location) {

FILE: packages/browser-sync-ui/tasks/icons.js
  function icons (line 7) | function icons (opts, ctx, done) {

FILE: packages/browser-sync-ui/test/client/e2e/e2e.sync-options.js
  function getItemText (line 47) | function getItemText(elem, selector, expected) {
  function getItemText (line 74) | function getItemText(elem, selector, expected) {

FILE: packages/browser-sync-ui/test/fixtures/plugin-multi-templates/index.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Test BS Plugin";

FILE: packages/browser-sync-ui/test/fixtures/plugin/index.plugin.js
  constant PLUGIN_NAME (line 1) | const PLUGIN_NAME = "Test BS Plugin";

FILE: packages/browser-sync/lib/args.js
  function isFilesArg (line 66) | function isFilesArg(arg) {

FILE: packages/browser-sync/lib/async.js
  function logPluginError (line 143) | function logPluginError(plugin) {

FILE: packages/browser-sync/lib/bin.ts
  type BsErrorLevels (line 13) | enum BsErrorLevels {
  type BsErrorTypes (line 17) | enum BsErrorTypes {
  type BsErrors (line 22) | type BsErrors = BsError[];
  type BsError (line 23) | interface BsError {
  type BsErrorItem (line 28) | interface BsErrorItem {
  function freshYargs (line 40) | function freshYargs() {
  function runFromCli (line 44) | function runFromCli() {
  function handleNoCommand (line 108) | function handleNoCommand(argv, input, yargs) {
  function handleCli (line 169) | function handleCli(opts) {
  function processStart (line 180) | function processStart(yargs) {
  function handleIncoming (line 195) | function handleIncoming(command, yargs) {
  function pathErrors (line 233) | function pathErrors(input, resolved): BsErrors {

FILE: packages/browser-sync/lib/browser-sync.js
  function taskRunner (line 134) | function taskRunner(bs) {
  function handleOut (line 170) | function handleOut(bs, out) {
  function setOptions (line 202) | function setOptions(bs, options) {
  function tasksComplete (line 226) | function tasksComplete(bs) {

FILE: packages/browser-sync/lib/cli/cli-options.ts
  type BsTempOptions (line 40) | type BsTempOptions = Map<string, any>;
  type TransformResult (line 41) | type TransformResult = [BsTempOptions, BsErrors];
  type TransformFn (line 42) | type TransformFn = (subject: BsTempOptions) => TransformResult;
  function merge (line 44) | function merge(input) {
  function explodeFilesArg (line 90) | function explodeFilesArg(string): string {
  function makeFilesArg (line 98) | function makeFilesArg(value) {
  function printErrors (line 124) | function printErrors(errors: BsErrors) {

FILE: packages/browser-sync/lib/cli/command.start.ts
  function preprocessFlags (line 54) | function preprocessFlags(flags) {
  function stripUndefined (line 68) | function stripUndefined(subject) {
  function legacyFilesArgs (line 83) | function legacyFilesArgs(flags) {
  function removeWatchBooleanWhenFalse (line 99) | function removeWatchBooleanWhenFalse(flags) {

FILE: packages/browser-sync/lib/cli/transforms/addCwdToWatchOptions.ts
  function addCwdToWatchOptions (line 3) | function addCwdToWatchOptions(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/addDefaultIgnorePatterns.ts
  function addDefaultIgnorePatterns (line 13) | function addDefaultIgnorePatterns(

FILE: packages/browser-sync/lib/cli/transforms/addToFilesOption.ts
  function addToFilesOption (line 4) | function addToFilesOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/appendServerDirectoryOption.ts
  function appendServerDirectoryOption (line 3) | function appendServerDirectoryOption(

FILE: packages/browser-sync/lib/cli/transforms/appendServerIndexOption.ts
  function appendServerIndexOption (line 3) | function appendServerIndexOption(

FILE: packages/browser-sync/lib/cli/transforms/copyCLIIgnoreToWatchOptions.ts
  function copyCLIIgnoreToWatchOptions (line 4) | function copyCLIIgnoreToWatchOptions(

FILE: packages/browser-sync/lib/cli/transforms/handleExtensionsOption.ts
  function handleExtensionsOption (line 10) | function handleExtensionsOption(

FILE: packages/browser-sync/lib/cli/transforms/handleFilesOption.ts
  function handleFilesOption (line 5) | function handleFilesOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/handleGhostModeOption.ts
  function handleGhostModeOption (line 4) | function handleGhostModeOption(

FILE: packages/browser-sync/lib/cli/transforms/handleHostOption.ts
  function handleHostOption (line 4) | function handleHostOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/handlePortsOption.ts
  function handlePortsOption (line 5) | function handlePortsOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/handleProxyOption.ts
  function handleProxyOption (line 6) | function handleProxyOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/cli/transforms/handleServerOption.ts
  function handleServerOption (line 5) | function handleServerOption(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/connect-utils.js
  function getPath (line 7) | function getPath(options, relative, port) {
  function getScriptArgs (line 249) | function getScriptArgs(options, scriptPath) {

FILE: packages/browser-sync/lib/file-event-handler.js
  function fileChanges (line 9) | function fileChanges(subject, options) {
  function applyReloadOperators (line 55) | function applyReloadOperators(subject, options) {
  function applyOperators (line 86) | function applyOperators(items, subject, options, scheduler) {
  function getAggregatedDebouncedStream (line 101) | function getAggregatedDebouncedStream(subject, options, scheduler) {

FILE: packages/browser-sync/lib/file-watcher.js
  function watch (line 70) | function watch(patterns, opts, cb) {

FILE: packages/browser-sync/lib/http-protocol.js
  function methodRequiresInstance (line 21) | function methodRequiresInstance(method) {

FILE: packages/browser-sync/lib/index.js
  function newEmitter (line 197) | function newEmitter() {
  function getSingletonEmitter (line 207) | function getSingletonEmitter() {
  function noop (line 221) | function noop(name) {
  function initSingleton (line 241) | function initSingleton() {
  function getSingletonValue (line 276) | function getSingletonValue(prop) {
  function getSingle (line 289) | function getSingle(name) {
  function create (line 334) | function create(name, emitter) {

FILE: packages/browser-sync/lib/lodash.custom.js
  function addMapEntry (line 273) | function addMapEntry(map, pair) {
  function addSetEntry (line 287) | function addSetEntry(set, value) {
  function apply (line 303) | function apply(func, thisArg, args) {
  function arrayEach (line 326) | function arrayEach(array, iteratee) {
  function arrayFilter (line 347) | function arrayFilter(array, predicate) {
  function arrayIncludes (line 371) | function arrayIncludes(array, value) {
  function arrayIncludesWith (line 385) | function arrayIncludesWith(array, value, comparator) {
  function arrayMap (line 406) | function arrayMap(array, iteratee) {
  function arrayPush (line 425) | function arrayPush(array, values) {
  function arrayReduce (line 448) | function arrayReduce(array, iteratee, accumulator, initAccum) {
  function arraySome (line 471) | function arraySome(array, predicate) {
  function asciiToArray (line 490) | function asciiToArray(string) {
  function baseFindIndex (line 505) | function baseFindIndex(array, predicate, fromIndex, fromRight) {
  function baseIndexOf (line 526) | function baseIndexOf(array, value, fromIndex) {
  function baseIsNaN (line 539) | function baseIsNaN(value) {
  function baseProperty (line 550) | function baseProperty(key) {
  function baseTimes (line 565) | function baseTimes(n, iteratee) {
  function baseUnary (line 582) | function baseUnary(func) {
  function baseValues (line 598) | function baseValues(object, props) {
  function cacheHas (line 612) | function cacheHas(cache, key) {
  function getValue (line 624) | function getValue(object, key) {
  function hasUnicode (line 635) | function hasUnicode(string) {
  function iteratorToArray (line 646) | function iteratorToArray(iterator) {
  function mapToArray (line 663) | function mapToArray(map) {
  function overArg (line 681) | function overArg(func, transform) {
  function setToArray (line 694) | function setToArray(set) {
  function strictIndexOf (line 714) | function strictIndexOf(array, value, fromIndex) {
  function stringToArray (line 733) | function stringToArray(string) {
  function unicodeToArray (line 746) | function unicodeToArray(string) {
  function lodash (line 967) | function lodash() {
  function object (line 980) | function object() {}
  function Hash (line 1004) | function Hash(entries) {
  function hashClear (line 1022) | function hashClear() {
  function hashDelete (line 1037) | function hashDelete(key) {
  function hashGet (line 1052) | function hashGet(key) {
  function hashHas (line 1070) | function hashHas(key) {
  function hashSet (line 1087) | function hashSet(key, value) {
  function ListCache (line 1111) | function ListCache(entries) {
  function listCacheClear (line 1129) | function listCacheClear() {
  function listCacheDelete (line 1143) | function listCacheDelete(key) {
  function listCacheGet (line 1169) | function listCacheGet(key) {
  function listCacheHas (line 1185) | function listCacheHas(key) {
  function listCacheSet (line 1199) | function listCacheSet(key, value) {
  function MapCache (line 1228) | function MapCache(entries) {
  function mapCacheClear (line 1246) | function mapCacheClear() {
  function mapCacheDelete (line 1264) | function mapCacheDelete(key) {
  function mapCacheGet (line 1279) | function mapCacheGet(key) {
  function mapCacheHas (line 1292) | function mapCacheHas(key) {
  function mapCacheSet (line 1306) | function mapCacheSet(key, value) {
  function SetCache (line 1332) | function SetCache(values) {
  function setCacheAdd (line 1352) | function setCacheAdd(value) {
  function setCacheHas (line 1366) | function setCacheHas(value) {
  function Stack (line 1383) | function Stack(entries) {
  function stackClear (line 1395) | function stackClear() {
  function stackDelete (line 1409) | function stackDelete(key) {
  function stackGet (line 1426) | function stackGet(key) {
  function stackHas (line 1439) | function stackHas(key) {
  function stackSet (line 1453) | function stackSet(key, value) {
  function arrayLikeKeys (line 1486) | function arrayLikeKeys(value, inherited) {
  function assignMergeValue (line 1528) | function assignMergeValue(object, key, value) {
  function assignValue (line 1547) | function assignValue(object, key, value) {
  function assocIndexOf (line 1565) | function assocIndexOf(array, key) {
  function baseAssign (line 1584) | function baseAssign(object, source) {
  function baseAssignIn (line 1597) | function baseAssignIn(object, source) {
  function baseAssignValue (line 1610) | function baseAssignValue(object, key, value) {
  function baseClone (line 1639) | function baseClone(value, bitmask, customizer, key, object, stack) {
  function baseFlatten (line 1736) | function baseFlatten(array, depth, predicate, isStrict, result) {
  function baseForOwn (line 1780) | function baseForOwn(object, iteratee) {
  function baseGet (line 1792) | function baseGet(object, path) {
  function baseGetAllKeys (line 1815) | function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  function baseGetTag (line 1829) | function baseGetTag(value) {
  function baseHasIn (line 1846) | function baseHasIn(object, key) {
  function baseIsArguments (line 1857) | function baseIsArguments(value) {
  function baseIsEqual (line 1875) | function baseIsEqual(value, other, bitmask, customizer, stack) {
  function baseIsEqualDeep (line 1910) | function baseIsEqualDeep(
  function baseIsMatch (line 2002) | function baseIsMatch(object, source, matchData, customizer) {
  function baseIsNative (line 2069) | function baseIsNative(value) {
  function baseIsTypedArray (line 2084) | function baseIsTypedArray(value) {
  function baseIteratee (line 2099) | function baseIteratee(value) {
  function baseKeys (line 2123) | function baseKeys(object) {
  function baseKeysIn (line 2143) | function baseKeysIn(object) {
  function baseMatches (line 2170) | function baseMatches(source) {
  function baseMatchesProperty (line 2188) | function baseMatchesProperty(path, srcValue) {
  function baseMerge (line 2215) | function baseMerge(object, source, srcIndex, customizer, stack) {
  function baseMergeDeep (line 2270) | function baseMergeDeep(
  function basePropertyDeep (line 2343) | function basePropertyDeep(path) {
  function baseRest (line 2357) | function baseRest(func, start) {
  function baseSet (line 2371) | function baseSet(object, path, value, customizer) {
  function baseToString (line 2432) | function baseToString(value) {
  function baseUniq (line 2457) | function baseUniq(array, iteratee, comparator) {
  function castPath (line 2513) | function castPath(value, object) {
  function cloneBuffer (line 2528) | function cloneBuffer(buffer, isDeep) {
  function cloneArrayBuffer (line 2548) | function cloneArrayBuffer(arrayBuffer) {
  function cloneDataView (line 2562) | function cloneDataView(dataView, isDeep) {
  function cloneMap (line 2582) | function cloneMap(map, isDeep, cloneFunc) {
  function cloneRegExp (line 2596) | function cloneRegExp(regexp) {
  function cloneSet (line 2614) | function cloneSet(set, isDeep, cloneFunc) {
  function cloneSymbol (line 2628) | function cloneSymbol(symbol) {
  function cloneTypedArray (line 2640) | function cloneTypedArray(typedArray, isDeep) {
  function copyArray (line 2659) | function copyArray(source, array) {
  function copyObject (line 2680) | function copyObject(source, props, object, customizer) {
  function copySymbols (line 2714) | function copySymbols(source, object) {
  function copySymbolsIn (line 2726) | function copySymbolsIn(source, object) {
  function createAssigner (line 2737) | function createAssigner(assigner) {
  function createBaseEach (line 2772) | function createBaseEach(eachFunc, fromRight) {
  function createBaseFor (line 2800) | function createBaseFor(fromRight) {
  function equalArrays (line 2843) | function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  function equalByTag (line 2942) | function equalByTag(
  function equalObjects (line 3043) | function equalObjects(
  function getAllKeys (line 3129) | function getAllKeys(object) {
  function getAllKeysIn (line 3141) | function getAllKeysIn(object) {
  function getIteratee (line 3156) | function getIteratee() {
  function getMapData (line 3170) | function getMapData(map, key) {
  function getMatchData (line 3184) | function getMatchData(object) {
  function getNative (line 3205) | function getNative(object, key) {
  function getRawTag (line 3217) | function getRawTag(value) {
  function hasPath (line 3323) | function hasPath(object, path, hasFunc) {
  function initCloneArray (line 3356) | function initCloneArray(array) {
  function initCloneObject (line 3379) | function initCloneObject(object) {
  function initCloneByTag (line 3398) | function initCloneByTag(object, tag, cloneFunc, isDeep) {
  function isFlattenable (line 3447) | function isFlattenable(value) {
  function isIndex (line 3463) | function isIndex(value, length) {
  function isIterateeCall (line 3482) | function isIterateeCall(value, index, object) {
  function isKey (line 3505) | function isKey(value, object) {
  function isKeyable (line 3533) | function isKeyable(value) {
  function isMasked (line 3550) | function isMasked(func) {
  function isPrototype (line 3561) | function isPrototype(value) {
  function isStrictComparable (line 3577) | function isStrictComparable(value) {
  function matchesStrictComparable (line 3590) | function matchesStrictComparable(key, srcValue) {
  function memoizeCapped (line 3610) | function memoizeCapped(func) {
  function nativeKeysIn (line 3631) | function nativeKeysIn(object) {
  function objectToString (line 3648) | function objectToString(value) {
  function overRest (line 3661) | function overRest(func, start, transform) {
  function shortOut (line 3701) | function shortOut(func) {
  function toKey (line 3748) | function toKey(value) {
  function toSource (line 3763) | function toSource(func) {
  function forEach (line 3829) | function forEach(collection, iteratee) {
  function includes (line 3864) | function includes(collection, value, fromIndex, guard) {
  function memoize (line 3923) | function memoize(func, resolver) {
  function eq (line 3983) | function eq(value, other) {
  function isArrayLike (line 4069) | function isArrayLike(value) {
  function isArrayLikeObject (line 4098) | function isArrayLikeObject(value) {
  function isFunction (line 4138) | function isFunction(value) {
  function isLength (line 4179) | function isLength(value) {
  function isObject (line 4213) | function isObject(value) {
  function isObjectLike (line 4242) | function isObjectLike(value) {
  function isPlainObject (line 4274) | function isPlainObject(value) {
  function isString (line 4308) | function isString(value) {
  function isSymbol (line 4334) | function isSymbol(value) {
  function isUndefined (line 4379) | function isUndefined(value) {
  function toArray (line 4406) | function toArray(value) {
  function toFinite (line 4450) | function toFinite(value) {
  function toInteger (line 4488) | function toInteger(value) {
  function toNumber (line 4522) | function toNumber(value) {
  function toPlainObject (line 4570) | function toPlainObject(value) {
  function toString (line 4595) | function toString(value) {
  function get (line 4626) | function get(object, path, defaultValue) {
  function hasIn (line 4657) | function hasIn(object, path) {
  function keys (line 4689) | function keys(object) {
  function keysIn (line 4716) | function keysIn(object) {
  function set (line 4785) | function set(object, path, value) {
  function values (line 4815) | function values(object) {
  function constant (line 4840) | function constant(value) {
  function identity (line 4862) | function identity(value) {
  function iteratee (line 4908) | function iteratee(func) {
  function noop (line 4926) | function noop() {
  function property (line 4952) | function property(path) {
  function stubArray (line 4974) | function stubArray() {
  function stubFalse (line 4991) | function stubFalse() {

FILE: packages/browser-sync/lib/logger.js
  function serveFiles (line 182) | function serveFiles(base) {
  function logUrls (line 220) | function logUrls(urls) {
  function getPadding (line 268) | function getPadding(len, max) {
  function getChars (line 277) | function getChars(len, char) {
  function getKeyName (line 286) | function getKeyName(key) {
  function canLogFileChange (line 304) | function canLogFileChange(bs, data) {

FILE: packages/browser-sync/lib/options.ts
  function setProxyWs (line 12) | function setProxyWs(incoming: BsTempOptions): TransformResult {
  function setOpen (line 22) | function setOpen(incoming: BsTempOptions): TransformResult {
  function setMode (line 40) | function setMode(incoming: BsTempOptions): TransformResult {
  function setScheme (line 59) | function setScheme(incoming: BsTempOptions): TransformResult {
  function setStartPath (line 82) | function setStartPath(incoming: BsTempOptions): TransformResult {
  function setNamespace (line 95) | function setNamespace(incoming: BsTempOptions): TransformResult {
  function setServerOpts (line 113) | function setServerOpts(incoming: BsTempOptions): TransformResult {
  function liftExtensionsOptionFromCli (line 138) | function liftExtensionsOptionFromCli(
  function fixRewriteRules (line 158) | function fixRewriteRules(incoming: BsTempOptions): TransformResult {
  function fixSnippetIgnorePaths (line 169) | function fixSnippetIgnorePaths(
  function fixSnippetIncludePaths (line 190) | function fixSnippetIncludePaths(
  function ensureSlash (line 210) | function ensureSlash(item) {
  function setMiddleware (line 220) | function setMiddleware(incoming: BsTempOptions): TransformResult {
  function getMiddlwares (line 230) | function getMiddlwares(item) {
  function isList (line 256) | function isList(item) {
  function listMerge (line 265) | function listMerge(list, item) {
  function setUiPort (line 281) | function setUiPort(incoming: BsTempOptions): TransformResult {

FILE: packages/browser-sync/lib/plugins.js
  function resolvePlugin (line 27) | function resolvePlugin(item) {
  function requirePlugin (line 122) | function requirePlugin(item) {
  function getFromString (line 165) | function getFromString(string) {

FILE: packages/browser-sync/lib/public/exit.js
  function exit (line 8) | function exit() {

FILE: packages/browser-sync/lib/public/reload.js
  function browserSyncReload (line 19) | function browserSyncReload(opts) {

FILE: packages/browser-sync/lib/public/stream.js
  function browserSyncThroughStream (line 18) | function browserSyncThroughStream(opts) {

FILE: packages/browser-sync/lib/server/index.js
  function setCloseReceived (line 62) | function setCloseReceived(io) {
  function createServer (line 85) | function createServer(bs) {

FILE: packages/browser-sync/lib/server/proxy-server.js
  function applyFns (line 127) | function applyFns(name, fns) {
  function getProxyResFunctions (line 146) | function getProxyResFunctions(resFns, opt) {
  function getProxyReqFunctions (line 157) | function getProxyReqFunctions(reqFns, opt, bs) {

FILE: packages/browser-sync/lib/server/proxy-utils.js
  function rewriteCookies (line 122) | function rewriteCookies(rawCookie) {

FILE: packages/browser-sync/lib/server/utils.js
  function getCa (line 22) | function getCa(options) {
  function getKey (line 40) | function getKey(options) {
  function getCert (line 46) | function getCert(options) {
  function getHttpsServerDefaults (line 52) | function getHttpsServerDefaults(options) {
  function getPFXDefaults (line 61) | function getPFXDefaults(options) {
  function normaliseMiddleware (line 258) | function normaliseMiddleware(item) {
  function getRoute (line 417) | function getRoute(x) {
  function getFromString (line 426) | function getFromString(dir) {
  function getFromMap (line 442) | function getFromMap(dir) {

FILE: packages/browser-sync/lib/sockets.ts
  function plugin (line 8) | function plugin(server, clientEvents, bs) {
  function init (line 17) | function init(server, clientEvents, bs) {

FILE: packages/browser-sync/lib/types.ts
  type ServerIncoming (line 4) | type ServerIncoming = string | string[] | IServerOption;
  type IServerOption (line 6) | interface IServerOption {
  type MiddlewareInput (line 15) | type MiddlewareInput = Function | Function[] | Middleware | Middleware[];
  type Middleware (line 17) | interface Middleware {
  type BrowsersyncProxyIncoming (line 23) | type BrowsersyncProxyIncoming = string | BrowsersyncProxy;
  type BrowsersyncProxy (line 24) | interface BrowsersyncProxy {
  type PortsOption (line 30) | type PortsOption = {
  type FilesObject (line 35) | type FilesObject = { match: string[]; fn?: Function; options?: any };
  type FilesNamespace (line 36) | type FilesNamespace = { globs: string[]; objs: FilesObject[] };
  type FilesNamespaces (line 37) | type FilesNamespaces = { [name: string]: FilesNamespace };

FILE: packages/browser-sync/lib/utils.ts
  function getHostIp (line 18) | function getHostIp(options: BsTempOptions, devIp: string[]) {
  function getUrlOptions (line 35) | function getUrlOptions(options: BsTempOptions): Map<string, string> {
  function getUrl (line 61) | function getUrl(url: string, options: BsTempOptions) {
  function getUrls (line 82) | function getUrls(external, local, scheme, options) {
  function _makeUrl (line 104) | function _makeUrl(scheme, host, port) {
  type PortLookupCb (line 108) | type PortLookupCb = (error: null | Error, port: number) => void;
  function getPorts (line 114) | function getPorts(options: BsTempOptions, cb: PortLookupCb) {
  function getPort (line 129) | function getPort(
  function getUaString (line 150) | function getUaString(ua) {
  function openBrowser (line 160) | function openBrowser(url, options, bs) {
  function opnWrapper (line 192) | function opnWrapper(url, name, bs) {
  function fail (line 213) | function fail(kill, errMessage, cb) {
  function hostnameSuffix (line 233) | function hostnameSuffix(host, options) {
  function willCauseReload (line 247) | function willCauseReload(needles, haystack) {
  function getConfigErrors (line 260) | function getConfigErrors(options) {
  function verifyConfig (line 276) | function verifyConfig(options, cb) {
  function eachSeries (line 285) | function eachSeries(arr, iterator, callback) {
  function arrayify (line 310) | function arrayify(incoming) {
  function defaultCallback (line 317) | function defaultCallback(err?: Error) {
  function parseParams (line 332) | function parseParams(search: string): Record<string, any> {
  function serializeParams (line 366) | function serializeParams(args: Record<string, any> = {}): URLSearchParams {

FILE: packages/browser-sync/test/fixtures/bootstrap/js/bootstrap.bundle.js
  function _defineProperties (line 14) | function _defineProperties(target, props) {
  function _createClass (line 24) | function _createClass(Constructor, protoProps, staticProps) {
  function _extends (line 30) | function _extends() {
  function _inheritsLoose (line 48) | function _inheritsLoose(subClass, superClass) {
  function toType (line 70) | function toType(obj) {
  function getSpecialTransitionEndEvent (line 74) | function getSpecialTransitionEndEvent() {
  function transitionEndTest (line 88) | function transitionEndTest() {
  function transitionEndEmulator (line 98) | function transitionEndEmulator(duration) {
  function setTransitionEndSupport (line 113) | function setTransitionEndSupport() {
  function escapeId (line 122) | function escapeId(selector) {
  function Alert (line 237) | function Alert(element) {
  function Button (line 411) | function Button(element) {
  function Carousel (line 614) | function Carousel(element, config) {
  function Collapse (line 1088) | function Collapse(element, config) {
  function microtaskDebounce (line 1430) | function microtaskDebounce(fn) {
  function taskDebounce (line 1444) | function taskDebounce(fn) {
  function isFunction (line 1477) | function isFunction(functionToCheck) {
  function getStyleComputedProperty (line 1489) | function getStyleComputedProperty(element, property) {
  function getParentNode (line 1505) | function getParentNode(element) {
  function getScrollParent (line 1519) | function getScrollParent(element) {
  function getOffsetParent (line 1554) | function getOffsetParent(element) {
  function isOffsetContainer (line 1576) | function isOffsetContainer(element) {
  function getRoot (line 1592) | function getRoot(node) {
  function findCommonOffsetParent (line 1608) | function findCommonOffsetParent(element1, element2) {
  function getScroll (line 1652) | function getScroll(element) {
  function includeScroll (line 1676) | function includeScroll(rect, element) {
  function getBordersSize (line 1699) | function getBordersSize(styles, axis) {
  function getSize (line 1721) | function getSize(axis, body, html, computedStyle) {
  function getWindowSizes (line 1725) | function getWindowSizes() {
  function defineProperties (line 1743) | function defineProperties(target, props) {
  function getClientRect (line 1800) | function getClientRect(offsets) {
  function getBoundingClientRect (line 1814) | function getBoundingClientRect(element) {
  function getOffsetRectRelativeToArbitraryNode (line 1863) | function getOffsetRectRelativeToArbitraryNode(children, parent) {
  function getViewportOffsetRectRelativeToArtbitraryNode (line 1908) | function getViewportOffsetRectRelativeToArtbitraryNode(element) {
  function isFixed (line 1935) | function isFixed(element) {
  function getBoundaries (line 1956) | function getBoundaries(popper, reference, padding, boundariesElement) {
  function getArea (line 2005) | function getArea(_ref) {
  function computeAutoPlacement (line 2021) | function computeAutoPlacement(placement, refRect, popper, reference, bou...
  function getReferenceOffsets (line 2081) | function getReferenceOffsets(state, popper, reference) {
  function getOuterSizes (line 2093) | function getOuterSizes(element) {
  function getOppositePlacement (line 2111) | function getOppositePlacement(placement) {
  function getPopperOffsets (line 2128) | function getPopperOffsets(popper, referenceOffsets, placement) {
  function find (line 2166) | function find(arr, check) {
  function findIndex (line 2185) | function findIndex(arr, prop, value) {
  function runModifiers (line 2210) | function runModifiers(modifiers, data, ends) {
  function update (line 2240) | function update() {
  function isModifierEnabled (line 2289) | function isModifierEnabled(modifiers, modifierName) {
  function getSupportedPropertyName (line 2304) | function getSupportedPropertyName(property) {
  function destroy (line 2323) | function destroy() {
  function getWindow (line 2350) | function getWindow(element) {
  function attachToScrollParents (line 2355) | function attachToScrollParents(scrollParent, event, callback, scrollPare...
  function setupEventListeners (line 2372) | function setupEventListeners(reference, options, state, updateBound) {
  function enableEventListeners (line 2392) | function enableEventListeners() {
  function removeEventListeners (line 2404) | function removeEventListeners(reference, state) {
  function disableEventListeners (line 2428) | function disableEventListeners() {
  function isNumeric (line 2442) | function isNumeric(n) {
  function setStyles (line 2454) | function setStyles(element, styles) {
  function setAttributes (line 2473) | function setAttributes(element, attributes) {
  function applyStyle (line 2493) | function applyStyle(data) {
  function applyStyleOnLoad (line 2522) | function applyStyleOnLoad(reference, popper, options, modifierOptions, s...
  function computeStyle (line 2547) | function computeStyle(data, options) {
  function isModifierRequired (line 2644) | function isModifierRequired(modifiers, requestingName, requestedName) {
  function arrow (line 2669) | function arrow(data, options) {
  function getOppositeVariation (line 2751) | function getOppositeVariation(variation) {
  function clockwise (line 2806) | function clockwise(placement) {
  function flip (line 2827) | function flip(data, options) {
  function keepTogether (line 2917) | function keepTogether(data) {
  function toValue (line 2951) | function toValue(str, measurement, popperOffsets, referenceOffsets) {
  function parseOffset (line 3003) | function parseOffset(offset, popperOffsets, referenceOffsets, basePlacem...
  function offset (line 3079) | function offset(data, _ref) {
  function preventOverflow (line 3120) | function preventOverflow(data, options) {
  function shift (line 3171) | function shift(data) {
  function hide (line 3204) | function hide(data) {
  function inner (line 3242) | function inner(data) {
  function Popper (line 3687) | function Popper(reference, popper) {
  function Dropdown (line 3920) | function Dropdown(element, config) {
  function Modal (line 4368) | function Modal(element, config) {
  function Tooltip (line 4968) | function Tooltip(element, config) {
  function Popover (line 5597) | function Popover() {
  function ScrollSpy (line 5793) | function ScrollSpy(element, config) {
  function Tab (line 6093) | function Tab(element) {

FILE: packages/browser-sync/test/fixtures/bootstrap/js/bootstrap.js
  function _defineProperties (line 15) | function _defineProperties(target, props) {
  function _createClass (line 25) | function _createClass(Constructor, protoProps, staticProps) {
  function _extends (line 31) | function _extends() {
  function _inheritsLoose (line 49) | function _inheritsLoose(subClass, superClass) {
  function toType (line 71) | function toType(obj) {
  function getSpecialTransitionEndEvent (line 75) | function getSpecialTransitionEndEvent() {
  function transitionEndTest (line 89) | function transitionEndTest() {
  function transitionEndEmulator (line 99) | function transitionEndEmulator(duration) {
  function setTransitionEndSupport (line 114) | function setTransitionEndSupport() {
  function escapeId (line 123) | function escapeId(selector) {
  function Alert (line 238) | function Alert(element) {
  function Button (line 412) | function Button(element) {
  function Carousel (line 615) | function Carousel(element, config) {
  function Collapse (line 1089) | function Collapse(element, config) {
  function Dropdown (line 1486) | function Dropdown(element, config) {
  function Modal (line 1934) | function Modal(element, config) {
  function Tooltip (line 2534) | function Tooltip(element, config) {
  function Popover (line 3163) | function Popover() {
  function ScrollSpy (line 3359) | function ScrollSpy(element, config) {
  function Tab (line 3659) | function Tab(element) {

FILE: packages/browser-sync/test/protractor/_run.js
  function runTests (line 29) | function runTests (config, configFile, bs, cb) {

FILE: packages/browser-sync/test/protractor/runProtractor.js
  function runTests (line 4) | function runTests (config, configFile, cb) {

FILE: packages/browser-sync/test/protractor/tests.multi.js
  function getApp (line 6) | function getApp (bs, options) {

FILE: packages/browser-sync/test/protractor/tests/proxy.interactions.js
  function assertScripts (line 96) | function assertScripts () {

FILE: packages/browser-sync/test/protractor/tests/server.interactions.js
  function assertScripts (line 75) | function assertScripts () {

FILE: packages/browser-sync/test/protractor/tests/with.baseurl.https.js
  function assertScripts (line 40) | function assertScripts () {

FILE: packages/browser-sync/test/protractor/tests/with.baseurl.js
  function assertScripts (line 37) | function assertScripts () {

FILE: packages/browser-sync/test/protractor/tests/with.socket.io.js
  function assertScripts (line 49) | function assertScripts () {

FILE: packages/browser-sync/test/specs/cli/cli.help.js
  function assertHelpOutput (line 6) | function assertHelpOutput(args, cond, done) {

FILE: packages/browser-sync/test/specs/e2e/e2e.options.logSnippet.js
  function testString (line 34) | function testString(match) {

FILE: packages/browser-sync/test/specs/e2e/e2e.options.serveStatic.js
  function getRequests (line 8) | function getRequests(reqs, server) {

FILE: tests/utils.ts
  type Msg (line 17) | type Msg = z.infer<typeof messageSchema>;
  type NextArgs (line 19) | interface NextArgs {
  type RequestForArgs (line 134) | interface RequestForArgs {
  function makesRequestIn (line 149) | function makesRequestIn(page: Page, args: RequestForArgs) {
  type ResponseForArgs (line 186) | interface ResponseForArgs {
  function responseFor (line 191) | async function responseFor(args: ResponseForArgs) {
  function timeout (line 207) | function timeout({ ms, msg }: { ms?: number; msg?: string } = {}): Promi...
  function touchFile (line 213) | function touchFile(filePath) {
Condensed preview — 682 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,530K chars).
[
  {
    "path": ".editorconfig",
    "chars": 218,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\ntrim_"
  },
  {
    "path": ".gitattributes",
    "chars": 12,
    "preview": "* text=auto\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 1470,
    "preview": "name: CI\n\n# Controls when the workflow will run\non:\n  # Triggers the workflow on push or pull request events but only fo"
  },
  {
    "path": ".gitignore",
    "chars": 497,
    "preview": "node_modules\n.idea\nnpm-debug.log\n.sass-cache\ntest/fixtures/files/*\ntest/fixtures/js/*\nexample.server.js\nexample.proxy.js"
  },
  {
    "path": ".travis.yml",
    "chars": 70,
    "preview": "git:\n  depth: 2\nlanguage: node_js\nnode_js:\n  - \"14\"\n  - \"12\"\n  - \"10\"\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4422,
    "preview": "# Contributing to Browsersync\n\nWe'd love for you to contribute to Browsersync and help make it even better than it is\nto"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "chars": 766,
    "preview": "### Issue details\n\n_Please provide issue details here_.\n\n### Steps to reproduce/test case\n\n_Please provide necessary ste"
  },
  {
    "path": "LICENSE",
    "chars": 11349,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 2571,
    "preview": "<p align=\"center\">\n<a href=\"https://www.npmjs.com/package/browser-sync\" title=\"NPM version\">\n <img src=\"https://img.shie"
  },
  {
    "path": "changelog.js",
    "chars": 1710,
    "preview": "const {execSync} = require('child_process');\nlet [start, end] = process.argv.slice(2);\nif (!start || !end)  {\n    consol"
  },
  {
    "path": "examples/404.js",
    "chars": 584,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will redire"
  },
  {
    "path": "examples/basic/run.js",
    "chars": 598,
    "preview": "const bs = require(\"../../packages/browser-sync/dist/index\").create();\nconst path = require(\"path\");\nconst serverDir = p"
  },
  {
    "path": "examples/callback.js",
    "chars": 469,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example shows how y"
  },
  {
    "path": "examples/express.js",
    "chars": 813,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync express\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example wil"
  },
  {
    "path": "examples/less.js",
    "chars": 606,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will serve "
  },
  {
    "path": "examples/middleware.css.injection.js",
    "chars": 1325,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync less\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will p"
  },
  {
    "path": "examples/notify-styles.js",
    "chars": 671,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n */\n\n\"use strict\";\n\nvar bro"
  },
  {
    "path": "examples/options.snippetOptions.js",
    "chars": 667,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example shows how y"
  },
  {
    "path": "examples/proxy.gzip.js",
    "chars": 450,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync compression\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example"
  },
  {
    "path": "examples/proxy.headers.js",
    "chars": 698,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example shows how t"
  },
  {
    "path": "examples/proxy.localhost.js",
    "chars": 359,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will wrap y"
  },
  {
    "path": "examples/proxy.middleware.js",
    "chars": 472,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/proxy.middleware.multi.js",
    "chars": 554,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/proxy.proxyRes.js",
    "chars": 503,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will proxy "
  },
  {
    "path": "examples/proxy.rewriteRules.advanced.js",
    "chars": 1168,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync serve-static\n *\n * Run:\n *      node <yourfile.js>\n *\n * This exampl"
  },
  {
    "path": "examples/proxy.rewriteRules.simple.js",
    "chars": 1004,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync serve-static\n *\n * Run:\n *      node <yourfile.js>\n *\n * This exampl"
  },
  {
    "path": "examples/proxy.secure.js",
    "chars": 312,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/proxy.vhost.js",
    "chars": 341,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will wrap y"
  },
  {
    "path": "examples/server.basedir.js",
    "chars": 340,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.basedir.mulitple.js",
    "chars": 367,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.default.js",
    "chars": 288,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.gzip.js",
    "chars": 409,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync compression\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example"
  },
  {
    "path": "examples/server.http2.js",
    "chars": 430,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync http2\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will "
  },
  {
    "path": "examples/server.latency.js",
    "chars": 582,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.middleware.js",
    "chars": 573,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.middleware.multiple.js",
    "chars": 755,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.proxy.js",
    "chars": 558,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync express http-proxy-middleware\n *\n * Run:\n *      node <yourfile.js>\n"
  },
  {
    "path": "examples/server.secure.js",
    "chars": 399,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.secure.pfx.js",
    "chars": 433,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/server.watch.js",
    "chars": 354,
    "preview": "/**\n *\n * Install:\n *      npm install browser-sync\n *\n * Run:\n *      node <yourfile.js>\n *\n * This example will create"
  },
  {
    "path": "examples/snippet/index.html",
    "chars": 414,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta\n            name=\"viewport\"\n "
  },
  {
    "path": "examples/snippet/run.js",
    "chars": 686,
    "preview": "const bs = require(\"../../packages/browser-sync/dist/index\").create();\nbs.init(\n    {\n        server: \".\",\n        open:"
  },
  {
    "path": "lerna.json",
    "chars": 63,
    "preview": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"3.0.4\"\n}\n"
  },
  {
    "path": "nx.json",
    "chars": 283,
    "preview": "{\n  \"tasksRunnerOptions\": {\n    \"default\": {\n      \"runner\": \"nx/tasks-runners/default\",\n      \"options\": {\n        \"cac"
  },
  {
    "path": "package.json",
    "chars": 439,
    "preview": "{\n\t\"private\": true,\n\t\"name\": \"browser-sync-mono\",\n\t\"scripts\": {\n\t\t\"bootstrap\": \"lerna bootstrap\",\n\t\t\"postinstall\": \"npm "
  },
  {
    "path": "packages/browser-sync/.gitignore",
    "chars": 8,
    "preview": "/dist/*\n"
  },
  {
    "path": "packages/browser-sync/.prettierignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "packages/browser-sync/certs/gen.sh",
    "chars": 268,
    "preview": "openssl genrsa -des3 -out server.key 2048\nopenssl req -new -key server.key -out server.csr\nopenssl x509 -req -days 3650 "
  },
  {
    "path": "packages/browser-sync/certs/server.crt",
    "chars": 1111,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDBjCCAe4CCQCir/8eGDIE/jANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJH\nQjETMBEGA1UECAwKU29tZS1TdGF"
  },
  {
    "path": "packages/browser-sync/certs/server.csr",
    "chars": 989,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIICoTCCAYkCAQAwRTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUx\nITAfBgNVBAoMGEludGV"
  },
  {
    "path": "packages/browser-sync/certs/server.key",
    "chars": 1675,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAxEtHZysoHhf/2kzeBHrjWIOxxlZbdqqjvSdQPHOjkGGTy66m\nrPQR91GgIsJR5CLFWnccnUe"
  },
  {
    "path": "packages/browser-sync/cli-options/opts.init.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "packages/browser-sync/cli-options/opts.recipe.json",
    "chars": 82,
    "preview": "{\n  \"output\": {\n    \"alias\": \"o\",\n    \"desc\": \"Specify an output directory\"\n  }\n}\n"
  },
  {
    "path": "packages/browser-sync/cli-options/opts.reload.json",
    "chars": 316,
    "preview": "{\n  \"files\": {\n    \"desc\": \"File paths to reload\",\n    \"type\": \"array\",\n    \"alias\": \"f\"\n  },\n  \"port\": {\n    \"alias\": \""
  },
  {
    "path": "packages/browser-sync/cli-options/opts.start.json",
    "chars": 3392,
    "preview": "{\n  \"server\": {\n    \"alias\": \"s\",\n    \"desc\": \"Run a Local server (uses your cwd as the web root)\"\n  },\n  \"cwd\": {\n    \""
  },
  {
    "path": "packages/browser-sync/lib/args.js",
    "chars": 1573,
    "preview": "\"use strict\";\n\n/**\n * The purpose of this function is\n * to handle back-backwards compatibility\n * @param {Object} args\n"
  },
  {
    "path": "packages/browser-sync/lib/async-tasks.js",
    "chars": 1325,
    "preview": "var async = require(\"./async\");\n\nmodule.exports = [\n    {\n        step: \"Finding an empty port\",\n        fn: async.getEm"
  },
  {
    "path": "packages/browser-sync/lib/async.js",
    "chars": 9983,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\nvar Immutable = require(\"immutable\");\n\nvar utils = require(\"./utils\")"
  },
  {
    "path": "packages/browser-sync/lib/bin.ts",
    "chars": 7281,
    "preview": "#!/usr/bin/env node\nconst startOpts = require(\"../cli-options/opts.start.json\");\nconst reloadOpts = require(\"../cli-opti"
  },
  {
    "path": "packages/browser-sync/lib/browser-sync.js",
    "chars": 14933,
    "preview": "\"use strict\";\n\nvar hooks = require(\"./hooks\");\nvar asyncTasks = require(\"./async-tasks\");\nvar config = require(\"./config"
  },
  {
    "path": "packages/browser-sync/lib/cli/cli-info.js",
    "chars": 1598,
    "preview": "\"use strict\";\n\nvar config = require(\"../config\");\nvar logger = require(\"../logger\").logger;\n\nvar fs = require(\"fs\");\nvar"
  },
  {
    "path": "packages/browser-sync/lib/cli/cli-options.ts",
    "chars": 4172,
    "preview": "import { Map, List, fromJS } from \"immutable\";\nimport { addToFilesOption } from \"./transforms/addToFilesOption\";\nimport "
  },
  {
    "path": "packages/browser-sync/lib/cli/command.init.js",
    "chars": 263,
    "preview": "\"use strict\";\n\nvar info = require(\"./cli-info\");\n\n/**\n * $ browser-sync init\n *\n * This command will generate a configur"
  },
  {
    "path": "packages/browser-sync/lib/cli/command.recipe.js",
    "chars": 2095,
    "preview": "\"use strict\";\nvar logger = require(\"../logger\").logger;\nvar chalk  = require(\"chalk\");\n\n/**\n * $ browser-sync recipe <na"
  },
  {
    "path": "packages/browser-sync/lib/cli/command.reload.js",
    "chars": 1120,
    "preview": "\"use strict\";\n\n/**\n * $ browser-sync reload <options>\n *\n * This commands starts the Browsersync servers\n * & Optionally"
  },
  {
    "path": "packages/browser-sync/lib/cli/command.start.ts",
    "chars": 2602,
    "preview": "import * as path from \"path\";\nimport { existsSync } from \"fs\";\nimport { fromJS } from \"immutable\";\nimport * as utils fro"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/addCwdToWatchOptions.ts",
    "chars": 307,
    "preview": "import { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function addCwdToWatchOptions(incoming: BsTempO"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/addDefaultIgnorePatterns.ts",
    "chars": 795,
    "preview": "import { List } from \"immutable\";\nimport { BsTempOptions, TransformResult } from \"../cli-options\";\n\nconst defaultIgnoreP"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/addToFilesOption.ts",
    "chars": 1501,
    "preview": "import { List, Map } from \"immutable\";\nimport { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/appendServerDirectoryOption.ts",
    "chars": 411,
    "preview": "import { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function appendServerDirectoryOption(\n    incom"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/appendServerIndexOption.ts",
    "chars": 372,
    "preview": "import { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function appendServerIndexOption(\n    incoming:"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/copyCLIIgnoreToWatchOptions.ts",
    "chars": 494,
    "preview": "import { List } from \"immutable\";\nimport { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function copy"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleExtensionsOption.ts",
    "chars": 613,
    "preview": "import { List } from \"immutable\";\nimport {\n    BsTempOptions,\n    explodeFilesArg,\n    TransformResult\n} from \"../cli-op"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleFilesOption.ts",
    "chars": 685,
    "preview": "import { fromJS } from \"immutable\";\nimport { BsTempOptions, makeFilesArg, TransformResult } from \"../cli-options\";\nimpor"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleGhostModeOption.ts",
    "chars": 1869,
    "preview": "import { fromJS } from \"immutable\";\nimport { BsTempOptions, TransformResult } from \"../cli-options\";\n\nexport function ha"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleHostOption.ts",
    "chars": 1504,
    "preview": "import { BsTempOptions, TransformResult } from \"../cli-options\";\nimport { BsErrorLevels, BsErrorTypes } from \"../../bin\""
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handlePortsOption.ts",
    "chars": 812,
    "preview": "import { Map } from \"immutable\";\nimport { PortsOption } from \"../../types\";\nimport { BsTempOptions, TransformResult } fr"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleProxyOption.ts",
    "chars": 1055,
    "preview": "import * as url from \"url\";\nimport { Map } from \"immutable\";\nimport { BrowsersyncProxy } from \"../../types\";\nimport { Bs"
  },
  {
    "path": "packages/browser-sync/lib/cli/transforms/handleServerOption.ts",
    "chars": 1185,
    "preview": "import { IServerOption } from \"../../types\";\nimport { fromJS, List, Map } from \"immutable\";\nimport { BsTempOptions, Tran"
  },
  {
    "path": "packages/browser-sync/lib/config.js",
    "chars": 1177,
    "preview": "\"use strict\";\n\nvar path = require(\"path\");\n/**\n * @type {{controlPanel: {jsFile: string, baseDir: *}, socketIoScript: st"
  },
  {
    "path": "packages/browser-sync/lib/connect-utils.js",
    "chars": 8036,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\nvar fs = require(\"fs\");\nvar config = require(\"./config\");\n\nfunction g"
  },
  {
    "path": "packages/browser-sync/lib/default-config.js",
    "chars": 14122,
    "preview": "/**\n * @module BrowserSync.options\n */\nmodule.exports = {\n    /**\n     * Browsersync includes a user-interface that is a"
  },
  {
    "path": "packages/browser-sync/lib/file-event-handler.js",
    "chars": 2597,
    "preview": "var utils = require(\"./utils\");\n\n/**\n * Apply the operators that apply to the 'file:changed' event\n * @param {Rx.Observa"
  },
  {
    "path": "packages/browser-sync/lib/file-utils.js",
    "chars": 1793,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\n\nvar fileUtils = {\n    /**\n     * React to file-change events that oc"
  },
  {
    "path": "packages/browser-sync/lib/file-watcher.js",
    "chars": 2117,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\nvar utils = require(\"./utils\");\nvar Rx = require(\"rx\");\n\n/**\n * Plugi"
  },
  {
    "path": "packages/browser-sync/lib/hooks.js",
    "chars": 2610,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\nvar Immutable = require(\"immutable\");\nvar snippetUtils = require(\"./s"
  },
  {
    "path": "packages/browser-sync/lib/http-protocol.js",
    "chars": 3426,
    "preview": "\"use strict\";\n\nvar proto = exports;\nvar instanceMethods = [\"exit\", \"notify\", \"pause\", \"resume\"];\nvar getBody = require(\""
  },
  {
    "path": "packages/browser-sync/lib/index.js",
    "chars": 10722,
    "preview": "#! /usr/bin/env node\n\"use strict\";\n\n/**\n * @module BrowserSync\n */\nvar pjson = require(\"../package.json\");\nvar BrowserSy"
  },
  {
    "path": "packages/browser-sync/lib/internal-events.js",
    "chars": 3626,
    "preview": "\"use strict\";\n\nvar utils = require(\"./utils\");\nvar fileUtils = require(\"./file-utils\");\nvar Rx = require(\"rx\");\nvar from"
  },
  {
    "path": "packages/browser-sync/lib/lodash.custom.js",
    "chars": 158386,
    "preview": "/**\n * @license\n * Lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash include=\"isUndefined,isFunction,toArray"
  },
  {
    "path": "packages/browser-sync/lib/logger.js",
    "chars": 7797,
    "preview": "\"use strict\";\n\nvar messages = require(\"./connect-utils\");\nvar utils = require(\"./utils\");\nvar _ = require(\"./lodash.cust"
  },
  {
    "path": "packages/browser-sync/lib/options.ts",
    "chars": 6594,
    "preview": "import { BsTempOptions, TransformResult } from \"./cli/cli-options\";\n\nconst _ = require(\"./lodash.custom\");\nimport * as I"
  },
  {
    "path": "packages/browser-sync/lib/plugins.js",
    "chars": 4853,
    "preview": "var Immutable = require(\"immutable\");\nvar Map = Immutable.Map;\nvar isMap = Immutable.Map.isMap;\nvar List = Immutable.Lis"
  },
  {
    "path": "packages/browser-sync/lib/public/exit.js",
    "chars": 304,
    "preview": "\"use strict\";\n\n/**\n * @param {BrowserSync} browserSync\n * @returns {Function}\n */\nmodule.exports = function(browserSync)"
  },
  {
    "path": "packages/browser-sync/lib/public/init.ts",
    "chars": 1013,
    "preview": "var _ = require(\"../lodash.custom\");\nimport { merge, printErrors } from \"../cli/cli-options\";\n\n/**\n * @param {BrowserSyn"
  },
  {
    "path": "packages/browser-sync/lib/public/notify.js",
    "chars": 373,
    "preview": "\"use strict\";\n\n/**\n * @param {BrowserSync} browserSync\n * @returns {Function}\n */\nmodule.exports = function(browserSync)"
  },
  {
    "path": "packages/browser-sync/lib/public/pause.js",
    "chars": 192,
    "preview": "\"use strict\";\n\n/**\n * @param {BrowserSync} browserSync\n * @returns {Function}\n */\nmodule.exports = function(browserSync)"
  },
  {
    "path": "packages/browser-sync/lib/public/public-utils.js",
    "chars": 1580,
    "preview": "\"use strict\";\n\nvar _ = require(\"../lodash.custom\");\n\nmodule.exports = {\n    /**\n     * Emit the internal `file:change` e"
  },
  {
    "path": "packages/browser-sync/lib/public/reload.js",
    "chars": 1929,
    "preview": "\"use strict\";\n\nvar utils = require(\"../utils\");\nvar publicUtils = require(\"./public-utils\");\nvar _ = require(\"../lodash."
  },
  {
    "path": "packages/browser-sync/lib/public/resume.js",
    "chars": 193,
    "preview": "\"use strict\";\n\n/**\n * @param {BrowserSync} browserSync\n * @returns {Function}\n */\nmodule.exports = function(browserSync)"
  },
  {
    "path": "packages/browser-sync/lib/public/stream.js",
    "chars": 2570,
    "preview": "\"use strict\";\n\nvar path = require(\"path\");\nvar micromatch = require(\"micromatch\");\nvar utils = require(\"./public-utils\")"
  },
  {
    "path": "packages/browser-sync/lib/server/index.js",
    "chars": 2464,
    "preview": "\"use strict\";\n\nvar enableDestroy = require(\"server-destroy\");\nvar _ = require(\"../lodash.custom\");\n\n/**\n * Browsersync s"
  },
  {
    "path": "packages/browser-sync/lib/server/proxy-server.js",
    "chars": 5128,
    "preview": "\"use strict\";\n\nvar httpProxy = require(\"http-proxy\");\nvar utils = require(\"./utils\");\nvar proxyUtils = require(\"./proxy-"
  },
  {
    "path": "packages/browser-sync/lib/server/proxy-utils.js",
    "chars": 4372,
    "preview": "var url = require(\"url\");\n\nmodule.exports.rewriteLinks = function(userServer) {\n    var host = userServer.hostname;\n    "
  },
  {
    "path": "packages/browser-sync/lib/server/serve-static-wrapper.ts",
    "chars": 313,
    "preview": "export default function() {\n    const serveStatic = require(\"serve-static\");\n\n    /**\n     * Adding a custom mime-type f"
  },
  {
    "path": "packages/browser-sync/lib/server/snippet-server.js",
    "chars": 373,
    "preview": "\"use strict\";\n\nvar connect = require(\"connect\");\nvar serverUtils = require(\"./utils.js\");\n\n/**\n * Create a server for th"
  },
  {
    "path": "packages/browser-sync/lib/server/static-server.js",
    "chars": 2654,
    "preview": "var serverUtils = require(\"./utils.js\");\nvar resolve = require(\"path\").resolve;\nvar utils = require(\"../utils.js\");\nvar "
  },
  {
    "path": "packages/browser-sync/lib/server/utils.js",
    "chars": 16271,
    "preview": "\"use strict\";\n\nvar fs = require(\"fs\");\nvar path = require(\"path\");\nvar join = require(\"path\").join;\nvar connect = requir"
  },
  {
    "path": "packages/browser-sync/lib/snippet.js",
    "chars": 2971,
    "preview": "\"use strict\";\n\nvar connectUtils = require(\"./connect-utils\");\nvar config = require(\"./config\");\n\nvar lrSnippet = require"
  },
  {
    "path": "packages/browser-sync/lib/sockets.ts",
    "chars": 2104,
    "preview": "import {Server} from \"socket.io\";\nimport * as utils from \"./server/utils\";\n\n/**\n * Plugin interface\n * @returns {*|funct"
  },
  {
    "path": "packages/browser-sync/lib/tunnel.js",
    "chars": 1345,
    "preview": "\"use strict\";\n\nvar _ = require(\"./lodash.custom\");\nvar utils = require(\"util\");\n\n/**\n * @param {BrowserSync} bs\n * @para"
  },
  {
    "path": "packages/browser-sync/lib/types.ts",
    "chars": 990,
    "preview": "import * as url from \"url\";\nimport { Map } from \"immutable\";\n\nexport type ServerIncoming = string | string[] | IServerOp"
  },
  {
    "path": "packages/browser-sync/lib/utils.ts",
    "chars": 9292,
    "preview": "import { BsTempOptions } from \"./cli/cli-options\";\n\nimport * as devIp from \"dev-ip\";\nimport * as portScanner from \"ports"
  },
  {
    "path": "packages/browser-sync/package.json",
    "chars": 2394,
    "preview": "{\n\t\"name\": \"browser-sync\",\n\t\"description\": \"Live CSS Reload & Browser Syncing\",\n\t\"version\": \"3.0.4\",\n\t\"homepage\": \"https"
  },
  {
    "path": "packages/browser-sync/readme.md",
    "chars": 2706,
    "preview": "<p align=\"center\">\n<a href=\"https://travis-ci.org/BrowserSync/browser-sync\" title=\"Travis branch\">\n <img src=\"https://im"
  },
  {
    "path": "packages/browser-sync/templates/cli-template.js",
    "chars": 448,
    "preview": "\n/*\n |--------------------------------------------------------------------------\n | Browser-sync config file\n |---------"
  },
  {
    "path": "packages/browser-sync/templates/connector.tmpl",
    "chars": 326,
    "preview": "window.___browserSync___ = {};\n___browserSync___.socketConfig = %config%;\n___browserSync___.socketUrl = %url%;\n___browse"
  },
  {
    "path": "packages/browser-sync/templates/script-tags-simple.html",
    "chars": 60,
    "preview": "<script %async% id=\"__bs_script__\" src=\"%script%\"></script>\n"
  },
  {
    "path": "packages/browser-sync/templates/script-tags.html",
    "chars": 513,
    "preview": "<script id=\"__bs_script__\">//<![CDATA[\n  (function() {\n    try {\n      var script = document.createElement('script');\n  "
  },
  {
    "path": "packages/browser-sync/test/env.js",
    "chars": 28,
    "preview": "process.env.TESTING = true;\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/.tmp/temp.css",
    "chars": 29,
    "preview": "body {\n    background: red;\n}"
  },
  {
    "path": "packages/browser-sync/test/fixtures/alt/index.htm",
    "chars": 607,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/assets/import.css",
    "chars": 52,
    "preview": "@import \"import2.css\";\n\nbody {\n    color: orange;\n}\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/assets/import2.css",
    "chars": 29,
    "preview": "body {\n    background: red;\n}"
  },
  {
    "path": "packages/browser-sync/test/fixtures/assets/print.css",
    "chars": 87,
    "preview": "body {\n    background: #322323;\n}\n\n.container {\n    margin: 0 auto;\n    width: 320px;\n}"
  },
  {
    "path": "packages/browser-sync/test/fixtures/assets/style.css",
    "chars": 87,
    "preview": "body {\n    background: white;\n}\n\n\n.container {\n    margin: 0 auto;\n    width: 320px;\n}\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/base.html",
    "chars": 2015,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/css/bootstrap-grid.css",
    "chars": 38875,
    "preview": "/*!\n * Bootstrap Grid v4.0.0-beta.3 (https://getbootstrap.com)\n * Copyright 2011-2017 The Bootstrap Authors\n * Copyright"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/css/bootstrap-reboot.css",
    "chars": 4968,
    "preview": "/*!\n * Bootstrap Reboot v4.0.0-beta.3 (https://getbootstrap.com)\n * Copyright 2011-2017 The Bootstrap Authors\n * Copyrig"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/css/bootstrap.css",
    "chars": 174909,
    "preview": "/*!\n * Bootstrap v4.0.0-beta.3 (https://getbootstrap.com)\n * Copyright 2011-2017 The Bootstrap Authors\n * Copyright 2011"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/css/justified-nav.css",
    "chars": 937,
    "preview": "body {\n    padding-top: 20px;\n}\n\n.footer {\n    padding-top: 40px;\n    padding-bottom: 40px;\n    margin-top: 40px;\n    bo"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/index.html",
    "chars": 4758,
    "preview": "\n<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-widt"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/js/bootstrap.bundle.js",
    "chars": 195758,
    "preview": "/*!\n  * Bootstrap v4.0.0-beta.3 (https://getbootstrap.com)\n  * Copyright 2011-2017 The Bootstrap Authors (https://github"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap/js/bootstrap.js",
    "chars": 114953,
    "preview": "/*!\n  * Bootstrap v4.0.0-beta.3 (https://getbootstrap.com)\n  * Copyright 2011-2017 The Bootstrap Authors (https://github"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bootstrap.html",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "packages/browser-sync/test/fixtures/bower.html",
    "chars": 419,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  },
  {
    "path": "packages/browser-sync/test/fixtures/bower_components/app.css",
    "chars": 32,
    "preview": "body {\n    background: orange;\n}"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/config.js",
    "chars": 4764,
    "preview": "/*\n |--------------------------------------------------------------------------\n | Browser-sync config file\n |----------"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/si-config-partial.js",
    "chars": 98,
    "preview": "module.exports = {\n    files: \"test/fixtures/**/*.css\",\n    testConfig: true,\n    server:false\n};\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/si-config-ports.js",
    "chars": 463,
    "preview": "module.exports = {\n    files: \"test/fixtures/**/*.css\",\n    testConfig: true,\n    logLevel: \"info\",\n    background: fals"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/si-config-proxy.js",
    "chars": 423,
    "preview": "module.exports = {\n    files: \"test/fixtures/**/*.css\",\n    testConfig: true,\n    logLevel: \"info\",\n    background: fals"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/si-config.js",
    "chars": 207,
    "preview": "module.exports = {\n    files: [\"test/fixtures/**/*.css\", \"test/fixtures/**/*.html\"],\n    testConfig: true,\n    logLevel:"
  },
  {
    "path": "packages/browser-sync/test/fixtures/config/si-default-config.js",
    "chars": 403,
    "preview": "module.exports = {\n    logLevel: \"info\",\n    files: \"test/fixtures/assets/style.css\",\n    background: false,\n    default"
  },
  {
    "path": "packages/browser-sync/test/fixtures/css/bootstrap-less.css",
    "chars": 121461,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/css/bootstrap-scss.css",
    "chars": 122009,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/css/bootstrap.css",
    "chars": 121432,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/fonts/roboto/Roboto-Regular-demo.html",
    "chars": 24065,
    "preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  },
  {
    "path": "packages/browser-sync/test/fixtures/fonts/roboto/stylesheet.css",
    "chars": 418,
    "preview": "@font-face {\n    font-family: 'robotoregular';\n    src: url('Roboto-Regular-webfont.eot');\n    src: url('Roboto-Regular-"
  },
  {
    "path": "packages/browser-sync/test/fixtures/forms.html",
    "chars": 2272,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/iframe.html",
    "chars": 580,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/images.html",
    "chars": 509,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/import-link.html",
    "chars": 328,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/import.html",
    "chars": 356,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/index-amd.html",
    "chars": 583,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/index-large.html",
    "chars": 67127,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/index-urls.html",
    "chars": 716,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/index.html",
    "chars": 718,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/inputs.html",
    "chars": 1087,
    "preview": "<form id=\"form01\">\n\n<label for=\"name\">Text Inputs: synced</label>\n<input type=\"text\" name=\"name\" value=\"name here\" id=\"n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/js/default.js",
    "chars": 22,
    "preview": "console.log('heelo');\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/js/main.js",
    "chars": 53,
    "preview": "define([], function () {\n    console.log('hey!');\n});"
  },
  {
    "path": "packages/browser-sync/test/fixtures/less/bootstrap.less",
    "chars": 122849,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/less.html",
    "chars": 588,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/links.html",
    "chars": 112,
    "preview": "<a href=\"#\" id=\"link\">Link</a>\n<a href=\"#\" id=\"img-link\">\n    <div>\n        <img src=\"\" alt=\"\"/>\n    </div>\n</a>"
  },
  {
    "path": "packages/browser-sync/test/fixtures/plugin.js",
    "chars": 125,
    "preview": "module.exports = {\n    \"plugin:name\": \"My Plugin\",\n    \"plugin\": function () {\n        console.log('running here');\n    "
  },
  {
    "path": "packages/browser-sync/test/fixtures/proxy-headers.html",
    "chars": 584,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/proxy-ip.html",
    "chars": 16012,
    "preview": "\n<!doctype html>\n<!--[if lt IE 7]>      <html class=\"no-js ie ie6 lt-ie10 lt-ie9 lt-ie8 lt-ie7\" lang=\"en\"> <![endif]-->\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/proxy-vhost.html",
    "chars": 15931,
    "preview": "\n<!doctype html>\n<!--[if lt IE 7]>      <html class=\"no-js ie ie6 lt-ie10 lt-ie9 lt-ie8 lt-ie7\" lang=\"en\"> <![endif]-->\n"
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/comment.expected.html",
    "chars": 243,
    "preview": "<!doctype html>\n<html><body>\n<p>This is an experiment.dev</p>\n<p><img src=\"/images/experiment.dev/example.jpg\"></p>\n<!--"
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/comment.html",
    "chars": 246,
    "preview": "<!doctype html>\n<html><body>\n<p>This is an experiment.dev</p>\n<p><img src=\"/images/experiment.dev/example.jpg\"></p>\n<!--"
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/escaped.1.expected.html",
    "chars": 145,
    "preview": "<a href=\"//192.168.0.4:3002\"></a>\nphpdebugbar.setOpenHandler(new PhpDebugBar.OpenHandler({\"url\":\"http:\\/\\/192.168.0.4:30"
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/escaped.1.html",
    "chars": 132,
    "preview": "<a href=\"http://demo.l5\"></a>\nphpdebugbar.setOpenHandler(new PhpDebugBar.OpenHandler({\"url\":\"http:\\/\\/demo.l5\\/_debugbar"
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/hashes.expected.html",
    "chars": 728,
    "preview": "<ul class=\"navigation__items\">\n  <li class=\"navigation__items__page\">\n    <a href=\"//192.168.0.4:3002/careers/?number=4\""
  },
  {
    "path": "packages/browser-sync/test/fixtures/rewrites/hashes.input.html",
    "chars": 830,
    "preview": "<ul class=\"navigation__items\">\n  <li class=\"navigation__items__page\">\n    <a href=\"http://www.example.local.colinr.com/c"
  },
  {
    "path": "packages/browser-sync/test/fixtures/sass.html",
    "chars": 591,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/scrolling.html",
    "chars": 3882,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/scss/bootstrap-scss.scss",
    "chars": 122533,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/socket.io.html",
    "chars": 413,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome="
  },
  {
    "path": "packages/browser-sync/test/fixtures/stylus/bootstrap.styl",
    "chars": 112372,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "packages/browser-sync/test/fixtures/svg.html",
    "chars": 185,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Included SVG reload test</title>\n</head>\n<body>\n\n<if"
  },
  {
    "path": "packages/browser-sync/test/fixtures/tailwind/index.html",
    "chars": 1298,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  },
  {
    "path": "packages/browser-sync/test/fixtures/test.txt",
    "chars": 15,
    "preview": "writing to file"
  },
  {
    "path": "packages/browser-sync/test/fixtures/test2.txt",
    "chars": 15,
    "preview": "writing to file"
  },
  {
    "path": "packages/browser-sync/test/fixtures/username.github.io/index.html",
    "chars": 325,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  },
  {
    "path": "packages/browser-sync/test/fixtures/watch-func.txt",
    "chars": 59,
    "preview": "A test generated this file and it is safe to delete changed"
  },
  {
    "path": "packages/browser-sync/test/fixtures2/style-alt.css",
    "chars": 28,
    "preview": "body {\n\tbackground: green;\n}"
  },
  {
    "path": "packages/browser-sync/test/protractor/_run.js",
    "chars": 1784,
    "preview": "\nvar browserSync = require(\"../../\");\nvar exec        = require(\"child_process\").exec;\n\nmodule.exports = function (logge"
  },
  {
    "path": "packages/browser-sync/test/protractor/bs.init.js",
    "chars": 359,
    "preview": "\nvar bs = require(\"../../\");\n\nmodule.exports = function (protractor, config) {\n    var flow = protractor.promise.control"
  },
  {
    "path": "packages/browser-sync/test/protractor/config.multi.js",
    "chars": 169,
    "preview": "\nexports.config = {\n    seleniumAddress: \"http://localhost:4444/wd/hub\",\n    baseUrl: process.env[\"BS_BASE\"],\n    specs:"
  },
  {
    "path": "packages/browser-sync/test/protractor/config.single.js",
    "chars": 391,
    "preview": "\nexports.config = {\n    seleniumAddress: \"http://localhost:4444/wd/hub\",\n    specs: [\n        //process.env[\"BS_TEST_FIL"
  },
  {
    "path": "packages/browser-sync/test/protractor/logger.js",
    "chars": 258,
    "preview": "var chalk       = require(\"chalk\");\nmodule.exports = require(\"eazy-logger\").Logger({\n    prefix: chalk.magenta(\"[BS E2E]"
  },
  {
    "path": "packages/browser-sync/test/protractor/runProtractor.js",
    "chars": 946,
    "preview": "\nvar exec = require(\"child_process\").exec;\n\nfunction runTests (config, configFile, cb) {\n    var out = \"\";\n    exec(\"pro"
  },
  {
    "path": "packages/browser-sync/test/protractor/setup.js",
    "chars": 836,
    "preview": "\nvar eachSeries  = require(\"async-each-series\");\nvar path        = require(\"path\");\nvar logger      = require(\"./logger\""
  },
  {
    "path": "packages/browser-sync/test/protractor/setup.single.js",
    "chars": 1015,
    "preview": "\nvar eachSeries  = require(\"async-each-series\");\nvar path        = require(\"path\");\nvar logger      = require(\"./logger\""
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/actions.clicks.js",
    "chars": 1324,
    "preview": "\nvar init = require(\"../bs.init\");\n\ndescribe(\"Scrolling around\", function () {\n    var instance;\n    var urls;\n    befor"
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/actions.scroll.js",
    "chars": 1617,
    "preview": "\nvar init = require(\"../bs.init\");\n\ndescribe(\"Scrolling around\", function () {\n    beforeEach(function () {\n        brow"
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/proxy.interactions.js",
    "chars": 3093,
    "preview": "\nvar init    = require(\"../bs.init\");\nvar path    = require(\"path\");\nvar connect = require(\"connect\");\nvar serveStatic ="
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/proxy.rewrites.js",
    "chars": 3268,
    "preview": "//var init    = require(\"../bs.init\");\n//var path    = require(\"path\");\n//var connect = require(\"connect\");\n//var serveS"
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/server.interactions.js",
    "chars": 2479,
    "preview": "\nvar init = require(\"../bs.init\");\nvar path = require(\"path\");\n\ndescribe(\"Interactions on Server Pages\", function () {\n "
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/snippet.injection.js",
    "chars": 991,
    "preview": "\n/**\n *\n */\n// abstract writing screen shot to a file\n//var fs = require(\"fs\");\n//var slugify = require(\"slugify\");\n//fu"
  },
  {
    "path": "packages/browser-sync/test/protractor/tests/with.baseurl.https.js",
    "chars": 1117,
    "preview": "\nvar init = require(\"../bs.init\");\n\ndescribe(\"works when base url set in HTML\", function () {\n    var instance;\n    var "
  }
]

// ... and 482 more files (download for full content)

About this extraction

This page contains the full source code of the BrowserSync/browser-sync GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 682 files (3.2 MB), approximately 867.3k tokens, and a symbol index with 1288 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!