[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*.{html,js}]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".gitignore",
    "content": "package-lock.json\nnpm-debug.log\nnode_modules/\n.DS_Store\ncoverage/\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n- 16\nscript: \"npm run test-travis\"\nafter_script: \"npm install coveralls@2 && cat ./coverage/lcov.info | coveralls\"\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Xin Hao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Readme.md",
    "content": "[![NPM version][npm-img]][npm-url]\n[![Build status][travis-img]][travis-url]\n[![Test coverage][coveralls-img]][coveralls-url]\n[![License][license-img]][license-url]\n[![Dependency status][david-img]][david-url]\n[![Gitter][gitter-img]][gitter-url]\n\n# gulp-file-include\na [gulp](https://github.com/gulpjs/gulp) plugin for file includes\n\n## Installation\n\n```bash\nnpm install --save-dev gulp-file-include\n```\n\n## API\n\n```js\nconst fileinclude = require('gulp-file-include');\n```\n\n### fileinclude([prefix])\n\n#### prefix\n\nType: `string`<br>\nDefault: `'@@'`\n\n### fileinclude([options])\n\n#### options\n\nType: `object`\n\n##### options.prefix\n\nType: `string`<br>\nDefault: `'@@'`\n\n##### options.suffix\n\nType: `string`<br>\nDefault: `''`\n\n##### options.basepath\n\nType: `string`<br>\nDefault: `'@file'`\n\nPossible values:\n  - `'@file'`:  include file relative to the dir in which `file` resides ([example](#include-options---type-json))\n  - `'@root'`: include file relative to the dir in which `gulp` is running\n  - `path/to/dir`: include file relative to the basepath you provide\n\n##### options.filters\n\nType: `object`<br>\nDefault: `false`\n\nFilters of include content.\n\n##### options.context\n\nType: `object`\nDefault: `{}`\n\nContext of `if` statement.\n\n##### options.indent\n\nType: `boolean`\nDefault: `false`\n\n## Examples\n\n### @@include options - type: `JSON`\n\nindex.html\n```html\n<!DOCTYPE html>\n<html>\n  <body>\n  @@include('./view.html')\n  @@include('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  </body>\n</html>\n```\n\nview.html\n```html\n<h1>view</h1>\n```\n\nvar.html\n```html\n<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>\n```\n\ngulpfile.js\n```js\nconst fileinclude = require('gulp-file-include');\nconst gulp = require('gulp');\n\ngulp.task('fileinclude', function() {\n  gulp.src(['index.html'])\n    .pipe(fileinclude({\n      prefix: '@@',\n      basepath: '@file'\n    }))\n    .pipe(gulp.dest('./'));\n});\n```\n\nresult:\n```html\n<!DOCTYPE html>\n<html>\n  <body>\n  <h1>view</h1>\n  <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<strong>twitter.com/include</strong>\n  </body>\n</html>\n```\n\n### @@include_once options - type: `JSON`\n\nindex.html\n```html\n<!DOCTYPE html>\n<html>\n  <body>\n  @@include_once('./view.html')\n  @@include_once('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  @@include_once('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  </body>\n</html>\n```\n\nview.html\n```html\n<h1>view</h1>\n```\n\nvar.html\n```html\n<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>\n```\n\ngulpfile.js\n```js\nconst fileinclude = require('gulp-file-include');\nconst gulp = require('gulp');\n\ngulp.task('fileinclude', function() {\n  gulp.src(['index.html'])\n    .pipe(fileinclude({\n      prefix: '@@',\n      basepath: '@file'\n    }))\n    .pipe(gulp.dest('./'));\n});\n```\n\nresult:\n```html\n<!DOCTYPE html>\n<html>\n  <body>\n  <h1>view</h1>\n  <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<strong>twitter.com/include</strong>\n\n  </body>\n</html>\n```\n\n\n### filters\n\nindex.html\n```html\n<!DOCTYPE html>\n<html>\n  <body>\n  @@include(markdown('view.md'))\n  @@include('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })\n  </body>\n</html>\n```\n\nview.md\n```html\nview\n====\n```\n\ngulpfile.js\n```js\nconst fileinclude = require('gulp-file-include');\nconst markdown = require('markdown');\nconst gulp = require('gulp');\n\ngulp.task('fileinclude', function() {\n  gulp.src(['index.html'])\n    .pipe(fileinclude({\n      filters: {\n        markdown: markdown.parse\n      }\n    }))\n    .pipe(gulp.dest('./'));\n});\n```\n\n### `if` statement\n\nindex.html\n```\n@@include('some.html', { \"nav\": true })\n\n@@if (name === 'test' && nav === true) {\n  @@include('test.html')\n}\n```\n\ngulpfile.js\n```js\nfileinclude({\n  context: {\n    name: 'test'\n  }\n});\n```\n\n### `for` statement\n\nindex.html\n```html\n<ul>\n@@for (var i = 0; i < arr.length; i++) {\n  <li>`+arr[i]+`</li>\n}\n</ul>\n```\n\ngulpfile.js\n```js\nfileinclude({\n  context: {\n    arr: ['test1', 'test2']\n  }\n});\n```\n\n### `loop` statement\n\nindex.html\n```html\n<body>\n  @@loop('loop-article.html', [\n    { \"title\": \"My post title\", \"text\": \"<p>lorem ipsum...</p>\" },\n    { \"title\": \"Another post\", \"text\": \"<p>lorem ipsum...</p>\" },\n    { \"title\": \"One more post\", \"text\": \"<p>lorem ipsum...</p>\" }\n  ])\n</body>\n```\n\nloop-article.html\n```html\n<article>\n  <h1>@@title</h1>\n  @@text\n</article>\n```\n\n### `loop` statement + `data.json`\n\ndata.json\n```js\n[\n  { \"title\": \"My post title\", \"text\": \"<p>lorem ipsum...</p>\" },\n  { \"title\": \"Another post\", \"text\": \"<p>lorem ipsum...</p>\" },\n  { \"title\": \"One more post\", \"text\": \"<p>lorem ipsum...</p>\" }\n]\n```\n\nloop-article.html\n```html\n<body>\n  @@loop(\"loop-article.html\", \"data.json\")\n</body>\n```\n\n### `webRoot` built-in context variable\n\nThe `webRoot` field of the context contains the relative path from the source document to\nthe source root (unless the value is already set in the context options).\n\nsupport/contact/index.html\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <link type=stylesheet src=@@webRoot/css/style.css>\n  </head>\n  <body>\n    <h1>Support Contact Info</h1>\n    <footer><a href=@@webRoot>Home</a></footer>\n  </body>\n  </body>\n</html>\n```\n\nresult:\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <link type=stylesheet src=../../css/style.css>\n  </head>\n  <body>\n    <h1>Support Contact Info</h1>\n    <footer><a href=../..>Home</a></footer>\n  </body>\n  </body>\n</html>\n```\n\n### License\nMIT\n\n[npm-img]: https://img.shields.io/npm/v/gulp-file-include.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/gulp-file-include\n[travis-img]: https://img.shields.io/travis/haoxins/gulp-file-include.svg?style=flat-square\n[travis-url]: https://travis-ci.org/haoxins/gulp-file-include\n[coveralls-img]: https://img.shields.io/coveralls/coderhaoxin/gulp-file-include.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/coderhaoxin/gulp-file-include?branch=master\n[license-img]: http://img.shields.io/badge/license-MIT-green.svg?style=flat-square\n[license-url]: http://opensource.org/licenses/MIT\n[david-img]: https://img.shields.io/david/coderhaoxin/gulp-file-include.svg?style=flat-square\n[david-url]: https://david-dm.org/coderhaoxin/gulp-file-include\n[gitter-img]: https://badges.gitter.im/Join%20Chat.svg\n[gitter-url]: https://gitter.im/coderhaoxin/gulp-file-include?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge\n"
  },
  {
    "path": "example/a/a1.txt",
    "content": "this is a1\n\n// include a2\n@@include('./a2.txt')\n"
  },
  {
    "path": "example/a/a2.txt",
    "content": "this is a2\n\n// include b1\n@@include('../b/b1.txt')\n"
  },
  {
    "path": "example/b/b1.txt",
    "content": "this is b1\n\n// include b2\n@@include('./b2.txt')\n"
  },
  {
    "path": "example/b/b2.txt",
    "content": "this is b2"
  },
  {
    "path": "example/c/c.txt",
    "content": "this is loop @@number"
  },
  {
    "path": "example/conditional.txt",
    "content": "this is conditional\n\nFlatten object \"@@obj\"\n@@if(typeof context.obj === 'object') {\n  Flatten variable \"@@obj.obj_param\"\n}\nDefined in parent \"@@param\"\nContext variable \"@@name\"\n"
  },
  {
    "path": "example/gulpfile.js",
    "content": "'use strict'\n\nconst fileinclude = require('..')\nconst gulp = require('gulp')\n\ngulp.task('include', () => {\n  gulp.src(['index.txt'])\n    .pipe(fileinclude({\n      prefix: '@@',\n      basepath: '@file',\n      context: {\n        name: 'example'\n      }\n    }))\n    .pipe(gulp.dest('./result'))\n})\n"
  },
  {
    "path": "example/index.txt",
    "content": "index\n\n@@include('a/a1.txt')\n\n@@name\n\n@@if (context.name === 'example') {\n  @@include('conditional.txt', {\n    \"param\": \"success\",\n    \"obj\": {\n      \"obj_param\": \"flatten param\"\n    }\n  })\n  @@include('conditional.txt', {\n    \"param\": \"success too\"\n  })\n\n  Defined in include @@param\n}\n\n@@loop('c/c.txt', [\n  { \"number\": 1 },\n  { \"number\": 2 },\n  { \"number\": 3 }\n])\n"
  },
  {
    "path": "example/result/index.txt",
    "content": "index\n\nthis is a1\n\n// include a2\nthis is a2\n\n// include b1\nthis is b1\n\n// include b2\nthis is b2\n\n\n\n\nexample\n\n\n  this is conditional\n\nFlatten object \"@@obj\"\n\n  Flatten variable \"flatten param\"\n\nDefined in parent \"success\"\nContext variable \"example\"\n\n  this is conditional\n\nFlatten object \"@@obj\"\n\nDefined in parent \"success too\"\nContext variable \"example\"\n\n\n  Defined in include @@param\n\n\nthis is loop 1this is loop 2this is loop 3\n"
  },
  {
    "path": "lib/indent.js",
    "content": "module.exports = function(src, index, dest) {\n  var indent = ''\n  var valid = false\n\n  while (src[index -= 1] == 0) { // eslint-disable-line\n    if (src[index] === '\\n') {\n      valid = true\n      break\n    }\n    indent = src[index] + indent\n  }\n\n  if (valid) {\n    dest = dest.split('\\n').map(function(str, i) {\n      return str == 0 || i === 0 ? str : (indent + str) // eslint-disable-line\n    }).join('\\n')\n  }\n\n  return dest\n}\n"
  },
  {
    "path": "lib/index.js",
    "content": "'use strict'\n\nconst replaceOperator = require('./replace-operator')\nconst replaceFunction = require('./replace-function')\nconst replaceVariable = require('./replace-variable')\nconst concat = require('concat-stream')\nconst setIndent = require('./indent')\nconst through = require('through2')\nconst Vinyl = require('vinyl')\nconst PluginError = require('plugin-error')\nconst extend = require('extend')\nconst path = require('path')\nconst fs = require('fs')\nconst JSON5 = require('json5')\n\nmodule.exports = function(opts) {\n  if (typeof opts === 'string') {\n    opts = {prefix: opts}\n  }\n\n  opts = extend({}, {\n    basepath: '@file',\n    prefix: '@@',\n    suffix: '',\n    context: {},\n    filters: false,\n    indent: false\n  }, opts)\n\n  if (opts.basepath !== '@file') {\n    opts.basepath = opts.basepath === '@root' ? process.cwd() : path.resolve(opts.basepath)\n  }\n\n  var customWebRoot = !!opts.context.webRoot\n  var includeOnceFiles = {};\n\n  function fileInclude(file, enc, cb) {\n    if (!customWebRoot) {\n      // built-in webRoot variable, example usage: <link rel=stylesheet href=@@webRoot/style.css>\n      opts.context.webRoot =\n        path.relative(path.dirname(file.path), file.base).replace(/\\\\/g, '/') || '.'\n    }\n\n    if (file.isNull()) {\n      cb(null, file)\n    } else if (file.isStream()) {\n      file.contents.pipe(concat(function(data) {\n        try {\n          data = include(file, String(data))\n          cb(null, data)\n        } catch (e) {\n          cb(new PluginError('gulp-file-include', e.message))\n        }\n      }))\n    } else if (file.isBuffer()) {\n      try {\n        file = include(file, String(file.contents))\n        cb(null, file)\n      } catch (e) {\n        cb(new PluginError('gulp-file-include', e.message))\n      }\n    }\n  }\n\n  return through.obj(fileInclude)\n\n  /**\n   * utils\n   */\n  function stripCommentedIncludes(content, opts) {\n    // remove single line html comments that use the format: <!-- @@include() -->\n    var regex = new RegExp('<!--(.*)' + opts.prefix + '[ ]*include([\\\\s\\\\S]*?)[ ]*' + opts.suffix + '-->', 'g')\n    return content.replace(regex, '')\n  }\n\n  function include(file, text, data, sourceFile = '') {\n    var filebase = opts.basepath === '@file' ? path.dirname(file.path) : opts.basepath\n    var currentFilename = path.resolve(file.base, file.path)\n\n    data = extend(true, {}, opts.context, data || {})\n    data.content = text\n\n    text = stripCommentedIncludes(text, opts)\n    text = replaceOperator(text, {\n      prefix: opts.prefix,\n      suffix: opts.suffix,\n      name: 'if',\n      handler: conditionalHandler,\n      sourceFile: sourceFile\n    })\n    text = replaceOperator(text, {\n      prefix: opts.prefix,\n      suffix: opts.suffix,\n      name: 'for',\n      handler: forHandler,\n      sourceFile: sourceFile\n    })\n    text = replaceVariable(text, data, opts)\n    text = replaceFunction(text, {\n      prefix: opts.prefix,\n      suffix: opts.suffix,\n      name: 'include_once',\n      handler: includeOnceHandler,\n      sourceFile: sourceFile\n    })\n    text = replaceFunction(text, {\n      prefix: opts.prefix,\n      suffix: opts.suffix,\n      name: 'include',\n      handler: includeHandler,\n      sourceFile: sourceFile\n    })\n    text = replaceFunction(text, {\n      prefix: opts.prefix,\n      suffix: opts.suffix,\n      name: 'loop',\n      handler: loopHandler,\n      sourceFile: sourceFile\n    })\n\n    function conditionalHandler(inst) {\n      try {\n        var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call(data) // eslint-disable-line\n      } catch (error) {\n        throw new Error(error.message + ': ' + inst.args)\n      }\n\n      return condition ? inst.body : ''\n    }\n\n    function forHandler(inst) {\n      var forLoop = 'for' + inst.args + ' { result+=`' + inst.body + '`; }'\n      var condition = 'var context = this; with (context) { var result=\"\"; ' + forLoop + ' return result; }'\n      try {\n        var result = new Function(condition).call(data) // eslint-disable-line\n      } catch (error) {\n        throw new Error(error.message + ': ' + forLoop)\n      }\n\n      return result\n    }\n\n    function includeOnceHandler(inst) {\n      var args = /[^)\"']*[\"']([^\"']*)[\"'](,\\s*({[\\s\\S]*})){0,1}\\s*/.exec(inst.args)\n      if (args) {\n        if (typeof includeOnceFiles[inst.sourceFile] === 'undefined') {\n          includeOnceFiles[inst.sourceFile] = [];\n        }\n        if (includeOnceFiles[inst.sourceFile].indexOf(args[1]) === -1) {\n          includeOnceFiles[inst.sourceFile].push(args[1]);\n          return includeHandler(inst)\n        } else {\n          return '';\n        }\n      } \n    }\n\n    function includeHandler(inst) {\n      var args = /[^)\"']*[\"']([^\"']*)[\"'](,\\s*({[\\s\\S]*})){0,1}\\s*/.exec(inst.args)\n\n      if (args) {\n        var includePath = path.resolve(filebase, args[1])\n        // for checking if we are not including the current file again\n        if (currentFilename.toLowerCase() === includePath.toLowerCase()) {\n          throw new Error('recursion detected in file: ' + currentFilename)\n        }\n\n        var includeContent = fs.readFileSync(includePath, 'utf-8')\n\n        if (opts.indent) {\n          includeContent = setIndent(inst.before, inst.before.length, includeContent)\n        }\n\n        // need to double each `$` to escape it in the `replace` function\n        // includeContent = includeContent.replace(/\\$/gi, '$$$$');\n\n        // apply filters on include content\n        if (typeof opts.filters === 'object') {\n          includeContent = applyFilters(includeContent, args.input)\n        }\n\n        var recFile = new Vinyl({\n          cwd: process.cwd(),\n          base: file.base,\n          path: includePath,\n          contents: Buffer.from(includeContent)\n        })\n\n        recFile = include(recFile, includeContent, args[3] ? JSON5.parse(args[3]) : {}, inst.sourceFile != '' ? inst.sourceFile : currentFilename)\n\n        return String(recFile.contents)\n      }\n    }\n\n    function loopHandler(inst) {\n      var args = /[^)\"']*[\"']([^\"']*)[\"'](,\\s*([\\s\\S]*())){0,1}\\s*/.exec(inst.args)\n      var arr = []\n\n      if (args) {\n        // loop array in the json file\n        if (args[3].match(/^('|\")[^']|[^\"]('|\")$/)) {\n          // clean filename var and define path\n          var jsonPath = args[3].replace(/^('|\")/, '').replace(/('|\")$/, '')\n          var jsonfile = path.join(file.base, jsonPath)\n          // check if json file exists\n          if (fs.existsSync(jsonfile)) {\n            // make sure we are getting the updated version of the json file\n            delete require.cache[jsonfile]\n            arr = require(jsonfile)\n          } else {\n            return console.error('JSON file not exists:', jsonfile)\n          }\n        } else {\n          // loop array in the function\n          try {\n            arr = JSON5.parse(args[3])\n          } catch (err) {\n            return console.error(err, args[3])\n          }\n        }\n\n        if (arr) {\n          var includePath = path.resolve(filebase, args[1])\n          // for checking if we are not including the current file again\n          if (currentFilename.toLowerCase() === includePath.toLowerCase()) {\n            throw new Error('recursion detected in file: ' + currentFilename)\n          }\n\n          var includeContent = fs.readFileSync(includePath, 'utf-8')\n\n          if (opts.indent) {\n            includeContent = setIndent(inst.before, inst.before.length, includeContent)\n          }\n\n          // apply filters on include content\n          if (typeof opts.filters === 'object') {\n            includeContent = applyFilters(includeContent, args.input)\n          }\n\n          var recFile = new Vinyl({\n            cwd: process.cwd(),\n            base: file.base,\n            path: includePath,\n            contents: Buffer.from(includeContent)\n          })\n\n          var contents = ''\n\n          for (var i in arr) {\n            if (arr.hasOwnProperty(i)) {\n              var context = arr[i]\n              recFile = include(recFile, includeContent, args[3] ? context : {}, inst.sourceFile != '' ? inst.sourceFile : currentFilename)\n              // why handler dont reconize underscore?\n              // if (typeof context == 'object' && typeof context['_key'] == 'undefined') {\n              //   context['_key'] = i;\n              // }\n              contents += String(recFile.contents)\n            }\n          }\n        }\n        return contents\n      }\n    }\n\n    file.contents = Buffer.from(text)\n\n    return file\n  }\n\n  function applyFilters(includeContent, match) {\n    if (!match.match(/\\)+$/)) {\n      // nothing to filter return unchanged\n      return includeContent\n    }\n\n    // now get the ordered list of filters\n    var filterlist = match.split('(').slice(0, -1)\n    filterlist = filterlist.map(function(str) {\n      return opts.filters[str.trim()]\n    })\n\n    // compose them together into one function\n    var filter = filterlist.reduce(compose)\n\n    // check match for filter options object\n    var options = match.match('{([^}]*)}')\n\n    // and apply the composed function to the stringified content\n    if (options) {\n      options = JSON5.parse(options[0])\n      return filter(String(includeContent), options)\n    } else {\n      return filter(String(includeContent))\n    }\n  }\n}\n\nfunction compose(f, g) {\n  return function(x) {\n    return f(g(x))\n  }\n}\n"
  },
  {
    "path": "lib/replace-function.js",
    "content": "'use strict'\n\nconst balanced = require('balanced-match')\n\nmodule.exports = function(content, opts) {\n  var result = ''\n  var reStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '\\\\(')\n  var reEnd = new RegExp('^[ ]*' + opts.suffix)\n  var matchStart\n  var matchArg\n  var matchEnd\n  var safeStart\n  var before\n  var replacement\n\n  while (matchStart = reStart.exec(content)) { // eslint-disable-line\n    safeStart = matchStart.index + matchStart[0].length - 1\n\n    matchArg = balanced('(', ')', content.slice(safeStart))\n\n    if (matchArg && matchArg.start === 0) {\n      if (opts.suffix) {\n        matchEnd = reEnd.exec(matchArg.post)\n      }\n\n      matchEnd = matchEnd ? matchEnd.index + matchEnd[0].length : 0\n\n      if (!opts.suffix || matchEnd) {\n        before = content.slice(0, matchStart.index)\n        replacement = opts.handler({\n          before: before,\n          args: matchArg.body,\n          sourceFile: opts.sourceFile\n        })\n\n        if (replacement !== undefined) {\n          result += before + replacement.toString()\n          content = content.slice(safeStart + matchArg.end + 1 + matchEnd)\n          continue\n        }\n      }\n    }\n\n    result += content.slice(0, safeStart)\n    content = content.slice(safeStart)\n  }\n\n  result += content\n\n  return result\n}\n"
  },
  {
    "path": "lib/replace-operator.js",
    "content": "'use strict'\n\nconst balanced = require('balanced-match')\n\nmodule.exports = function parse(content, opts) {\n  var regexpStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '([^{}]*)\\\\{')\n  var regexpEnd = opts.suffix ? new RegExp('^\\\\s*' + opts.suffix) : false\n  var replacement\n  var result = ''\n  var matchStart\n  var matchBody\n  var matchEnd\n  var startEnd\n  var before\n\n  while (matchStart = regexpStart.exec(content)) { // eslint-disable-line\n    startEnd = matchStart.index + matchStart[0].length\n    matchBody = balanced('{', '}', content.slice(startEnd - 1))\n\n    if (matchBody && matchBody.start === 0) {\n      matchEnd = regexpEnd ? regexpEnd.exec(matchBody.post) : true\n\n      if (matchEnd) {\n        before = content.slice(0, matchStart.index)\n        matchEnd = regexpEnd ? matchEnd[0].length : 0\n        replacement = opts.handler({\n          before: before,\n          args: matchStart[1],\n          body: matchBody.body\n        })\n\n        if (replacement !== undefined) {\n          result += before + parse(replacement.toString(), opts)\n          content = content.slice(startEnd + matchBody.end + matchEnd)\n          continue\n        }\n      }\n    }\n\n    result += content.slice(0, startEnd)\n    content = content.slice(startEnd)\n  }\n\n  result += content\n\n  return result\n}\n"
  },
  {
    "path": "lib/replace-variable.js",
    "content": "'use strict'\n\nconst flatten = require('flatnest').flatten\n\nmodule.exports = function(content, data, opts) {\n  var prefix = opts.prefix + '[ ]*'\n  var suffix = opts.suffix ? '[ ]*' + opts.suffix : ''\n  data = flatten(data)\n  // sort keys by longest keys to iterate in that order\n  var keys = Object.keys(data).sort()\n  var i = keys.length - 1\n  var key\n\n  for (; ~i; i -= 1) {\n    key = keys[i]\n    content = content.replace(new RegExp(prefix + key + suffix, 'g'), data[key])\n  }\n\n  return content\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"gulp-file-include\",\n  \"version\": \"2.3.0\",\n  \"description\": \"A gulp plugin for file include\",\n  \"main\": \"lib/index.js\",\n  \"scripts\": {\n    \"lint\": \"eslint lib test/*.js --fix\",\n    \"test\": \"mocha -R spec -t 200 test/*.js\",\n    \"test-cov\": \"istanbul cover node_modules/.bin/_mocha -- -R dot -t 200 test/*.js\",\n    \"test-travis\": \"istanbul cover node_modules/.bin/_mocha --report lcovonly -- -R dot -t 200 test/*.js\"\n  },\n  \"repository\": \"haoxins/gulp-file-include\",\n  \"keywords\": [\n    \"gulpplugin\",\n    \"file\",\n    \"include\",\n    \"replace\",\n    \"gulp\",\n    \"plugin\"\n  ],\n  \"files\": [\n    \"lib\"\n  ],\n  \"author\": \"haoxin\",\n  \"contributors\": [\n    \"Bogdan Chadkin <trysound@yandex.ru>\",\n    \"Arthur Araújo <webarthur@gmail.com>\"\n  ],\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"balanced-match\": \"^1.0.0\",\n    \"concat-stream\": \"^2.0.0\",\n    \"extend\": \"^3.0.2\",\n    \"flatnest\": \"^1.0.0\",\n    \"json5\": \"^2.1.3\",\n    \"plugin-error\": \"^1.0.1\",\n    \"through2\": \"^4.0.2\",\n    \"vinyl\": \"^2.2.1\"\n  },\n  \"devDependencies\": {\n    \"eslint-config-ok\": \"github:haoxins/eslint-config\",\n    \"gulp\": \"^4.0.2\",\n    \"istanbul\": \"^0.4.5\",\n    \"markdown\": \"^0.5.0\",\n    \"mocha\": \"^8.2.1\",\n    \"should\": \"^13.2.3\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"ok\"\n    ]\n  }\n}\n"
  },
  {
    "path": "test/.editorconfig",
    "content": "[*]\ninsert_final_newline = false\n"
  },
  {
    "path": "test/edge-case.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  describe('# edge cases', () => {\n    it('should escape included content to avoid recursive includes', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-edge-case/index.html',\n        contents: fs.createReadStream('test/fixtures-edge-case/index.html')\n      })\n      var expected = fs.readFileSync('test/fixtures-edge-case/result.html', 'utf8')\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(expected)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('should work without trailing newline', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-edge-case/without-trailing-newline.txt',\n        contents: fs.createReadStream('test/fixtures-edge-case/without-trailing-newline.txt')\n      })\n      var expected = fs.readFileSync('test/fixtures-edge-case/without-trailing-newline-result.txt', 'utf8')\n\n      var stream = fileIncludePlugin()\n      stream.on('data', function(newFile) {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(expected)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('should skip commented includes', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-edge-case/commented-inclusion.html',\n        contents: fs.createReadStream('test/fixtures-edge-case/commented-inclusion.html')\n      })\n      var expected = fs.readFileSync('test/fixtures-edge-case/commented-inclusion-result.html', 'utf8').replace(/\\s/g, '')\n\n      var stream = fileIncludePlugin()\n\n      stream.on('data', newFile => {\n        var inputString = String(newFile.contents).replace(/\\s/g, '')\n\n        inputString.should.equal(expected)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('should give an error on recursive includes', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-edge-case/recursion.html',\n        contents: fs.createReadStream('test/fixtures-edge-case/recursion.html')\n      })\n\n      var stream = fileIncludePlugin()\n\n      stream.on('error', err => {\n        should.exist(err)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    // it('should give an error on circular recursive includes', function(done) {\n    //   var file = new Vinyl({\n    //     path: 'test/fixtures-edge-case/a.html',\n    //     contents: fs.createReadStream('test/fixtures-edge-case/a.html')\n    //   });\n\n    //   var stream = fileIncludePlugin();\n\n    //   stream.on('error', function(err) {\n    //     should.exist(err);\n    //     done();\n    //   });\n\n    //   stream.write(file);\n    //   stream.end();\n    // });\n  })\n})\n"
  },
  {
    "path": "test/error.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst fs = require('fs')\nconst os = require('os')\n\nrequire('should')\n\ndescribe('## error', () => {\n  it('# if statement', done => {\n    var file = new Vinyl({\n      path: 'test/fixtures-error/if.html',\n      contents: fs.readFileSync('test/fixtures-error/if.html')\n    })\n\n    var stream = fileIncludePlugin({\n      prefix: '@@',\n      basepath: '@root'\n    })\n    stream.on('error', error => {\n      error.message.should.equal('invalid is not defined:  (invalid === true) ')\n      done()\n    })\n    stream.write(file)\n    stream.end()\n  })\n\n  it('# for statement', done => {\n    var file = new Vinyl({\n      path: 'test/fixtures-error/if.html',\n      contents: fs.readFileSync('test/fixtures-error/for.html')\n    })\n\n    var stream = fileIncludePlugin({\n      prefix: '@@',\n      basepath: '@root'\n    })\n    stream.on('error', error => {\n      error.message.should.equal('invalid is not defined: for (var i = 0; i < invalid.length; i++)  { result+=`' + os.EOL + '  <label>`+invalid[i]+`</label>' + os.EOL + '  `; }')\n      done()\n    })\n    stream.write(file)\n    stream.end()\n  })\n})\n"
  },
  {
    "path": "test/filters.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst markdown = require('markdown')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures/result.html', 'utf8')\n\n  describe('# options - filters', () => {\n    it('file - filters: markdown', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-markdown.html',\n        contents: fs.readFileSync('test/fixtures/index-markdown.html')\n      })\n\n      var stream = fileIncludePlugin({\n        filters: {\n          markdown: markdown.parse\n        }\n      })\n\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - filters: markdown', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-markdown.html',\n        contents: fs.createReadStream('test/fixtures/index-markdown.html')\n      })\n\n      var stream = fileIncludePlugin({\n        filters: {\n          markdown: markdown.parse\n        }\n      })\n\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - filters: markdown & rot13', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-markdown-rot13.html',\n        contents: fs.readFileSync('test/fixtures/index-markdown-rot13.html')\n      })\n\n      var stream = fileIncludePlugin({\n        filters: {\n          markdown: markdown.parse,\n          rot13: rot13\n        }\n      })\n\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - filters: markdown & rot13', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-markdown-rot13.html',\n        contents: fs.createReadStream('test/fixtures/index-markdown-rot13.html')\n      })\n\n      var stream = fileIncludePlugin({\n        filters: {\n          markdown: markdown.parse,\n          rot13: rot13\n        }\n      })\n\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - filters: custom filter handler options', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-handler-options.html',\n        contents: fs.createReadStream('test/fixtures/index-handler-options.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@file',\n        filters: {\n          handler: function(content, options) {\n            should.exist(options)\n            should.exist(options.age)\n            should.exist(options.name)\n\n            // other handler code or\n            // template engine compiling here, i.e.:\n            // var template = Handlebars.compile(content);\n            // return template(options);\n\n            return content\n          }\n        }\n      })\n\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n\nfunction rot13(str) {\n  // original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)\n  return (str + '').replace(/[a-z]/gi, s => {\n    return String.fromCharCode(\n      s.charCodeAt(0) + (s.toLowerCase() < 'n' ? 13 : -13)\n    )\n  })\n}\n"
  },
  {
    "path": "test/fixtures/arr-result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <h1>view</h1>\n  \n<label>haoxin</label>\n\n<label>12345</label>\n\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/arr.html",
    "content": "@@for (var i = 0; i < name.length; i++) {\n<label>`+name[i]+`</label>\n}"
  },
  {
    "path": "test/fixtures/index-01.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('view.html')\n  @@ if(true) {@@include('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })}\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-02.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('fixtures/view.html')\n  @@include('./fixtures/var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-03.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('./test/fixtures/view.html')\n  @@include('test/fixtures/var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-04.js",
    "content": "(function(okanjo) {\n\n  okanjo.mvc.registerCss('main', '@@include(jsStringEscape(\"./test/fixtures/view.html\"))', {\n    id: 'okanjo-test-main'\n  });\n\n  okanjo.mvc.registerCss('main', '@@include(jsStringEscape(\"test/fixtures/var.html\", { \"name\": \"haoxin\", \"age\": 12345 }))', {\n    id: 'okanjo-test-main'\n  });\n\n})(okanjo);\n"
  },
  {
    "path": "test/fixtures/index-05.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('view.html')\n  @@include('./arr.html', {\n    \"name\": [\"haoxin\", 12345]\n  })\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-handler-options.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('view.html')\n  @@include(handler('var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  }))\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-markdown-rot13.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include(markdown(rot13('view.rot13.md')))\n  @@include(rot13('./var.rot13.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  }))\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/index-markdown.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@  include(markdown('view.md'))\n  @@include('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <h1>view</h1>\n  <label>haoxin</label>\n<label>12345</label>\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/result.js",
    "content": "(function(okanjo) {\n\n  okanjo.mvc.registerCss('main', '<h1>view</h1>', {\n    id: 'okanjo-test-main'\n  });\n\n  okanjo.mvc.registerCss('main', '<label>haoxin</label>\n<label>12345</label>', {\n    id: 'okanjo-test-main'\n  });\n\n})(okanjo);\n"
  },
  {
    "path": "test/fixtures/sameprefix-result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <a href=\"http://drewlustro.com\">Cool Link</a>\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/sameprefix-var.html",
    "content": "<a href=\"@@title_link\">@@title</a>"
  },
  {
    "path": "test/fixtures/sameprefix.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('./sameprefix-var.html', {\n    \"title\": \"Cool Link\",\n    \"title_link\": \"http://drewlustro.com\"\n  })\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures/var.html",
    "content": "<label>@@name</label>\n<label>@@ age</label>"
  },
  {
    "path": "test/fixtures/var.rot13.html",
    "content": "<ynory>@@anzr</ynory>\n<ynory>@@ntr</ynory>"
  },
  {
    "path": "test/fixtures/view.html",
    "content": "<h1>view</h1>"
  },
  {
    "path": "test/fixtures/view.md",
    "content": "view\n====\n"
  },
  {
    "path": "test/fixtures/view.rot13.md",
    "content": "ivrj\n====\n"
  },
  {
    "path": "test/fixtures-edge-case/a.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <!-- include b, that includes a again -->\n  @@include('b.html')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/b.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <!-- includes a again (nested recursion) -->\n  @@include('a.html')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/commented-inclusion-result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <!-- this line stays, but the include should be skipped -->\n\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/commented-inclusion.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <!-- this line stays, but the include should be skipped -->\n  <!-- @@include('recursion.html') -->\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/dangerous.txt",
    "content": "This: $& should not trigger recursive includes.\n"
  },
  {
    "path": "test/fixtures-edge-case/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('dangerous.txt')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/recursion.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <!-- silly recursion, should give an error -->\n  @@include('recursion.html')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  This: $& should not trigger recursive includes.\n\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-edge-case/without-trailing-newline-result.txt",
    "content": "hello world!\nThis: $& should not trigger recursive includes.\nwithout trailing newline\nThis: $& should not trigger recursive includes.\n!@\n!!This: $& should not trigger recursive includes.\n!@\nbye\n"
  },
  {
    "path": "test/fixtures-edge-case/without-trailing-newline.txt",
    "content": "hello world!\n@@include('dangerous.txt')without trailing newline\n@@include('dangerous.txt')!@\n!!@@include('dangerous.txt')!@\nbye\n"
  },
  {
    "path": "test/fixtures-error/for.html",
    "content": "@@for (var i = 0; i < invalid.length; i++) {\n  <label>`+invalid[i]+`</label>\n  }"
  },
  {
    "path": "test/fixtures-error/if.html",
    "content": "@@if (invalid === true) {\n  <h1>a</h1>\n}"
  },
  {
    "path": "test/fixtures-flatten/index.html",
    "content": "<label>@@obj</label>\n<strong>@@obj.param1</strong>\n<strong>@@obj.param2</strong>"
  },
  {
    "path": "test/fixtures-flatten/result.html",
    "content": "<label>@@obj</label>\n<strong>value1</strong>\n<strong>value2</strong>"
  },
  {
    "path": "test/fixtures-indent/index.html",
    "content": "<h1>Hello</h1>\n\n<div class=\"section\">\n  <span>Sub</span>\n  //= include('sub.html')\n</div>\n"
  },
  {
    "path": "test/fixtures-indent/result.html",
    "content": "<h1>Hello</h1>\n\n<div class=\"section\">\n  <span>Sub</span>\n  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam in nisi blanditiis!</p>\n  <div>\n    <p>Lorem ipsum dolor sit amet, consectetur.</p>\n    <small>Am Dig Bo</small>\n\n  </div>\n</div>\n"
  },
  {
    "path": "test/fixtures-indent/sub-sub.html",
    "content": "<small>Am Dig Bo</small>\n"
  },
  {
    "path": "test/fixtures-indent/sub.html",
    "content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam in nisi blanditiis!</p>\n<div>\n  <p>Lorem ipsum dolor sit amet, consectetur.</p>\n  //= include('sub-sub.html')\n</div>"
  },
  {
    "path": "test/fixtures-nested/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<strong>twitter.com/include</strong>\n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested/var.html",
    "content": "<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>"
  },
  {
    "path": "test/fixtures-nested-once/index-twice.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include_once('var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  @@include_once('var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested-once/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include_once('var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345,\n    \"socials\": {\n      \"fb\": \"facebook.com/include\",\n      \"tw\": \"twitter.com/include\"\n    }\n  })\n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested-once/result-twice.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<strong>twitter.com/include</strong>\n  \n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested-once/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  <label>haoxin</label>\n<label>12345</label>\n<strong>facebook.com/include</strong>\n<strong>twitter.com/include</strong>\n  </body>\n</html>"
  },
  {
    "path": "test/fixtures-nested-once/var.html",
    "content": "<label>@@name</label>\n<label>@@age</label>\n<strong>@@socials.fb</strong>\n<strong>@@socials.tw</strong>"
  },
  {
    "path": "test/fixtures-operator/index.html",
    "content": "\n@@if (content.indexOf('>a') > -1) {\n  <h1>a</h1>\n}\n\n@@if(content.indexOf('>a') > -1){\n  {<h1>a</h1>}\n}\n\n@@if content.indexOf('>a') > -1 {\n  <h1>a</h1>\n}\n\n@@if (content.length > 888) {\n  <h2>b</h2>\n}\n\n@@if (name === 'c') {\n@@if (name === 'c') {\n  <h3>c</h3>\n}\n}\n\n@@ if (name === 'c' && context.title === 'haoxin') {\n  <h3>c</h3>\n}\n\n@@  if (name === 'c' && context.title !== 'haoxin') {\n  <h3>c</h3>\n}\n\n@@if(name === 'c') {\n"
  },
  {
    "path": "test/fixtures-operator/result-index.html",
    "content": "\n\n  <h1>a</h1>\n\n\n\n  {<h1>a</h1>}\n\n\n\n  <h1>a</h1>\n\n\n\n\n\n\n  <h3>c</h3>\n\n\n\n\n\n\n  <h3>c</h3>\n\n\n@@if(name === 'c') {\n"
  },
  {
    "path": "test/fixtures-operator/result-suffix.html",
    "content": "\n\n  <h1>a</h1>\n\n\n\n  {<h1>a</h1>}\n\n\n\n  <h1>a</h1>\n\n\n\n\n\n\n  <h3>c</h3>\n\n\n\n\n\n\n  <h3>c</h3>\n\n\n@@if(name === 'c') {\n\n}\n\n@@if(name === 'c') {\n"
  },
  {
    "path": "test/fixtures-operator/suffix.html",
    "content": "\n@@if (content.indexOf('>a') > -1) {\n  <h1>a</h1>\n}##\n\n@@if(content.indexOf('>a') > -1){\n  {<h1>a</h1>}\n} ##\n\n@@if content.indexOf('>a') > -1 {\n  <h1>a</h1>\n}\n##\n\n@@if (content.length > 888) {\n  <h2>b</h2>\n}\n\n##\n\n@@if (name === 'c') {\n@@if (name === 'c') {\n  <h3>c</h3>\n}##\n}\n##\n\n@@ if (name === 'c' && context.title === 'haoxin') {\n  <h3>c</h3>\n}##\n\n@@  if (name === 'c' && context.title !== 'haoxin') {\n  <h3>c</h3>\n}##\n\n@@if(name === 'c') {\n\n}\n\n@@if(name === 'c') {\n"
  },
  {
    "path": "test/fixtures-recursion/index.txt",
    "content": "this is index\n\n@@include('./sub/a.txt')\n@@include('./sub/b.txt')\n\n@@include('./var.txt', {\n  \"name\": \"from index.txt\"\n})\n"
  },
  {
    "path": "test/fixtures-recursion/result.txt",
    "content": "this is index\n\nthis is a.txt\nthis is b.txt\nname is: from b.txt\n\n\n\nthis is b.txt\nname is: from b.txt\n\n\n\nname is: from index.txt\n\n"
  },
  {
    "path": "test/fixtures-recursion/sub/a.txt",
    "content": "this is a.txt\n@@include('./b.txt')\n"
  },
  {
    "path": "test/fixtures-recursion/sub/b.txt",
    "content": "this is b.txt\n@@include('../var.txt', {\n  \"name\": \"from b.txt\"\n})\n"
  },
  {
    "path": "test/fixtures-recursion/var.txt",
    "content": "name is: @@name\n"
  },
  {
    "path": "test/fixtures-suffix/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n  @@include('../fixtures/view.html')@@\n  @@include('./var.html', {\n    \"name\": \"haoxin\",\n    \"age\": 12345\n  })@@\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-suffix/var.html",
    "content": "<label>@@name@@</label>\n<label>@@age@@</label>"
  },
  {
    "path": "test/fixtures-variable/index-suffix.html",
    "content": "<ul>\n  <li>\n    <var>//=   param1  @@</var>\n  </li>\n  <li>\n    <var>//= obj.param1@@</var>\n  </li>\n  <li>\n    <var>//= obj.param2@@</var>\n  </li>\n  <li>\n    <var>//=param2 @@</var>\n  </li>\n</ul>\n"
  },
  {
    "path": "test/fixtures-variable/index.html",
    "content": "<ul>\n  <li>\n    <var>//=   param1</var>\n  </li>\n  <li>\n    <var>//= obj.param1</var>\n  </li>\n  <li>\n    <var>//= obj.param2</var>\n  </li>\n  <li>\n    <var>//=param2</var>\n  </li>\n</ul>\n"
  },
  {
    "path": "test/fixtures-variable/result.html",
    "content": "<ul>\n  <li>\n    <var>value1</var>\n  </li>\n  <li>\n    <var>o1</var>\n  </li>\n  <li>\n    <var>o2</var>\n  </li>\n  <li>\n    <var>value2</var>\n  </li>\n</ul>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/html-head.html",
    "content": "<head>\n  <link type=stylesheet src=@@webRoot/style.css>\n</head>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  @@include('html-head.html')\n  <body>\n    <h1>Page</h1>\n    <a href=@@webRoot/about>About</a>\n    @@include('sub/home-link.html')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n  <link type=stylesheet src=../../style.css>\n</head>\n\n  <body>\n    <h1>Page</h1>\n    <a href=../../about>About</a>\n    <a href=../..>Home</a>\n\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/sub/home-link.html",
    "content": "<a href=@@webRoot>Home</a>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/sub/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  @@include('../html-head.html')\n  <body>\n    <h1>Sub Page</h1>\n    <a href=@@webRoot/about>About</a>\n    @@include('home-link.html')\n  </body>\n</html>\n"
  },
  {
    "path": "test/fixtures-webroot-variable/sub/result.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n  <link type=stylesheet src=../../../style.css>\n</head>\n\n  <body>\n    <h1>Sub Page</h1>\n    <a href=../../../about>About</a>\n    <a href=../../..>Home</a>\n\n  </body>\n</html>\n"
  },
  {
    "path": "test/flatten.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures-flatten/result.html', 'utf8')\n\n  describe('# flatten variables', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-flatten/index.html',\n        contents: fs.readFileSync('test/fixtures-flatten/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        context: {\n          obj: {\n            'param1': 'value1',\n            'param2': 'value2'\n          }\n        }\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-flatten/index.html',\n        contents: fs.createReadStream('test/fixtures-flatten/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        context: {\n          obj: {\n            'param1': 'value1',\n            'param2': 'value2'\n          }\n        }\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/indent.js",
    "content": "'use strict'\n\nconst setIndent = require('../lib/indent')\n\nrequire('should')\n\ndescribe('## indent', () => {\n  it('# basic', done => {\n    setIndent(\n      ' content \\n\\t  start',\n      13,\n      'some other \\n content').should.equal('some other \\n\\t   content')\n    done()\n  })\n\n  it('# basic with \\\\r\\\\n newlines', done => {\n    setIndent(\n      ' content \\r\\n\\t  start',\n      14,\n      '\\r\\n\\r\\nsome other \\r\\n content').should.equal('\\r\\n\\r\\n\\t  some other \\r\\n\\t   content')\n    done()\n  })\n\n  it('# with non-space char', done => {\n    setIndent(\n      ' content \\n\\t g start',\n      14,\n      '\\n\\nsome other \\n content').should.equal('\\n\\nsome other \\n content')\n    done()\n  })\n\n  it('# with non-space char and \\\\r\\\\n newlines', done => {\n    setIndent(\n      ' content \\r\\n\\t g start',\n      15,\n      '\\r\\n\\r\\nsome other \\r\\n content').should.equal('\\r\\n\\r\\nsome other \\r\\n content')\n    done()\n  })\n})\n"
  },
  {
    "path": "test/index.js",
    "content": "\n'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures/result.html', 'utf8')\n  var resultJS = fs.readFileSync('test/fixtures/result.js', 'utf8')\n  var resultSamePrefix = fs.readFileSync('test/fixtures/sameprefix-result.html', 'utf8')\n  var resultArr = fs.readFileSync('test/fixtures/arr-result.html', 'utf8')\n\n  describe('# default', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.readFileSync('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.createReadStream('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# options - basepath', () => {\n    it('file - basepath: @file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.readFileSync('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: @file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.createReadStream('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-03.html',\n        contents: fs.readFileSync('test/fixtures/index-03.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-03.html',\n        contents: fs.createReadStream('test/fixtures/index-03.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - basepath: dir', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-02.html',\n        contents: fs.readFileSync('test/fixtures/index-02.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: __dirname\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: dir', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-02.html',\n        contents: fs.createReadStream('test/fixtures/index-02.html')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: __dirname\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# options - prefix, basepath', () => {\n    it('file - basepath: @file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.readFileSync('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: @file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-01.html',\n        contents: fs.createReadStream('test/fixtures/index-01.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-03.html',\n        contents: fs.readFileSync('test/fixtures/index-03.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-03.html',\n        contents: fs.createReadStream('test/fixtures/index-03.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('file - basepath: dir', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-02.html',\n        contents: fs.readFileSync('test/fixtures/index-02.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: __dirname\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: dir', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-02.html',\n        contents: fs.createReadStream('test/fixtures/index-02.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: __dirname\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# options - suffix', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-suffix/index.html',\n        contents: fs.readFileSync('test/fixtures-suffix/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        suffix: '@@'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents);\n        // TODO\n        (String(newFile.contents) === result).should.equal(true)\n        // String(newFile.contents).should.equal(result);\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-suffix/index.html',\n        contents: fs.createReadStream('test/fixtures-suffix/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        suffix: '@@'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents);\n        // TODO\n        (String(newFile.contents) === result).should.equal(true)\n        // String(newFile.contents).should.equal(result);\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# vars - same key prefix', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/sameprefix.html',\n        contents: fs.readFileSync('test/fixtures/sameprefix.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultSamePrefix)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/sameprefix.html',\n        contents: fs.createReadStream('test/fixtures/sameprefix.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultSamePrefix)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# aggressive regex', () => {\n    it('file - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-04.js',\n        contents: fs.readFileSync('test/fixtures/index-04.js')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n        String(newFile.contents).should.equal(resultJS)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream - basepath: @root', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-04.js',\n        contents: fs.createReadStream('test/fixtures/index-04.js')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '@@',\n        basepath: '@root'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n        String(newFile.contents).should.equal(resultJS)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# for statement', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-05.html',\n        contents: fs.readFileSync('test/fixtures/index-05.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultArr)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures/index-05.html',\n        contents: fs.createReadStream('test/fixtures/index-05.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultArr)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/nested-once.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('../lib')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures-nested-once/result.html', 'utf8')\n  var resultTwice = fs.readFileSync('test/fixtures-nested-once/result-twice.html', 'utf8')\n\n  describe('# nested once arguments', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested-once/index.html',\n        contents: fs.readFileSync('test/fixtures-nested-once/index.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested-once/index.html',\n        contents: fs.createReadStream('test/fixtures-nested-once/index.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n\n  describe('# nested once arguments twice', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested-once/index-twice.html',\n        contents: fs.readFileSync('test/fixtures-nested-once/index-twice.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultTwice)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested-once/index-twice.html',\n        contents: fs.createReadStream('test/fixtures-nested-once/index-twice.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(resultTwice)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/nested.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures-nested/result.html', 'utf8')\n\n  describe('# nested arguments', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested/index.html',\n        contents: fs.readFileSync('test/fixtures-nested/index.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-nested/index.html',\n        contents: fs.createReadStream('test/fixtures-nested/index.html')\n      })\n\n      var stream = fileIncludePlugin()\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/operator.js",
    "content": "'use strict'\n\nconst parse = require('../lib/replace-operator')\nconst fs = require('fs')\n\nrequire('should')\n\ndescribe('## operator', () => {\n  it('# basic usage', done => {\n    var result = fs.readFileSync('test/fixtures-operator/result-index.html', 'utf-8')\n    var index = fs.readFileSync('test/fixtures-operator/index.html', 'utf-8')\n\n    parse(index, {\n      prefix: '@@',\n      suffix: '',\n      name: 'if',\n      handler: inst => {\n        var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call({ // eslint-disable-line\n          content: index,\n          name: 'c'\n        })\n\n        return condition ? inst.body : ''\n      }\n    }).should.equal(result)\n\n    done()\n  })\n\n  it('# with suffix', done => {\n    var result = fs.readFileSync('test/fixtures-operator/result-suffix.html', 'utf-8')\n    var index = fs.readFileSync('test/fixtures-operator/suffix.html', 'utf-8')\n\n    parse(index, {\n      name: 'if',\n      prefix: '@@',\n      suffix: '##',\n      handler: inst => {\n        var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call({ // eslint-disable-line\n          content: index,\n          name: 'c'\n        })\n\n        return condition ? inst.body : ''\n      }\n    }).should.equal(result)\n\n    done()\n  })\n})\n"
  },
  {
    "path": "test/plugin-indent.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## gulp-file-include', () => {\n  var result = fs.readFileSync('test/fixtures-indent/result.html', 'utf-8')\n\n  describe('# indent', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-indent/index.html',\n        contents: fs.readFileSync('test/fixtures-indent/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '//=',\n        indent: true\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-indent/index.html',\n        contents: fs.createReadStream('test/fixtures-indent/index.html')\n      })\n\n      var stream = fileIncludePlugin({\n        prefix: '//=',\n        indent: true\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/recursion.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## recursion include', () => {\n  var result = fs.readFileSync('test/fixtures-recursion/result.txt', 'utf8')\n\n  describe('# basepath: @file', () => {\n    it('file', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-recursion/index.txt',\n        contents: fs.readFileSync('test/fixtures-recursion/index.txt')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n\n    it('stream', done => {\n      var file = new Vinyl({\n        path: 'test/fixtures-recursion/index.txt',\n        contents: fs.createReadStream('test/fixtures-recursion/index.txt')\n      })\n\n      var stream = fileIncludePlugin({\n        basepath: '@file'\n      })\n      stream.on('data', newFile => {\n        should.exist(newFile)\n        should.exist(newFile.contents)\n\n        String(newFile.contents).should.equal(result)\n        done()\n      })\n\n      stream.write(file)\n      stream.end()\n    })\n  })\n})\n"
  },
  {
    "path": "test/variable.js",
    "content": "'use strict'\n\nconst replaceVariable = require('../lib/replace-variable')\nconst fs = require('fs')\n\nrequire('should')\n\ndescribe('## variable', () => {\n  var result = fs.readFileSync('test/fixtures-variable/result.html', 'utf-8')\n\n  it('# basic', done => {\n    var index = fs.readFileSync('test/fixtures-variable/index.html', 'utf-8')\n\n    replaceVariable(index, {\n      param1: 'value1',\n      obj: {\n        param1: 'o1',\n        param2: 'o2'\n      },\n      param2: 'value2'\n    }, {\n      prefix: '//='\n    }).should.equal(result)\n\n    done()\n  })\n\n  it('# with suffix', done => {\n    var index = fs.readFileSync('test/fixtures-variable/index-suffix.html', 'utf-8')\n\n    replaceVariable(index, {\n      param1: 'value1',\n      obj: {\n        param1: 'o1',\n        param2: 'o2'\n      },\n      param2: 'value2'\n    }, {\n      prefix: '//=',\n      suffix: '@@'\n    }).should.equal(result)\n\n    done()\n  })\n})\n"
  },
  {
    "path": "test/webroot-variable.js",
    "content": "'use strict'\n\nconst fileIncludePlugin = require('..')\nconst Vinyl = require('vinyl')\nconst should = require('should')\nconst fs = require('fs')\n\ndescribe('## built-in webRoot variable', () => {\n  it('# regular usage and includes', done => {\n    var result = fs.readFileSync('test/fixtures-webroot-variable/result.html', 'utf8')\n    var path = 'test/fixtures-webroot-variable/index.html'\n    var file = new Vinyl({ path: path, contents: fs.createReadStream(path) })\n\n    var stream = fileIncludePlugin()\n    stream.on('data', newFile => {\n      should.exist(newFile)\n      should.exist(newFile.contents)\n\n      String(newFile.contents).should.equal(result)\n      done()\n    })\n\n    stream.write(file)\n    stream.end()\n  })\n\n  it('# nested folder', done => {\n    var result = fs.readFileSync('test/fixtures-webroot-variable/sub/result.html', 'utf8')\n    var path = 'test/fixtures-webroot-variable/sub/index.html'\n    var file = new Vinyl({ path: path, contents: fs.createReadStream(path) })\n\n    var stream = fileIncludePlugin()\n    stream.on('data', newFile => {\n      should.exist(newFile)\n      should.exist(newFile.contents)\n\n      String(newFile.contents).should.equal(result)\n      done()\n    })\n\n    stream.write(file)\n    stream.end()\n  })\n})\n"
  }
]